adding repeated parsing and validating tests make the new DOM tree

* 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.
Daniel
diff --git a/tree.c b/tree.c
index 0fcfedf..4eed575 100644
--- a/tree.c
+++ b/tree.c
@@ -914,6 +914,18 @@
 }
 
 /**
+ * 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));
+
+/**
  * xmlFreeDtd:
  * @cur:  the DTD structure to free up
  *
@@ -921,13 +933,12 @@
  */
 void
 xmlFreeDtd(xmlDtdPtr cur) {
+    xmlDictPtr dict = NULL;
+
     if (cur == NULL) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlFreeDtd : DTD == NULL\n");
-#endif
 	return;
     }
+    if (cur->doc != NULL) dict = cur->doc->dict;
 
     if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
 	xmlDeregisterNodeDefaultValue((xmlNodePtr)cur);
@@ -948,9 +959,9 @@
 	    c = next;
 	}
     }
-    if (cur->name != NULL) xmlFree((char *) cur->name);
-    if (cur->SystemID != NULL) xmlFree((char *) cur->SystemID);
-    if (cur->ExternalID != NULL) xmlFree((char *) cur->ExternalID);
+    DICT_FREE(cur->name)
+    DICT_FREE(cur->SystemID)
+    DICT_FREE(cur->ExternalID)
     /* TODO !!! */
     if (cur->notations != NULL)
         xmlFreeNotationTable((xmlNotationTablePtr) cur->notations);
@@ -1019,6 +1030,7 @@
 void
 xmlFreeDoc(xmlDocPtr cur) {
     xmlDtdPtr extSubset, intSubset;
+    xmlDictPtr dict = NULL;
 
     if (cur == NULL) {
 #ifdef DEBUG_TREE
@@ -1027,6 +1039,7 @@
 #endif
 	return;
     }
+    if (cur != NULL) dict = cur->dict;
 
     if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
 	xmlDeregisterNodeDefaultValue((xmlNodePtr)cur);
@@ -1054,13 +1067,14 @@
     }
 
     if (cur->children != NULL) xmlFreeNodeList(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);
+
+    DICT_FREE(cur->version)
+    DICT_FREE(cur->name)
+    DICT_FREE(cur->encoding)
+    DICT_FREE(cur->URL)
     xmlFree(cur);
+    if (dict) xmlDictFree(dict);
 }
 
 /**
@@ -1915,13 +1929,7 @@
 void
 xmlFreePropList(xmlAttrPtr cur) {
     xmlAttrPtr next;
-    if (cur == NULL) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlFreePropList : property == NULL\n");
-#endif
-	return;
-    }
+    if (cur == NULL) return;
     while (cur != NULL) {
         next = cur->next;
         xmlFreeProp(cur);
@@ -1937,13 +1945,10 @@
  */
 void
 xmlFreeProp(xmlAttrPtr cur) {
-    if (cur == NULL) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlFreeProp : property == NULL\n");
-#endif
-	return;
-    }
+    xmlDictPtr dict = NULL;
+    if (cur == NULL) return;
+
+    if (cur->doc != NULL) dict = cur->doc->dict;
 
     if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
 	xmlDeregisterNodeDefaultValue((xmlNodePtr)cur);
@@ -1955,8 +1960,8 @@
         if (xmlIsID(cur->parent->doc, cur->parent, cur))
 	    xmlRemoveID(cur->parent->doc, cur);
     }
-    if (cur->name != NULL) xmlFree((char *) cur->name);
     if (cur->children != NULL) xmlFreeNodeList(cur->children);
+    DICT_FREE(cur->name)
     xmlFree(cur);
 }
 
@@ -3187,13 +3192,9 @@
 void
 xmlFreeNodeList(xmlNodePtr cur) {
     xmlNodePtr next;
-    if (cur == NULL) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlFreeNodeList : node == NULL\n");
-#endif
-	return;
-    }
+    xmlDictPtr dict = NULL;
+
+    if (cur == NULL) return;
     if (cur->type == XML_NAMESPACE_DECL) {
 	xmlFreeNsList((xmlNsPtr) cur);
 	return;
@@ -3206,9 +3207,9 @@
 	xmlFreeDoc((xmlDocPtr) cur);
 	return;
     }
