revamped the XML debugging module and prepare for a new checking mode

* 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
Daniel
diff --git a/ChangeLog b/ChangeLog
index 3ca161f..8d8c9b5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+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
diff --git a/NEWS b/NEWS
index 723b02f..b96d9cf 100644
--- a/NEWS
+++ b/NEWS
@@ -15,9 +15,27 @@
 to the CVS at 
 http://cvs.gnome.org/viewcvs/libxml2/
  code base.There is the list of public releases:
+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, 
+    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
diff --git a/configure.in b/configure.in
index ee585f3..c593072 100644
--- a/configure.in
+++ b/configure.in
@@ -440,6 +440,7 @@
     then
 	if test "${with_mem_debug}" = "" ; then
 	    with_mem_debug="yes"
+	    with_run_debug="yes"
 	fi
 	if test "${with_docbook}" = "" ; then
 	    with_docbook="yes"
@@ -1031,6 +1032,19 @@
 fi
 AC_SUBST(WITH_MEM_DEBUG)
 
+AC_ARG_WITH(run_debug,
+[  --with-run-debug        add the runtime debugging module (off)])
+if test "$with_minimum" = "yes" -a "$with_run_debug" = ""
+then
+    with_run_debug=no
+fi
+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=
diff --git a/debugXML.c b/debugXML.c
index bb6560a..1980441 100644
--- a/debugXML.c
+++ b/debugXML.c
@@ -34,6 +34,1139 @@
 #include <libxml/relaxng.h>
 #endif
 