+    if (cur->doc != NULL) dict = cur->doc->dict;
     while (cur != NULL) {
         next = cur->next;
-	/* unroll to speed up freeing the document */
 	if (cur->type != XML_DTD_NODE) {
 
 	    if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
@@ -3226,7 +3227,7 @@
 		(cur->type != XML_XINCLUDE_START) &&
 		(cur->type != XML_XINCLUDE_END) &&
 		(cur->type != XML_ENTITY_REF_NODE)) {
-		if (cur->content != NULL) xmlFree(cur->content);
+		DICT_FREE(cur->content)
 	    }
 	    if (((cur->type == XML_ELEMENT_NODE) ||
 	         (cur->type == XML_XINCLUDE_START) ||
@@ -3237,28 +3238,13 @@
 	    /*
 	     * When a node is a text node or a comment, it uses a global static
 	     * variable for the name of the node.
-	     *
-	     * The xmlStrEqual comparisons need to be done when (happened with
-	     * XML::libXML and XML::libXSLT) the library is included twice
-	     * statically in the binary and a tree allocated by one occurrence
-	     * of the lib gets freed by the other occurrence, in this case
-	     * the string addresses compare are not sufficient.
+	     * Otherwise the node name might come from the document's
+	     * dictionnary
 	     */
 	    if ((cur->name != NULL) &&
-		(cur->name != xmlStringText) &&
-		(cur->name != xmlStringTextNoenc) &&
-		(cur->name != xmlStringComment)) {
-		if (cur->type == XML_TEXT_NODE) {
-		    if ((!xmlStrEqual(cur->name, xmlStringText)) &&
-			(!xmlStrEqual(cur->name, xmlStringTextNoenc)))
-			xmlFree((char *) cur->name);
-		} else if (cur->type == XML_COMMENT_NODE) {
-		    if (!xmlStrEqual(cur->name, xmlStringComment))
-			xmlFree((char *) cur->name);
-		} else
-		    xmlFree((char *) cur->name);
-	    }
-	    /* TODO : derecursivate this function */
+		(cur->type != XML_TEXT_NODE) &&
+		(cur->type != XML_COMMENT_NODE))
+		DICT_FREE(cur->name)
 	    xmlFree(cur);
 	}
 	cur = next;
@@ -3274,13 +3260,9 @@
  */
 void
 xmlFreeNode(xmlNodePtr cur) {
-    if (cur == NULL) {
-#ifdef DEBUG_TREE
-        xmlGenericError(xmlGenericErrorContext,
-		"xmlFreeNode : node == NULL\n");
-#endif
-	return;
-    }
+    xmlDictPtr dict = NULL;
+
+    if (cur == NULL) return;
 
     /* use xmlFreeDtd for DTD nodes */
     if (cur->type == XML_DTD_NODE) {
@@ -3299,6 +3281,8 @@
     if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
 	xmlDeregisterNodeDefaultValue(cur);
 
+    if (cur->doc != NULL) dict = cur->doc->dict;
+
     if ((cur->children != NULL) &&
 	(cur->type != XML_ENTITY_REF_NODE))
 	xmlFreeNodeList(cur->children);
@@ -3312,33 +3296,18 @@
 	(cur->type != XML_ENTITY_REF_NODE) &&
 	(cur->type != XML_XINCLUDE_END) &&
 	(cur->type != XML_XINCLUDE_START)) {
-	xmlFree(cur->content);
+	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.
-     *
-     * The xmlStrEqual comparisons need to be done when (happened with
-     * XML::libXML and XML::libXSLT) the library is included twice statically
-     * in the binary and a tree allocated by one occurence of the lib gets
-     * freed by the other occurrence, in this case the string addresses compare
-     * are not sufficient.
+     * Otherwise the node name might come from the document's dictionnary
      */
     if ((cur->name != NULL) &&
-	(cur->name != xmlStringText) &&
-	(cur->name != xmlStringTextNoenc) &&
-	(cur->name != xmlStringComment)) {
-	if (cur->type == XML_TEXT_NODE) {
-            if ((!xmlStrEqual(cur->name, xmlStringText)) &&
-		(!xmlStrEqual(cur->name, xmlStringTextNoenc)))
-		xmlFree((char *) cur->name);
-	} else if (cur->type == XML_COMMENT_NODE) {
-            if (!xmlStrEqual(cur->name, xmlStringComment))
-		xmlFree((char *) cur->name);
-	} else
-	    xmlFree((char *) cur->name);
-    }
+        (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) ||