+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 */
+    int check;                  /* do just checkings */
+};
+
+static void xmlCtxtDumpNodeList(xmlDebugCtxtPtr ctxt, xmlNodePtr node);
+
+static void
+xmlCtxtDumpInitCtxt(xmlDebugCtxtPtr ctxt)
+{
+    int i;
+
+    ctxt->depth = 0;
+    ctxt->check = 0;
+    ctxt->output = stdout;
+    for (i = 0; i < 100; i++)
+        ctxt->shift[i] = ' ';
+    ctxt->shift[100] = 0;
+}
+
+static void
+xmlCtxtDumpSpaces(xmlDebugCtxtPtr ctxt)
+{
+    if (ctxt->check)
+        return;
+    if ((ctxt->output != NULL) && (ctxt->depth > 0)) {
+        if (ctxt->depth < 50)
+            fprintf(ctxt->output, &ctxt->shift[100 - 2 * ctxt->depth]);
+        else
+            fprintf(ctxt->output, ctxt->shift);
+    }
+}
+
+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) {
+        fprintf(ctxt->output, "PBM: not a DTD\n");
+        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
+     */
+    if (dtd->parent == NULL)
+        fprintf(ctxt->output, "PBM: DTD has no parent\n");
+    if (dtd->doc == NULL)
+        fprintf(ctxt->output, "PBM: DTD has no doc\n");
+    if ((dtd->parent != NULL) && (dtd->doc != dtd->parent->doc))
+        fprintf(ctxt->output, "PBM: DTD doc differs from parent's one\n");
+    if (dtd->prev == NULL) {
+        if ((dtd->parent != NULL)
+            && (dtd->parent->children != (xmlNodePtr) dtd))
+            fprintf(ctxt->output,
+                    "PBM: DTD has no prev and not first of list\n");
+    } else {
+        if (dtd->prev->next != (xmlNodePtr) dtd)
+            fprintf(ctxt->output,
+                    "PBM: DTD prev->next : back link wrong\n");
+    }
+    if (dtd->next == NULL) {
+        if ((dtd->parent != NULL)
+            && (dtd->parent->last != (xmlNodePtr) dtd))
+            fprintf(ctxt->output,
+                    "PBM: DTD has no next and not last of list\n");
+    } else {
+        if (dtd->next->prev != (xmlNodePtr) dtd)
+            fprintf(ctxt->output,
+                    "PBM: DTD next->prev : forward link wrong\n");
+    }
+}
+
+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) {
+        fprintf(ctxt->output, "PBM: not a Attr\n");
+        return;
+    }
+    if (attr->name != NULL) {
+        if (!ctxt->check)
+            fprintf(ctxt->output, "ATTRDECL(%s)", (char *) attr->name);
+    } else
+        fprintf(ctxt->output, "PBM ATTRDECL noname!!!");
+    if (attr->elem != NULL) {
+        if (!ctxt->check)
+            fprintf(ctxt->output, " for %s", (char *) attr->elem);
+    } else
+        fprintf(ctxt->output, " PBM noelem!!!");
+    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
+     */
+    if (attr->parent == NULL)
+        fprintf(ctxt->output, "PBM: Attr has no parent\n");
+    if (attr->doc == NULL)
+        fprintf(ctxt->output, "PBM: Attr has no doc\n");
+    if ((attr->parent != NULL) && (attr->doc != attr->parent->doc))
+        fprintf(ctxt->output, "PBM: Attr doc differs from parent's one\n");
+    if (attr->prev == NULL) {
+        if ((attr->parent != NULL)
+            && (attr->parent->children != (xmlNodePtr) attr))
+            fprintf(ctxt->output,
+                    "PBM: Attr has no prev and not first of list\n");
+    } else {
+        if (attr->prev->next != (xmlNodePtr) attr)
+            fprintf(ctxt->output,
+                    "PBM: Attr prev->next : back link wrong\n");
+    }
+    if (attr->next == NULL) {
+        if ((attr->parent != NULL)
+            && (attr->parent->last != (xmlNodePtr) attr))
+            fprintf(ctxt->output,
+                    "PBM: Attr has no next and not last of list\n");
+    } else {
+        if (attr->next->prev != (xmlNodePtr) attr)
+            fprintf(ctxt->output,
+                    "PBM: Attr next->prev : forward link wrong\n");
+    }
+}
+
+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) {
+        fprintf(ctxt->output, "PBM: not a Elem\n");
+        return;
+    }
+    if (elem->name != NULL) {
+        if (!ctxt->check) {
+            fprintf(ctxt->output, "ELEMDECL(");
+            xmlCtxtDumpString(ctxt, elem->name);
+            fprintf(ctxt->output, ")");
+        }
+    } else
+        fprintf(ctxt->output, "PBM ELEMDECL noname!!!");
+    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
+     */
+    if (elem->parent == NULL)
+        fprintf(ctxt->output, "PBM: Elem has no parent\n");
+    if (elem->doc == NULL)
+        fprintf(ctxt->output, "PBM: Elem has no doc\n");
+    if ((elem->parent != NULL) && (elem->doc != elem->parent->doc))
+        fprintf(ctxt->output, "PBM: Elem doc differs from parent's one\n");
+    if (elem->prev == NULL) {
+        if ((elem->parent != NULL)
+            && (elem->parent->children != (xmlNodePtr) elem))
+            fprintf(ctxt->output,
+                    "PBM: Elem has no prev and not first of list\n");
+    } else {
+        if (elem->prev->next != (xmlNodePtr) elem)
+            fprintf(ctxt->output,
+                    "PBM: Elem prev->next : back link wrong\n");
+    }
+    if (elem->next == NULL) {
+        if ((elem->parent != NULL)
+            && (elem->parent->last != (xmlNodePtr) elem))
+            fprintf(ctxt->output,
+                    "PBM: Elem has no next and not last of list\n");
+    } else {
+        if (elem->next->prev != (xmlNodePtr) elem)
+            fprintf(ctxt->output,
+                    "PBM: Elem next->prev : forward link wrong\n");
+    }
+}
+
+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) {
+        fprintf(ctxt->output, "PBM: not a Entity decl\n");
+        return;
+    }
+    if (ent->name != NULL) {
+        if (!ctxt->check) {
+            fprintf(ctxt->output, "ENTITYDECL(");
+            xmlCtxtDumpString(ctxt, ent->name);
+            fprintf(ctxt->output, ")");
+        }
+    } else
+        fprintf(ctxt->output, "PBM ENTITYDECL noname!!!");
+    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
+     */
+    if (ent->parent == NULL)
+        fprintf(ctxt->output, "PBM: Ent has no parent\n");
+    if (ent->doc == NULL)
+        fprintf(ctxt->output, "PBM: Ent has no doc\n");
+    if ((ent->parent != NULL) && (ent->doc != ent->parent->doc))
+        fprintf(ctxt->output, "PBM: Ent doc differs from parent's one\n");
+    if (ent->prev == NULL) {
+        if ((ent->parent != NULL)
+            && (ent->parent->children != (xmlNodePtr) ent))
+            fprintf(ctxt->output,
+                    "PBM: Ent has no prev and not first of list\n");
+    } else {
+        if (ent->prev->next != (xmlNodePtr) ent)
+            fprintf(ctxt->output,
+                    "PBM: Ent prev->next : back link wrong\n");
+    }
+    if (ent->next == NULL) {
+        if ((ent->parent != NULL)
+            && (ent->parent->last != (xmlNodePtr) ent))
+            fprintf(ctxt->output,
+                    "PBM: Ent has no next and not last of list\n");
+    } else {
+        if (ent->next->prev != (xmlNodePtr) ent)
+            fprintf(ctxt->output,
+                    "PBM: Ent next->prev : forward link wrong\n");
+    }
+}
+
+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) {
+        fprintf(ctxt->output, "invalid namespace type %d\n", ns->type);
+        return;
+    }
+    if (ns->href == NULL) {
+        if (ns->prefix != NULL)
+            fprintf(ctxt->output,
+                    "PBM: incomplete namespace %s href=NULL\n",
+                    (char *) ns->prefix);
+        else
+            fprintf(ctxt->output,
+                    "PBM: 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--;
+        }
+    }
+
+    /*
+     * Do a bit of checking
+     */
+    if (attr->parent == NULL)
+        fprintf(ctxt->output, "PBM: Attr has no parent\n");
+    if (attr->doc == NULL)
+        fprintf(ctxt->output, "PBM: Attr has no doc\n");
+    if ((attr->parent != NULL) && (attr->doc != attr->parent->doc))
+        fprintf(ctxt->output, "PBM: Attr doc differs from parent's one\n");
+    if (attr->prev == NULL) {
+        if ((attr->parent != NULL) && (attr->parent->properties != attr))
+            fprintf(ctxt->output,
+                    "PBM: Attr has no prev and not first of list\n");
+    } else {
+        if (attr->prev->next != attr)
+            fprintf(ctxt->output,
+                    "PBM: Attr prev->next : back link wrong\n");
+    }
+    if (attr->next != NULL) {
+        if (attr->next->prev != attr)
+            fprintf(ctxt->output,
+                    "PBM: Attr next->prev : forward link wrong\n");
+    }
+}
+
+/**
+ * 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;
+    }
+    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");
+            break;
+        case XML_TEXT_NODE:
+            if (!ctxt->check) {
+                xmlCtxtDumpSpaces(ctxt);
+                if (node->name == (const xmlChar *) xmlStringTextNoenc)
+                    fprintf(ctxt->output, "TEXT no enc\n");
+                else
+                    fprintf(ctxt->output, "TEXT\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, "PBM: DOCUMENT found here\n");
+            break;
+        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);
+            fprintf(ctxt->output, "PBM: NODE_%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->nsDef != NULL)
+        xmlCtxtDumpNamespaceList(ctxt, node->nsDef);
+    if (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
+     */
+    if (node->parent == NULL)
+        fprintf(ctxt->output, "PBM: Node has no parent\n");
+    if (node->doc == NULL)
+        fprintf(ctxt->output, "PBM: Node has no doc\n");
+    if ((node->parent != NULL) && (node->doc != node->parent->doc))
+        fprintf(ctxt->output, "PBM: Node doc differs from parent's one\n");
+    if (node->prev == NULL) {
+        if ((node->parent != NULL) && (node->parent->children != node))
+            fprintf(ctxt->output,
+                    "PBM: Node has no prev and not first of list\n");
+    } else {
+        if (node->prev->next != node)
+            fprintf(ctxt->output,
+                    "PBM: Node prev->next : back link wrong\n");
+    }
+    if (node->next == NULL) {
+        if ((node->parent != NULL) && (node->parent->last != node))
+            fprintf(ctxt->output,
+                    "PBM: Node has no next and not last of list\n");
+    } else {
+        if (node->next->prev != node)
+            fprintf(ctxt->output,
+                    "PBM: Node next->prev : forward link wrong\n");
+    }
+}
+
+/**
+ * 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->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;
+    }
+}
+
+
+/**
+ * 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) {
+        if (!ctxt->check)
+            fprintf(ctxt->output, "DOCUMENT == NULL !\n");
+        return;
+    }
+
+    switch (doc->type) {
+        case XML_ELEMENT_NODE:
+            fprintf(ctxt->output, "Error, ELEMENT found here ");
+            break;
+        case XML_ATTRIBUTE_NODE:
+            fprintf(ctxt->output, "Error, ATTRIBUTE found here\n");
+            break;
+        case XML_TEXT_NODE:
+            fprintf(ctxt->output, "Error, TEXT\n");
+            break;
+        case XML_CDATA_SECTION_NODE:
+            fprintf(ctxt->output, "Error, CDATA_SECTION\n");
+            break;
+        case XML_ENTITY_REF_NODE:
+            fprintf(ctxt->output, "Error, ENTITY_REF\n");
+            break;
+        case XML_ENTITY_NODE:
+            fprintf(ctxt->output, "Error, ENTITY\n");
+            break;
+        case XML_PI_NODE:
+            fprintf(ctxt->output, "Error, PI\n");
+            break;
+        case XML_COMMENT_NODE:
+            fprintf(ctxt->output, "Error, COMMENT\n");
+            break;
+        case XML_DOCUMENT_NODE:
+            fprintf(ctxt->output, "DOCUMENT\n");
+            break;
+        case XML_HTML_DOCUMENT_NODE:
+            fprintf(ctxt->output, "HTML DOCUMENT\n");
+            break;
+        case XML_DOCUMENT_TYPE_NODE:
+            fprintf(ctxt->output, "Error, DOCUMENT_TYPE\n");
+            break;
+        case XML_DOCUMENT_FRAG_NODE:
+            fprintf(ctxt->output, "Error, DOCUMENT_FRAG\n");
+            break;
+        case XML_NOTATION_NODE:
+            fprintf(ctxt->output, "Error, NOTATION\n");
+            break;
+        default:
+            fprintf(ctxt->output, "NODE_%d\n", doc->type);
+    }
+    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:
+                fprintf(ctxt->output, "UNKNOWN TYPE %d", 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) {
+        if (!ctxt->check)
+            fprintf(ctxt->output, "DOCUMENT == NULL !\n");
+        return;
+    }
+
+    switch (doc->type) {
+        case XML_ELEMENT_NODE:
+            fprintf(ctxt->output, "Error, ELEMENT found here ");
+            break;
+        case XML_ATTRIBUTE_NODE:
+            fprintf(ctxt->output, "Error, ATTRIBUTE found here\n");
+            break;
+        case XML_TEXT_NODE:
+            fprintf(ctxt->output, "Error, TEXT\n");
+            break;
+        case XML_CDATA_SECTION_NODE:
+            fprintf(ctxt->output, "Error, CDATA_SECTION\n");
+            break;
+        case XML_ENTITY_REF_NODE:
+            fprintf(ctxt->output, "Error, ENTITY_REF\n");
+            break;
+        case XML_ENTITY_NODE:
+            fprintf(ctxt->output, "Error, ENTITY\n");
+            break;
+        case XML_PI_NODE:
+            fprintf(ctxt->output, "Error, PI\n");
+            break;
+        case XML_COMMENT_NODE:
+            fprintf(ctxt->output, "Error, COMMENT\n");
+            break;
+        case XML_DOCUMENT_NODE:
+            fprintf(ctxt->output, "DOCUMENT\n");
+            break;
+        case XML_HTML_DOCUMENT_NODE:
+            fprintf(ctxt->output, "HTML DOCUMENT\n");
+            break;
+        case XML_DOCUMENT_TYPE_NODE:
+            fprintf(ctxt->output, "Error, DOCUMENT_TYPE\n");
+            break;
+        case XML_DOCUMENT_FRAG_NODE:
+            fprintf(ctxt->output, "Error, DOCUMENT_FRAG\n");
+            break;
+        case XML_NOTATION_NODE:
+            fprintf(ctxt->output, "Error, NOTATION\n");
+            break;
+        default:
+            fprintf(ctxt->output, "NODE_%d\n", doc->type);
+    }
+    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;
+    }
+    if (dtd->type != XML_DTD_NODE) {
+        fprintf(ctxt->output, "PBM: not a DTD\n");
+        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
+     */
+    if ((dtd->parent != NULL) && (dtd->doc != dtd->parent->doc))
+        fprintf(ctxt->output, "PBM: DTD doc differs from parent's one\n");
+    if (dtd->prev == NULL) {
+        if ((dtd->parent != NULL)
+            && (dtd->parent->children != (xmlNodePtr) dtd))
+            fprintf(ctxt->output,
+                    "PBM: DTD has no prev and not first of list\n");
+    } else {
+        if (dtd->prev->next != (xmlNodePtr) dtd)
+            fprintf(ctxt->output,
+                    "PBM: DTD prev->next : back link wrong\n");
+    }
+    if (dtd->next == NULL) {
+        if ((dtd->parent != NULL)
+            && (dtd->parent->last != (xmlNodePtr) dtd))
+            fprintf(ctxt->output,
+                    "PBM: DTD has no next and not last of list\n");
+    } else {
+        if (dtd->next->prev != (xmlNodePtr) dtd)
+            fprintf(ctxt->output,
+                    "PBM: DTD next->prev : forward link wrong\n");
+    }
+    if (dtd->children == NULL)
+        fprintf(ctxt->output, "    DTD is empty\n");
+    else {
+        ctxt->depth++;
+        xmlCtxtDumpNodeList(ctxt, dtd->children);
+        ctxt->depth--;
+    }
+}
+/************************************************************************
+ *									*
+ *			Public entry points				*
+ *									*
+ ************************************************************************/
+
 /**
  * xmlDebugDumpString:
  * @output:  the FILE * for the output
@@ -64,447 +1197,6 @@
     fprintf(output, "...");
 }
 
-static void
-xmlDebugDumpDtdNode(FILE *output, xmlDtdPtr dtd, 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, shift);
-
-    if (dtd == NULL) {
-	fprintf(output, "DTD node is NULL\n");
-	return;
-    }
-
-    if (dtd->type != XML_DTD_NODE) {
-	fprintf(output, "PBM: not a DTD\n");
-	return;
-    }
-    if (dtd->name != NULL)
-	fprintf(output, "DTD(%s)", (char *)dtd->name);
-    else
-	fprintf(output, "DTD");
-    if (dtd->ExternalID != NULL)
-	fprintf(output, ", PUBLIC %s", (char *)dtd->ExternalID);
-    if (dtd->SystemID != NULL)
-	fprintf(output, ", SYSTEM %s", (char *)dtd->SystemID);
-    fprintf(output, "\n");
-    /*
-     * Do a bit of checking
-     */
-    if (dtd->parent == NULL)
-	fprintf(output, "PBM: DTD has no parent\n");
-    if (dtd->doc == NULL)
-	fprintf(output, "PBM: DTD has no doc\n");
-    if ((dtd->parent != NULL) && (dtd->doc != dtd->parent->doc))
-	fprintf(output, "PBM: DTD doc differs from parent's one\n");
-    if (dtd->prev == NULL) {
-	if ((dtd->parent != NULL) && (dtd->parent->children != (xmlNodePtr)dtd))
-	    fprintf(output, "PBM: DTD has no prev and not first of list\n");
-    } else {
-	if (dtd->prev->next != (xmlNodePtr) dtd)
-	    fprintf(output, "PBM: DTD prev->next : back link wrong\n");
-    }
-    if (dtd->next == NULL) {
-	if ((dtd->parent != NULL) && (dtd->parent->last != (xmlNodePtr) dtd))
-	    fprintf(output, "PBM: DTD has no next and not last of list\n");
-    } else {
-	if (dtd->next->prev != (xmlNodePtr) dtd)
-	    fprintf(output, "PBM: DTD next->prev : forward link wrong\n");
-    }
-}
-
-static void
-xmlDebugDumpAttrDecl(FILE *output, xmlAttributePtr attr, 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, shift);
-
-    if (attr == NULL) {
-	fprintf(output, "Attribute declaration is NULL\n");
-	return;
-    }
-    if (attr->type != XML_ATTRIBUTE_DECL) {
-	fprintf(output, "PBM: not a Attr\n");
-	return;
-    }
-    if (attr->name != NULL)
-	fprintf(output, "ATTRDECL(%s)", (char *)attr->name);
-    else
-	fprintf(output, "PBM ATTRDECL noname!!!");
-    if (attr->elem != NULL)
-	fprintf(output, " for %s", (char *)attr->elem);
-    else
-	fprintf(output, " PBM noelem!!!");
-    switch (attr->atype) {
-        case XML_ATTRIBUTE_CDATA:
-	    fprintf(output, " CDATA");
-	    break;
-        case XML_ATTRIBUTE_ID:
-	    fprintf(output, " ID");
-	    break;
-        case XML_ATTRIBUTE_IDREF:
-	    fprintf(output, " IDREF");
-	    break;
-        case XML_ATTRIBUTE_IDREFS:
-	    fprintf(output, " IDREFS");
-	    break;
-        case XML_ATTRIBUTE_ENTITY:
-	    fprintf(output, " ENTITY");
-	    break;
-        case XML_ATTRIBUTE_ENTITIES:
-	    fprintf(output, " ENTITIES");
-	    break;
-        case XML_ATTRIBUTE_NMTOKEN:
-	    fprintf(output, " NMTOKEN");
-	    break;
-        case XML_ATTRIBUTE_NMTOKENS:
-	    fprintf(output, " NMTOKENS");
-	    break;
-        case XML_ATTRIBUTE_ENUMERATION:
-	    fprintf(output, " ENUMERATION");
-	    break;
-        case XML_ATTRIBUTE_NOTATION:
-	    fprintf(output, " NOTATION ");
-	    break;
-    }
-    if (attr->tree != NULL) {
-	int indx;
-	xmlEnumerationPtr cur = attr->tree;
-
-	for (indx = 0;indx < 5; indx++) {
-	    if (indx != 0)
-		fprintf(output, "|%s", (char *)cur->name);
-	    else
-		fprintf(output, " (%s", (char *)cur->name);
-	    cur = cur->next;
-	    if (cur == NULL) break;
-	}
-	if (cur == NULL)
-	    fprintf(output, ")");
-	else
-	    fprintf(output, "...)");
-    }
-    switch (attr->def) {
-        case XML_ATTRIBUTE_NONE:
-	    break;
-        case XML_ATTRIBUTE_REQUIRED:
-	    fprintf(output, " REQUIRED");
-	    break;
-        case XML_ATTRIBUTE_IMPLIED:
-	    fprintf(output, " IMPLIED");
-	    break;
-        case XML_ATTRIBUTE_FIXED:
-	    fprintf(output, " FIXED");
-	    break;
-    }
-    if (attr->defaultValue != NULL) {
-	fprintf(output, "\"");
-	xmlDebugDumpString(output, attr->defaultValue);
-	fprintf(output, "\"");
-    }
-    fprintf(output, "\n");
-
-    /*
-     * Do a bit of checking
-     */
-    if (attr->parent == NULL)
-	fprintf(output, "PBM: Attr has no parent\n");
-    if (attr->doc == NULL)
-	fprintf(output, "PBM: Attr has no doc\n");
-    if ((attr->parent != NULL) && (attr->doc != attr->parent->doc))
-	fprintf(output, "PBM: Attr doc differs from parent's one\n");
-    if (attr->prev == NULL) {
-	if ((attr->parent != NULL) && (attr->parent->children != (xmlNodePtr)attr))
-	    fprintf(output, "PBM: Attr has no prev and not first of list\n");
-    } else {
-	if (attr->prev->next != (xmlNodePtr) attr)
-	    fprintf(output, "PBM: Attr prev->next : back link wrong\n");
-    }
-    if (attr->next == NULL) {
-	if ((attr->parent != NULL) && (attr->parent->last != (xmlNodePtr) attr))
-	    fprintf(output, "PBM: Attr has no next and not last of list\n");
-    } else {
-	if (attr->next->prev != (xmlNodePtr) attr)
-	    fprintf(output, "PBM: Attr next->prev : forward link wrong\n");
-    }
-}
-
-static void
-xmlDebugDumpElemDecl(FILE *output, xmlElementPtr elem, 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, shift);
-
-    if (elem == NULL) {
-	fprintf(output, "Element declaration is NULL\n");
-	return;
-    }
-    if (elem->type != XML_ELEMENT_DECL) {
-	fprintf(output, "PBM: not a Elem\n");
-	return;
-    }
-    if (elem->name != NULL) {
-	fprintf(output, "ELEMDECL(");
-	xmlDebugDumpString(output, elem->name);
-	fprintf(output, ")");
-    } else
-	fprintf(output, "PBM ELEMDECL noname!!!");
-    switch (elem->etype) {
-	case XML_ELEMENT_TYPE_UNDEFINED: 
-	    fprintf(output, ", UNDEFINED");
-	    break;
-	case XML_ELEMENT_TYPE_EMPTY: 
-	    fprintf(output, ", EMPTY");
-	    break;
-	case XML_ELEMENT_TYPE_ANY: 
-	    fprintf(output, ", ANY");
-	    break;
-	case XML_ELEMENT_TYPE_MIXED: 
-	    fprintf(output, ", MIXED ");
-	    break;
-	case XML_ELEMENT_TYPE_ELEMENT: 
-	    fprintf(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(output, "%s", buf);
-    }
-    fprintf(output, "\n");
-
-    /*
-     * Do a bit of checking
-     */
-    if (elem->parent == NULL)
-	fprintf(output, "PBM: Elem has no parent\n");
-    if (elem->doc == NULL)
-	fprintf(output, "PBM: Elem has no doc\n");
-    if ((elem->parent != NULL) && (elem->doc != elem->parent->doc))
-	fprintf(output, "PBM: Elem doc differs from parent's one\n");
-    if (elem->prev == NULL) {
-	if ((elem->parent != NULL) && (elem->parent->children != (xmlNodePtr)elem))
-	    fprintf(output, "PBM: Elem has no prev and not first of list\n");
-    } else {
-	if (elem->prev->next != (xmlNodePtr) elem)
-	    fprintf(output, "PBM: Elem prev->next : back link wrong\n");
-    }
-    if (elem->next == NULL) {
-	if ((elem->parent != NULL) && (elem->parent->last != (xmlNodePtr) elem))
-	    fprintf(output, "PBM: Elem has no next and not last of list\n");
-    } else {
-	if (elem->next->prev != (xmlNodePtr) elem)
-	    fprintf(output, "PBM: Elem next->prev : forward link wrong\n");
-    }
-}
-
-static void
-xmlDebugDumpEntityDecl(FILE *output, xmlEntityPtr ent, 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, shift);
-
-    if (ent == NULL) {
-	fprintf(output, "Entity declaration is NULL\n");
-	return;
-    }
-    if (ent->type != XML_ENTITY_DECL) {
-	fprintf(output, "PBM: not a Entity decl\n");
-	return;
-    }
-    if (ent->name != NULL) {
-	fprintf(output, "ENTITYDECL(");
-	xmlDebugDumpString(output, ent->name);
-	fprintf(output, ")");
-    } else
-	fprintf(output, "PBM ENTITYDECL noname!!!");
-    switch (ent->etype) {
-	case XML_INTERNAL_GENERAL_ENTITY: 
-	    fprintf(output, ", internal\n");
-	    break;
-	case XML_EXTERNAL_GENERAL_PARSED_ENTITY: 
-	    fprintf(output, ", external parsed\n");
-	    break;
-	case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY: 
-	    fprintf(output, ", unparsed\n");
-	    break;
-	case XML_INTERNAL_PARAMETER_ENTITY: 
-	    fprintf(output, ", parameter\n");
-	    break;
-	case XML_EXTERNAL_PARAMETER_ENTITY: 
-	    fprintf(output, ", external parameter\n");
-	    break;
-	case XML_INTERNAL_PREDEFINED_ENTITY: 
-	    fprintf(output, ", predefined\n");
-	    break;
-    }
-    if (ent->ExternalID) {
-        fprintf(output, shift);
-        fprintf(output, " ExternalID=%s\n", (char *)ent->ExternalID);
-    }
-    if (ent->SystemID) {
-        fprintf(output, shift);
-        fprintf(output, " SystemID=%s\n", (char *)ent->SystemID);
-    }
-    if (ent->URI != NULL) {
-        fprintf(output, shift);
-        fprintf(output, " URI=%s\n", (char *)ent->URI);
-    }
-    if (ent->content) {
-        fprintf(output, shift);
-	fprintf(output, " content=");
-	xmlDebugDumpString(output, ent->content);
-	fprintf(output, "\n");
-    }
-
-    /*
-     * Do a bit of checking
-     */
-    if (ent->parent == NULL)
-	fprintf(output, "PBM: Ent has no parent\n");
-    if (ent->doc == NULL)
-	fprintf(output, "PBM: Ent has no doc\n");
-    if ((ent->parent != NULL) && (ent->doc != ent->parent->doc))
-	fprintf(output, "PBM: Ent doc differs from parent's one\n");
-    if (ent->prev == NULL) {
-	if ((ent->parent != NULL) && (ent->parent->children != (xmlNodePtr)ent))
-	    fprintf(output, "PBM: Ent has no prev and not first of list\n");
-    } else {
-	if (ent->prev->next != (xmlNodePtr) ent)
-	    fprintf(output, "PBM: Ent prev->next : back link wrong\n");
-    }
-    if (ent->next == NULL) {
-	if ((ent->parent != NULL) && (ent->parent->last != (xmlNodePtr) ent))
-	    fprintf(output, "PBM: Ent has no next and not last of list\n");
-    } else {
-	if (ent->next->prev != (xmlNodePtr) ent)
-	    fprintf(output, "PBM: Ent next->prev : forward link wrong\n");
-    }
-}
-
-static void
-xmlDebugDumpNamespace(FILE *output, xmlNsPtr ns, 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, shift);
-
-    if (ns == NULL) {
-	fprintf(output, "namespace node is NULL\n");
-	return;
-    }
-    if (ns->type != XML_NAMESPACE_DECL) {
-        fprintf(output, "invalid namespace node %d\n", (char *)ns->type);
-	return;
-    }
-    if (ns->href == NULL) {
-	if (ns->prefix != NULL)
-	    fprintf(output, "incomplete namespace %s href=NULL\n",
-	    	(char *)ns->prefix);
-	else
-	    fprintf(output, "incomplete default namespace href=NULL\n");
-    } else {
-	if (ns->prefix != NULL)
-	    fprintf(output, "namespace %s href=", (char *)ns->prefix);
-	else
-	    fprintf(output, "default namespace href=");
-
-	xmlDebugDumpString(output, ns->href);
-	fprintf(output, "\n");
-    }
-}
-
-static void
-xmlDebugDumpNamespaceList(FILE *output, xmlNsPtr ns, int depth) {
-    while (ns != NULL) {
-        xmlDebugDumpNamespace(output, ns, depth);
-	ns = ns->next;
-    }
-}
-
-static void
-xmlDebugDumpEntity(FILE *output, xmlEntityPtr ent, 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, shift);
-    
-    if (ent == NULL) {
-	fprintf(output, "Entity is NULL\n");
-	return;
-    }
-    switch (ent->etype) {
-        case XML_INTERNAL_GENERAL_ENTITY:
-	    fprintf(output, "INTERNAL_GENERAL_ENTITY ");
-	    break;
-        case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
-	    fprintf(output, "EXTERNAL_GENERAL_PARSED_ENTITY ");
-	    break;
-        case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
-	    fprintf(output, "EXTERNAL_GENERAL_UNPARSED_ENTITY ");
-	    break;
-        case XML_INTERNAL_PARAMETER_ENTITY:
-	    fprintf(output, "INTERNAL_PARAMETER_ENTITY ");
-	    break;
-        case XML_EXTERNAL_PARAMETER_ENTITY:
-	    fprintf(output, "EXTERNAL_PARAMETER_ENTITY ");
-	    break;
-	default:
-	    fprintf(output, "ENTITY_%d ! ", (char *)ent->etype);
-    }
-    fprintf(output, "%s\n", ent->name);
-    if (ent->ExternalID) {
-        fprintf(output, shift);
-        fprintf(output, "ExternalID=%s\n", (char *)ent->ExternalID);
-    }
-    if (ent->SystemID) {
-        fprintf(output, shift);
-        fprintf(output, "SystemID=%s\n", (char *)ent->SystemID);
-    }
-    if (ent->URI) {
-        fprintf(output, shift);
-        fprintf(output, "URI=%s\n", (char *)ent->URI);
-    }
-    if (ent->content) {
-        fprintf(output, shift);
-	fprintf(output, "content=");
-	xmlDebugDumpString(output, ent->content);
-	fprintf(output, "\n");
-    }
-}
-
 /**
  * xmlDebugDumpAttr:
  * @output:  the FILE * for the output
@@ -515,45 +1207,30 @@
  */
 void
 xmlDebugDumpAttr(FILE *output, xmlAttrPtr attr, int depth) {
-    int i;
-    char shift[100];
+    xmlDebugCtxt ctxt;
 
-    for (i = 0;((i < depth) && (i < 25));i++)
-        shift[2 * i] = shift[2 * i + 1] = ' ';
-    shift[2 * i] = shift[2 * i + 1] = 0;
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.output = output;
+    ctxt.depth = depth;
+    xmlCtxtDumpAttr(&ctxt, attr);
+}
 
-    fprintf(output, shift);
-    
-    if (attr == NULL) {
-	fprintf(output, "Attr is NULL");
-	return;
-    }
-    fprintf(output, "ATTRIBUTE ");
-    xmlDebugDumpString(output, attr->name);
-    fprintf(output, "\n");
-    if (attr->children != NULL) 
-        xmlDebugDumpNodeList(output, attr->children, depth + 1);
 
-    /*
-     * Do a bit of checking
-     */
-    if (attr->parent == NULL)
-	fprintf(output, "PBM: Attr has no parent\n");
-    if (attr->doc == NULL)
-	fprintf(output, "PBM: Attr has no doc\n");
-    if ((attr->parent != NULL) && (attr->doc != attr->parent->doc))
-	fprintf(output, "PBM: Attr doc differs from parent's one\n");
-    if (attr->prev == NULL) {
-	if ((attr->parent != NULL) && (attr->parent->properties != attr))
-	    fprintf(output, "PBM: Attr has no prev and not first of list\n");
-    } else {
-	if (attr->prev->next != attr)
-	    fprintf(output, "PBM: Attr prev->next : back link wrong\n");
-    }
-    if (attr->next != NULL) {
-	if (attr->next->prev != attr)
-	    fprintf(output, "PBM: Attr next->prev : forward link wrong\n");
-    }
+/**
+ * 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;
+
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.output = output;
+    xmlCtxtDumpEntities(&ctxt, doc);
 }
 
 /**
@@ -567,12 +1244,12 @@
 void
 xmlDebugDumpAttrList(FILE * output, xmlAttrPtr attr, int depth)
 {
-    if (output == NULL)
-	output = stdout;
-    while (attr != NULL) {
-        xmlDebugDumpAttr(output, attr, depth);
-        attr = attr->next;
-    }
+    xmlDebugCtxt ctxt;
+
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.output = output;
+    ctxt.depth = depth;
+    xmlCtxtDumpAttrList(&ctxt, attr);
 }
 
 /**
@@ -586,156 +1263,12 @@
 void
 xmlDebugDumpOneNode(FILE * output, xmlNodePtr node, int depth)
 {
-    int i;
-    char shift[100];
+    xmlDebugCtxt ctxt;
 
-    if (output == NULL)
-	output = stdout;
-    for (i = 0; ((i < depth) && (i < 25)); i++)
-        shift[2 * i] = shift[2 * i + 1] = ' ';
-    shift[2 * i] = shift[2 * i + 1] = 0;
-
-    if (node == NULL) {
-	fprintf(output, shift);
-	fprintf(output, "node is NULL\n");
-	return;
-    }
-    switch (node->type) {
-        case XML_ELEMENT_NODE:
-            fprintf(output, shift);
-            fprintf(output, "ELEMENT ");
-            if ((node->ns != NULL) && (node->ns->prefix != NULL)) {
-                xmlDebugDumpString(output, node->ns->prefix);
-                fprintf(output, ":");
-            }
-            xmlDebugDumpString(output, node->name);
-            fprintf(output, "\n");
-            break;
-        case XML_ATTRIBUTE_NODE:
-            fprintf(output, shift);
-            fprintf(output, "Error, ATTRIBUTE found here\n");
-            break;
-        case XML_TEXT_NODE:
-            fprintf(output, shift);
-	    if (node->name == (const xmlChar *) xmlStringTextNoenc)
-		fprintf(output, "TEXT no enc\n");
-	    else
-		fprintf(output, "TEXT\n");
-            break;
-        case XML_CDATA_SECTION_NODE:
-            fprintf(output, shift);
-            fprintf(output, "CDATA_SECTION\n");
-            break;
-        case XML_ENTITY_REF_NODE:
-            fprintf(output, shift);
-            fprintf(output, "ENTITY_REF(%s)\n", (char *)node->name);
-            break;
-        case XML_ENTITY_NODE:
-            fprintf(output, shift);
-            fprintf(output, "ENTITY\n");
-            break;
-        case XML_PI_NODE:
-            fprintf(output, shift);
-            fprintf(output, "PI %s\n", (char *)node->name);
-            break;
-        case XML_COMMENT_NODE:
-            fprintf(output, shift);
-            fprintf(output, "COMMENT\n");
-            break;
-        case XML_DOCUMENT_NODE:
-        case XML_HTML_DOCUMENT_NODE:
-            fprintf(output, shift);
-            fprintf(output, "Error, DOCUMENT found here\n");
-            break;
-        case XML_DOCUMENT_TYPE_NODE:
-            fprintf(output, shift);
-            fprintf(output, "DOCUMENT_TYPE\n");
-            break;
-        case XML_DOCUMENT_FRAG_NODE:
-            fprintf(output, shift);
-            fprintf(output, "DOCUMENT_FRAG\n");
-            break;
-        case XML_NOTATION_NODE:
-            fprintf(output, shift);
-            fprintf(output, "NOTATION\n");
-            break;
-        case XML_DTD_NODE:
-            xmlDebugDumpDtdNode(output, (xmlDtdPtr) node, depth);
-            return;
-        case XML_ELEMENT_DECL:
-            xmlDebugDumpElemDecl(output, (xmlElementPtr) node, depth);
-            return;
-        case XML_ATTRIBUTE_DECL:
-            xmlDebugDumpAttrDecl(output, (xmlAttributePtr) node, depth);
-            return;
-        case XML_ENTITY_DECL:
-            xmlDebugDumpEntityDecl(output, (xmlEntityPtr) node, depth);
-            return;
-        case XML_NAMESPACE_DECL:
-            xmlDebugDumpNamespace(output, (xmlNsPtr) node, depth);
-            return;
-        case XML_XINCLUDE_START:
-            fprintf(output, shift);
-            fprintf(output, "INCLUDE START\n");
-            return;
-        case XML_XINCLUDE_END:
-            fprintf(output, shift);
-            fprintf(output, "INCLUDE END\n");
-            return;
-        default:
-            fprintf(output, shift);
-            fprintf(output, "NODE_%d !!!\n", (char *)node->type);
-            return;
-    }
-    if (node->doc == NULL) {
-        fprintf(output, shift);
-        fprintf(output, "doc == NULL !!!\n");
-    }
-    if (node->nsDef != NULL)
-        xmlDebugDumpNamespaceList(output, node->nsDef, depth + 1);
-    if (node->properties != NULL)
-        xmlDebugDumpAttrList(output, node->properties, depth + 1);
-    if (node->type != XML_ENTITY_REF_NODE) {
-        if ((node->type != XML_ELEMENT_NODE) && (node->content != NULL)) {
-            shift[2 * i] = shift[2 * i + 1] = ' ';
-            shift[2 * i + 2] = shift[2 * i + 3] = 0;
-            fprintf(output, shift);
-            fprintf(output, "content=");
-            xmlDebugDumpString(output, node->content);
-            fprintf(output, "\n");
-        }
-    } else {
-        xmlEntityPtr ent;
-
-        ent = xmlGetDocEntity(node->doc, node->name);
-        if (ent != NULL)
-            xmlDebugDumpEntity(output, ent, depth + 1);
-    }
-    /*
-     * Do a bit of checking
-     */
-    if (node->parent == NULL)
-        fprintf(output, "PBM: Node has no parent\n");
-    if (node->doc == NULL)
-        fprintf(output, "PBM: Node has no doc\n");
-    if ((node->parent != NULL) && (node->doc != node->parent->doc))
-        fprintf(output, "PBM: Node doc differs from parent's one\n");
-    if (node->prev == NULL) {
-        if ((node->parent != NULL) && (node->parent->children != node))
-            fprintf(output,
-                    "PBM: Node has no prev and not first of list\n");
-    } else {
-        if (node->prev->next != node)
-            fprintf(output, "PBM: Node prev->next : back link wrong\n");
-    }
-    if (node->next == NULL) {
-        if ((node->parent != NULL) && (node->parent->last != node))
-            fprintf(output,
-                    "PBM: Node has no next and not last of list\n");
-    } else {
-        if (node->next->prev != node)
-            fprintf(output, "PBM: Node next->prev : forward link wrong\n");
-    }
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.output = output;
+    ctxt.depth = depth;
+    xmlCtxtDumpOneNode(&ctxt, node);
 }
 
 /**
@@ -749,23 +1282,14 @@
 void
 xmlDebugDumpNode(FILE * output, xmlNodePtr node, int depth)
 {
+    xmlDebugCtxt ctxt;
+
     if (output == NULL)
 	output = stdout;
-    if (node == NULL) {
-	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, shift);
-	fprintf(output, "node is NULL\n");
-	return;
-    }	
-    xmlDebugDumpOneNode(output, node, depth);
-    if ((node->children != NULL) && (node->type != XML_ENTITY_REF_NODE))
-        xmlDebugDumpNodeList(output, node->children, depth + 1);
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.output = output;
+    ctxt.depth = depth;
+    xmlCtxtDumpNode(&ctxt, node);
 }
 
 /**
@@ -779,15 +1303,16 @@
 void
 xmlDebugDumpNodeList(FILE * output, xmlNodePtr node, int depth)
 {
+    xmlDebugCtxt ctxt;
+
     if (output == NULL)
 	output = stdout;
-    while (node != NULL) {
-        xmlDebugDumpNode(output, node, depth);
-        node = node->next;
-    }
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.output = output;
+    ctxt.depth = depth;
+    xmlCtxtDumpNodeList(&ctxt, node);
 }
 
-
 /**
  * xmlDebugDumpDocumentHead:
  * @output:  the FILE * for the output
@@ -798,80 +1323,13 @@
 void
 xmlDebugDumpDocumentHead(FILE * output, xmlDocPtr doc)
 {
-    if (output == NULL)
-        output = stdout;
-    if (doc == NULL) {
-        fprintf(output, "DOCUMENT == NULL !\n");
-        return;
-    }
+    xmlDebugCtxt ctxt;
 
-    switch (doc->type) {
-        case XML_ELEMENT_NODE:
-            fprintf(output, "Error, ELEMENT found here ");
-            break;
-        case XML_ATTRIBUTE_NODE:
-            fprintf(output, "Error, ATTRIBUTE found here\n");
-            break;
-        case XML_TEXT_NODE:
-            fprintf(output, "Error, TEXT\n");
-            break;
-        case XML_CDATA_SECTION_NODE:
-            fprintf(output, "Error, CDATA_SECTION\n");
-            break;
-        case XML_ENTITY_REF_NODE:
-            fprintf(output, "Error, ENTITY_REF\n");
-            break;
-        case XML_ENTITY_NODE:
-            fprintf(output, "Error, ENTITY\n");
-            break;
-        case XML_PI_NODE:
-            fprintf(output, "Error, PI\n");
-            break;
-        case XML_COMMENT_NODE:
-            fprintf(output, "Error, COMMENT\n");
-            break;
-        case XML_DOCUMENT_NODE:
-            fprintf(output, "DOCUMENT\n");
-            break;
-        case XML_HTML_DOCUMENT_NODE:
-            fprintf(output, "HTML DOCUMENT\n");
-            break;
-        case XML_DOCUMENT_TYPE_NODE:
-            fprintf(output, "Error, DOCUMENT_TYPE\n");
-            break;
-        case XML_DOCUMENT_FRAG_NODE:
-            fprintf(output, "Error, DOCUMENT_FRAG\n");
-            break;
-        case XML_NOTATION_NODE:
-            fprintf(output, "Error, NOTATION\n");
-            break;
-        default:
-            fprintf(output, "NODE_%d\n", (char *)doc->type);
-    }
-    if (doc->name != NULL) {
-        fprintf(output, "name=");
-        xmlDebugDumpString(output, BAD_CAST doc->name);
-        fprintf(output, "\n");
-    }
-    if (doc->version != NULL) {
-        fprintf(output, "version=");
-        xmlDebugDumpString(output, doc->version);
-        fprintf(output, "\n");
-    }
-    if (doc->encoding != NULL) {
-        fprintf(output, "encoding=");
-        xmlDebugDumpString(output, doc->encoding);
-        fprintf(output, "\n");
-    }
-    if (doc->URL != NULL) {
-        fprintf(output, "URL=");
-        xmlDebugDumpString(output, doc->URL);
-        fprintf(output, "\n");
-    }
-    if (doc->standalone)
-        fprintf(output, "standalone=true\n");
-    if (doc->oldNs != NULL)
-        xmlDebugDumpNamespaceList(output, doc->oldNs, 0);
+    if (output == NULL)
+	output = stdout;
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.output = output;
+    xmlCtxtDumpDocumentHead(&ctxt, doc);
 }
 
 /**
@@ -884,16 +1342,13 @@
 void
 xmlDebugDumpDocument(FILE * output, xmlDocPtr doc)
 {
+    xmlDebugCtxt ctxt;
+
     if (output == NULL)
-        output = stdout;
-    if (doc == NULL) {
-        fprintf(output, "DOCUMENT == NULL !\n");
-        return;
-    }
-    xmlDebugDumpDocumentHead(output, doc);
-    if (((doc->type == XML_DOCUMENT_NODE) ||
-         (doc->type == XML_HTML_DOCUMENT_NODE)) && (doc->children != NULL))
-        xmlDebugDumpNodeList(output, doc->children, 1);
+	output = stdout;
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.output = output;
+    xmlCtxtDumpDocument(&ctxt, doc);
 }
 
 /**
@@ -906,171 +1361,20 @@
 void
 xmlDebugDumpDTD(FILE * output, xmlDtdPtr dtd)
 {
+    xmlDebugCtxt ctxt;
+
     if (output == NULL)
 	output = stdout;
-    if (dtd == NULL) {
-	fprintf(output, "DTD is NULL\n");
-        return;
-    }
-    if (dtd->type != XML_DTD_NODE) {
-        fprintf(output, "PBM: not a DTD\n");
-        return;
-    }
-    if (dtd->name != NULL)
-        fprintf(output, "DTD(%s)", (char *)dtd->name);
-    else
-        fprintf(output, "DTD");
-    if (dtd->ExternalID != NULL)
-        fprintf(output, ", PUBLIC %s", (char *)dtd->ExternalID);
-    if (dtd->SystemID != NULL)
-        fprintf(output, ", SYSTEM %s", (char *)dtd->SystemID);
-    fprintf(output, "\n");
-    /*
-     * Do a bit of checking
-     */
-    if ((dtd->parent != NULL) && (dtd->doc != dtd->parent->doc))
-        fprintf(output, "PBM: DTD doc differs from parent's one\n");
-    if (dtd->prev == NULL) {
-        if ((dtd->parent != NULL)
-            && (dtd->parent->children != (xmlNodePtr) dtd))
-            fprintf(output,
-                    "PBM: DTD has no prev and not first of list\n");
-    } else {
-        if (dtd->prev->next != (xmlNodePtr) dtd)
-            fprintf(output, "PBM: DTD prev->next : back link wrong\n");
-    }
-    if (dtd->next == NULL) {
-        if ((dtd->parent != NULL)
-            && (dtd->parent->last != (xmlNodePtr) dtd))
-            fprintf(output, "PBM: DTD has no next and not last of list\n");
-    } else {
-        if (dtd->next->prev != (xmlNodePtr) dtd)
-            fprintf(output, "PBM: DTD next->prev : forward link wrong\n");
-    }
-    if (dtd->children == NULL)
-        fprintf(output, "    DTD is empty\n");
-    else
-        xmlDebugDumpNodeList(output, dtd->children, 1);
+    xmlCtxtDumpInitCtxt(&ctxt);
+    ctxt.output = output;
+    xmlCtxtDumpDTD(&ctxt, dtd);
 }
 
-static void
-xmlDebugDumpEntityCallback(xmlEntityPtr cur, FILE *output) {
-    if (cur == NULL) {
-	fprintf(output, "Entity is NULL");
-	return;
-    }
-    fprintf(output, "%s : ", (char *)cur->name);
-    switch (cur->etype) {
-	case XML_INTERNAL_GENERAL_ENTITY:
-	    fprintf(output, "INTERNAL GENERAL, ");
-	    break;
-	case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
-	    fprintf(output, "EXTERNAL PARSED, ");
-	    break;
-	case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
-	    fprintf(output, "EXTERNAL UNPARSED, ");
-	    break;
-	case XML_INTERNAL_PARAMETER_ENTITY:
-	    fprintf(output, "INTERNAL PARAMETER, ");
-	    break;
-	case XML_EXTERNAL_PARAMETER_ENTITY:
-	    fprintf(output, "EXTERNAL PARAMETER, ");
-	    break;
-	default:
-	    fprintf(output, "UNKNOWN TYPE %d",
-		    (char *)cur->etype);
-    }
-    if (cur->ExternalID != NULL) 
-	fprintf(output, "ID \"%s\"", (char *)cur->ExternalID);
-    if (cur->SystemID != NULL)
-	fprintf(output, "SYSTEM \"%s\"", (char *)cur->SystemID);
-    if (cur->orig != NULL)
-	fprintf(output, "\n orig \"%s\"", (char *)cur->orig);
-    if ((cur->type != XML_ELEMENT_NODE) &&
-	(cur->content != NULL))
-	fprintf(output, "\n content \"%s\"", (char *)cur->content);
-    fprintf(output, "\n");	
-}
-
-/**
- * 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)
-{
-    if (output == NULL)
-        output = stdout;
-    if (doc == NULL) {
-        fprintf(output, "DOCUMENT == NULL !\n");
-        return;
-    }
-
-    switch (doc->type) {
-        case XML_ELEMENT_NODE:
-            fprintf(output, "Error, ELEMENT found here ");
-            break;
-        case XML_ATTRIBUTE_NODE:
-            fprintf(output, "Error, ATTRIBUTE found here\n");
-            break;
-        case XML_TEXT_NODE:
-            fprintf(output, "Error, TEXT\n");
-            break;
-        case XML_CDATA_SECTION_NODE:
-            fprintf(output, "Error, CDATA_SECTION\n");
-            break;
-        case XML_ENTITY_REF_NODE:
-            fprintf(output, "Error, ENTITY_REF\n");
-            break;
-        case XML_ENTITY_NODE:
-            fprintf(output, "Error, ENTITY\n");
-            break;
-        case XML_PI_NODE:
-            fprintf(output, "Error, PI\n");
-            break;
-        case XML_COMMENT_NODE:
-            fprintf(output, "Error, COMMENT\n");
-            break;
-        case XML_DOCUMENT_NODE:
-            fprintf(output, "DOCUMENT\n");
-            break;
-        case XML_HTML_DOCUMENT_NODE:
-            fprintf(output, "HTML DOCUMENT\n");
-            break;
-        case XML_DOCUMENT_TYPE_NODE:
-            fprintf(output, "Error, DOCUMENT_TYPE\n");
-            break;
-        case XML_DOCUMENT_FRAG_NODE:
-            fprintf(output, "Error, DOCUMENT_FRAG\n");
-            break;
-        case XML_NOTATION_NODE:
-            fprintf(output, "Error, NOTATION\n");
-            break;
-        default:
-            fprintf(output, "NODE_%d\n", (char *)doc->type);
-    }
-    if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
-        xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
-            doc->intSubset->entities;
-
-        fprintf(output, "Entities in internal subset\n");
-        xmlHashScan(table, (xmlHashScanner) xmlDebugDumpEntityCallback,
-                    output);
-    } else
-        fprintf(output, "No entities in internal subset\n");
-    if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
-        xmlEntitiesTablePtr table = (xmlEntitiesTablePtr)
-            doc->extSubset->entities;
-
-        fprintf(output, "Entities in external subset\n");
-        xmlHashScan(table, (xmlHashScanner) xmlDebugDumpEntityCallback,
-                    output);
-    } else
-        fprintf(output, "No entities in external subset\n");
-}
+/************************************************************************
+ *									*
+ *			Helpers for Shell				*
+ *									*
+ ************************************************************************/
 
 /**
  * xmlLsCountNode:
diff --git a/include/libxml/xmlversion.h.in b/include/libxml/xmlversion.h.in
index 8f261b2..cf06429 100644
--- a/include/libxml/xmlversion.h.in
+++ b/include/libxml/xmlversion.h.in
@@ -295,6 +295,15 @@
 #endif
 
 /**
+ * LIBXML_DEBUG_RUNTIME:
+ *
+ * Whether the runtime debugging is configured in
+ */
+#if @WITH_MEM_DEBUG@
+#define LIBXML_DEBUG_RUNTIME
+#endif
+
+/**
  * LIBXML_UNICODE_ENABLED:
  *
  * Whether the Unicode related interfaces are compiled in
diff --git a/include/libxml/xmlwin32version.h.in b/include/libxml/xmlwin32version.h.in
index da76f74..8d740f5 100644
--- a/include/libxml/xmlwin32version.h.in
+++ b/include/libxml/xmlwin32version.h.in
@@ -202,6 +202,15 @@
 #endif
 
 /**
+ * LIBXML_DEBUG_RUNTIME:
+ *
+ * Whether the runtime debugging is configured in
+ */
+#if 0
+#define LIBXML_DEBUG_RUNTIME
+#endif
+
+/**
  * LIBXML_DLL_IMPORT:
  *
  * Used on Windows (MS C compiler only) to declare a variable as