Changed the internals a lot for DOM, entity support, slight changes of API,
more (if not all) formating of function comments, started documentation, Daniel.
diff --git a/ChangeLog b/ChangeLog
index d285e39..726f7f2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+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.
diff --git a/SAX.c b/SAX.c
index 56585eb..9b7e504 100644
--- a/SAX.c
+++ b/SAX.c
@@ -8,6 +8,7 @@
 #include <stdlib.h>
 #include "tree.h"
 #include "parser.h"
+#include "entities.h"
 #include "error.h"
 
 /* #define DEBUG_SAX */
@@ -85,8 +86,11 @@
  *
  * 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).
  *
- * return values: an int
+ * return values: the xmlParserInputPtr if inlined or NULL for DOM behaviour.
  */
 xmlParserInputPtr
 resolveEntity(xmlParserCtxtPtr ctxt, const CHAR *publicId, const CHAR *systemId)
@@ -95,6 +99,7 @@
 #ifdef DEBUG_SAX
     fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
 #endif
+
     return(NULL);
 }
 
@@ -206,16 +211,9 @@
 void
 startElement(xmlParserCtxtPtr ctxt, const CHAR *name)
 {
-    xmlNodePtr parent;
-
 #ifdef DEBUG_SAX
     fprintf(stderr, "SAX.startElement(%s)\n", name);
 #endif
-    if (ctxt->nodeNr < 2) return;
-    parent = ctxt->nodeTab[ctxt->nodeNr - 2];
-    if (parent != NULL)
-	xmlAddChild(parent, ctxt->node);
-    
 }
 
 /**
@@ -254,7 +252,6 @@
 #ifdef DEBUG_SAX
     fprintf(stderr, "SAX.attribute(%s, %s)\n", name, value);
 #endif
-    xmlNewProp(ctxt->node, name, value);
 }
 
 /**
diff --git a/doc/DOM.fig b/doc/DOM.fig
new file mode 100644
index 0000000..7a48a32
--- /dev/null
+++ b/doc/DOM.fig
@@ -0,0 +1,64 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter  
+100.00
+Single
+-2
+1200 2
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+	 825 1125 2625 1125 2625 3375 825 3375 825 1125
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+	 4125 1125 5925 1125 5925 3375 4125 3375 4125 1125
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+	 2025 3075 2025 1650 1050 1650 1050 3075 2025 3075
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+	 1425 1875 1575 1875 1575 2025 1425 2025 1425 1875
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+	 1200 2175 1350 2175 1350 2325 1200 2325 1200 2175
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+	 1500 2175 1650 2175 1650 2325 1500 2325 1500 2175
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+	 1800 2175 1950 2175 1950 2325 1800 2325 1800 2175
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+	 1500 2475 1650 2475 1650 2625 1500 2625 1500 2475
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+	 1725 2700 1875 2700 1875 2850 1725 2850 1725 2700
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+	 1275 2700 1425 2700 1425 2850 1275 2850 1275 2700
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 1500 2025 1350 2175
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 1500 2025 1575 2175
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 1500 2025 1875 2175
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 1575 2325 1575 2475
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 1650 2625 1725 2700
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 1500 2625 1425 2700
+2 3 0 2 0 7 0 0 -1 6.000 0 0 -1 0 0 5
+	 2550 1725 2175 1950 2175 2850 2550 3075 2550 1725
+2 3 0 2 0 7 0 0 -1 6.000 0 0 -1 0 0 5
+	 4575 1725 4200 1950 4200 2850 4575 3075 4575 1725
+2 2 0 1 0 7 0 0 -1 4.000 0 0 -1 0 0 5
+	 2700 2025 4050 2025 4050 2775 2700 2775 2700 2025
+2 1 0 2 0 7 0 0 -1 6.000 0 0 -1 0 0 2
+	 5025 2025 4575 2175
+2 1 1 2 0 7 0 0 -1 6.000 0 0 -1 1 0 3
+	1 1 2.00 120.00 240.00
+	 4575 2175 4200 2250 2025 2250
+2 1 1 2 0 7 0 0 -1 6.000 0 0 -1 0 0 3
+	 2025 2475 4200 2475 4575 2550
+2 1 0 2 0 7 0 0 -1 6.000 0 0 -1 1 0 2
+	1 1 2.00 120.00 240.00
+	 4575 2550 5025 2625
+4 0 0 0 0 0 18 0.0000 4 255 1155 1050 825 Program 1\001
+4 0 0 0 0 0 18 0.0000 4 255 1155 4425 900 Program 2\001
+4 0 0 0 0 0 18 0.0000 4 195 585 1350 1500 XML\001
+4 0 0 0 0 0 18 0.0000 4 195 975 3000 3075 CORBA\001
+4 0 0 0 0 0 18 0.0000 4 195 735 3000 3375 ORBit\001
+4 0 0 0 0 0 18 0.0000 4 195 1395 2175 1575 DOM server\001
+4 0 0 0 0 0 18 0.0000 4 195 1335 4200 1650 DOM client\001
diff --git a/doc/DOM.gif b/doc/DOM.gif
new file mode 100644
index 0000000..a44882f
--- /dev/null
+++ b/doc/DOM.gif
Binary files differ
diff --git a/doc/structure.fig b/doc/structure.fig
new file mode 100644
index 0000000..34f6237
--- /dev/null
+++ b/doc/structure.fig
@@ -0,0 +1,303 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter  
+100.00
+Single
+-2
+1200 2
+6 1275 4425 5475 5100
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+	 2250 5100 2250 4425 1275 4425 1275 5100 2250 5100
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+	 3975 5100 3975 4425 3000 4425 3000 5100 3975 5100
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+	 5475 5100 5475 4425 4500 4425 4500 5100 5475 5100
+4 0 0 0 0 14 16 0.0000 4 135 600 4650 4725 TEXT\001
+4 0 0 0 0 14 16 0.0000 4 135 600 1425 4725 TEXT\001
+4 0 0 0 0 14 16 0.0000 4 135 900 3075 4725 ENTITY\001
+4 0 0 0 0 14 16 0.0000 4 135 450 3075 4950 REF\001
+-6
+6 825 4575 900 5100
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 900 4575 900 5100
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 900 5025 825 5100
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 900 4950 825 5025
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 900 4800 825 4875
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 900 4875 825 4950
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 900 4650 825 4725
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 900 4725 825 4800
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 900 4575 825 4650
+-6
+6 1125 2325 1200 2850
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 1200 2325 1200 2850
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 1200 2775 1125 2850
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 1200 2700 1125 2775
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 1200 2550 1125 2625
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 1200 2625 1125 2700
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 1200 2400 1125 2475
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 1200 2475 1125 2550
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 1200 2325 1125 2400
+-6
+6 2550 4650 2625 5175
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 2625 4650 2625 5175
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 2625 5100 2550 5175
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 2625 5025 2550 5100
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 2625 4875 2550 4950
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 2625 4950 2550 5025
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 2625 4725 2550 4800
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 2625 4800 2550 4875
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 2625 4650 2550 4725
+-6
+6 6000 4200 6075 4725
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 6075 4200 6075 4725
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 6075 4650 6000 4725
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 6075 4575 6000 4650
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 6075 4425 6000 4500
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 6075 4500 6000 4575
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 6075 4275 6000 4350
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 6075 4350 6000 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 6075 4200 6000 4275
+-6
+6 2475 4425 2550 4950
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 2475 4950 2475 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 2475 4500 2550 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 2475 4575 2550 4500
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 2475 4725 2550 4650
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 2475 4650 2550 4575
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 2475 4875 2550 4800
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 2475 4800 2550 4725
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 2475 4950 2550 4875
+-6
+6 5775 4425 5850 4950
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 5775 4950 5775 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 5775 4500 5850 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 5775 4575 5850 4500
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 5775 4725 5850 4650
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 5775 4650 5850 4575
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 5775 4875 5850 4800
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 5775 4800 5850 4725
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 5775 4950 5850 4875
+-6
+6 9000 2100 9075 2625
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 9000 2625 9000 2100
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 9000 2175 9075 2100
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 9000 2250 9075 2175
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 9000 2400 9075 2325
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 9000 2325 9075 2250
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 9000 2550 9075 2475
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 9000 2475 9075 2400
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 9000 2625 9075 2550
+-6
+6 11850 4050 11925 4575
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 11850 4575 11850 4050
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 11850 4125 11925 4050
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 11850 4200 11925 4125
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 11850 4350 11925 4275
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 11850 4275 11925 4200
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 11850 4500 11925 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 11850 4425 11925 4350
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 2
+	 11850 4575 11925 4500
+-6
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+	 3150 375 4425 375 4425 1275 3150 1275 3150 375
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+	 2850 2775 2850 2100 1875 2100 1875 2775 2850 2775
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+	 5550 2775 5550 2100 4575 2100 4575 2775 5550 2775
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+	 8175 2775 8175 2100 7200 2100 7200 2775 8175 2775
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+	 7650 4725 7650 4050 6675 4050 6675 4725 7650 4725
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+	 9675 4725 9675 4050 8700 4050 8700 4725 9675 4725
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 3750 1275 2400 2100
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 2850 2325 4575 2325
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 5550 2325 7200 2325
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 8175 2325 9000 2325
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 7200 2550 5550 2550
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 4575 2550 2850 2550
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 1875 2550 1200 2550
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 2250 2100 3525 1275
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 5100 2100 4050 1275
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 7725 2100 4125 1275
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 7725 2775 7125 4050
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 7650 4275 8700 4275
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 8700 4425 7650 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 9675 4275 10275 4275
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 6675 4500 6075 4500
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+	 1275 3375 2250 3375 2250 3825 1275 3825 1275 3375
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+	 3000 3375 3975 3375 3975 3825 3000 3825 3000 3375
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 2325 2775 1725 3375
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 2250 3600 3000 3600
+2 4 0 1 0 7 0 0 -1 0.000 0 0 7 0 0 5
+	 11250 4725 11250 4050 10275 4050 10275 4725 11250 4725
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 11250 4275 11850 4275
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 10275 4425 9675 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 1725 3825 1725 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 3450 3825 3450 4425
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 3975 4650 4500 4650
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 5475 4650 5775 4650
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 4500 4875 3975 4875
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 2250 4650 2550 4650
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 1275 4875 900 4875
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+	 975 5625 2550 5625 2550 5850 975 5850 975 5625
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+	 4200 5625 5775 5625 5775 5850 4200 5850 4200 5625
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+	 6450 5250 8025 5250 8025 5475 6450 5475 6450 5250
+2 2 0 1 0 7 0 0 -1 0.000 0 0 -1 0 0 5
+	 10125 5250 11700 5250 11700 5475 10125 5475 10125 5250
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 1725 5100 1725 5625
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 4875 5100 4875 5625
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 7050 4725 7050 5250
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 10650 4725 10650 5250
+2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
+	1 1 1.00 60.00 120.00
+	 3000 4875 2625 4875
+4 0 0 0 0 0 16 0.0000 4 150 420 3000 2250 next\001
+4 0 0 0 0 0 16 0.0000 4 180 450 3975 2775 prev\001
+4 0 0 0 0 0 16 0.0000 4 210 630 5100 2025 parent\001
+4 0 0 0 0 14 15 0.0000 4 135 945 7200 2475 ELEMENT\001
+4 0 0 0 0 14 15 0.0000 4 135 945 4575 2475 ELEMENT\001
+4 0 0 0 0 14 15 0.0000 4 135 945 1875 2475 ELEMENT\001
+4 0 0 0 0 14 16 0.0000 4 135 450 8775 4590 REF\001
+4 0 0 0 0 14 16 0.0000 4 135 900 8775 4350 ENTITY\001
+4 0 0 0 0 14 16 0.0000 4 135 600 10350 4425 TEXT\001
+4 0 0 0 0 14 16 0.0000 4 135 600 6750 4425 TEXT\001
+4 0 0 0 0 14 16 0.0000 4 150 1050 1275 2025 xmlNode\001
+4 0 0 0 0 14 16 0.0000 4 150 900 2175 675 xmlDoc\001
+4 0 0 0 0 14 16 0.0000 4 150 1050 675 3300 xmlAttr\001
+4 0 0 0 0 14 16 0.0000 4 135 1200 3225 825 DOCUMENT\001
+4 0 0 0 0 0 16 0.0000 4 150 390 3375 1650 root\001
+4 0 0 0 0 -1 20 0.0000 4 285 4770 5175 825 A DOM tree as built by the XML parser\001
+4 0 0 0 0 -1 20 0.0000 4 180 465 1050 6150 text\001
+4 0 0 0 0 -1 16 0.0000 4 225 990 2250 3000 properties\001
+4 0 0 0 0 -1 16 0.0000 4 150 720 1800 5475 content\001
diff --git a/doc/structure.gif b/doc/structure.gif
new file mode 100644
index 0000000..6711480
--- /dev/null
+++ b/doc/structure.gif
Binary files differ
diff --git a/doc/xml.html b/doc/xml.html
new file mode 100644
index 0000000..d0f57a4
--- /dev/null
+++ b/doc/xml.html
@@ -0,0 +1,78 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
+   "http://www.w3.org/TR/REC-html40/loose.dtd">
+<html>
+<head>
+<title>No title</title>
+<meta name="GENERATOR" content="amaya V1.3b">
+</head>
+<body bgcolor="#ffffff">
+
+<h1 align="center">The XML library for Gnome</h1>
+<p>
+This document describes the <a href="http://www.w3.org/XML/">XML</a> library
+provideed in the <a href="http://www.gnome.org/">Gnome</a> framework. XML is a
+standard to build tag based structured documents. The internal document
+repesentation is as close as possible to the <a
+href="http://www.w3.org/DOM/">DOM</a> interfaces.</p>
+
+<h2>xml</h2>
+<p>
+XML is a standard for markup based structured documents, here is an
+example:</p>
+<pre>&lt;?xml version="1.0"?>
+&lt;EXAMPLE prop1="gnome is great" prop2="&amp;linux; too">
+  &lt;head>
+   &lt;title>Welcome to Gnome&lt;/title>
+  &lt;/head>
+  &lt;chapter>
+   &lt;title>The Linux adventure&lt;/title>
+   &lt;p>bla bla bla ...&lt;/p>
+   &lt;image href="linus.gif"/>
+   &lt;p>...&lt;/p>
+  &lt;/chapter>
+&lt;/EXAMPLE></pre>
+<p>
+ </p>
+
+<h2>Invoking the parser</h2>
+
+<h2>The tree output</h2>
+<p>
+The parser returns a tree built during the document analysis. The value
+returned is an <strong>xmlDocPtr</strong> (i.e. a pointer to an
+<strong>xmlDoc</strong> structure). This structure contains informations like
+the file  name, the document type, and a <strong>root</strong> pointer which
+is the root of the document (or more exactly the first child under the root
+which is the document). The tree is made of <strong>xmlNode</strong>s, chained
+in double linked lists of siblings and with childs&lt;->parent relationship.
+An xmlNode can also carry properties (a chain of xmlAttr structures). An
+attribute may have a value which is a list of TEXT or ENTITY_REF nodes.</p>
+<p>
+Here is an example (erroneous w.r.t. the XML spec since there should be only
+one ELEMENT under the root):</p>
+<p>
+<img src="structure.gif" alt=" structure.gif "></p>
+<p>
+</p>
+
+<h2>Modifying the tree</h2>
+
+<h2>Saving a tree</h2>
+
+<h2>DOM interfaces</h2>
+<p>
+<a href="http://www.w3.org/DOM/">DOM</a> stands for the <em>Document Object
+Model</em> this is an API for accessing XML or HTML structured documents.
+Native support for DOM in Gnome is on the way (module gnome-dom), and it will
+be based on gnome-xml. DOM defiles a set of IDL (or Java) interfaces allowing
+to traverse and manipulate a document. The DOM library will allow accessing
+and modifying "live" documents presents on other programs like this:</p>
+<p>
+<img src="DOM.gif" alt=" DOM.gif "></p>
+<p>
+This should help greatly doing things like modifying a gnumeric spreadsheet
+embedded in a GWP document for example.</p>
+<p>
+</p>
+</body>
+</html>
diff --git a/encoding.c b/encoding.c
index 02ff02a..7753419 100644
--- a/encoding.c
+++ b/encoding.c
@@ -77,7 +77,7 @@
     unsigned char* outstart= out;
     unsigned char* outend= out+outlen;
     unsigned char* inend= in+inlen;
-    unsigned char c, d;
+    unsigned char c;
 
     while (in < inend) {
         c= *in++;
diff --git a/entities.c b/entities.c
index 5a788e6..351746c 100644
--- a/entities.c
+++ b/entities.c
@@ -143,6 +143,29 @@
     }
 }
 
+/**
+ * xmlGetPredefinedEntity:
+ * @name:  the entity name
+ *
+ * Check whether this name is an predefined entity.
+ *
+ * return values: NULL if not, othervise the entity
+ */
+xmlEntityPtr
+xmlGetPredefinedEntity(const CHAR *name) {
+    int i;
+    xmlEntityPtr cur;
+
+    if (xmlPredefinedEntities == NULL)
+        xmlInitializePredefinedEntities();
+    for (i = 0;i < xmlPredefinedEntities->nb_entities;i++) {
+	cur = &xmlPredefinedEntities->table[i];
+	if (!xmlStrcmp(cur->name, name)) return(cur);
+    }
+    return(NULL);
+}
+
+
 
 /*
  * xmlAddDtdEntity : register a new entity for this DTD.
diff --git a/entities.h b/entities.h
index 0065245..6f971c0 100644
--- a/entities.h
+++ b/entities.h
@@ -8,8 +8,8 @@
 
 #ifndef __XML_ENTITIES_H__
 #define __XML_ENTITIES_H__
-#include "parser.h"
 
+#include "parser.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -48,6 +48,7 @@
     xmlEntityPtr table;		/* the table of entities */
 } xmlEntitiesTable, *xmlEntitiesTablePtr;
 
+
 /*
  * External functions :
  */
@@ -56,12 +57,15 @@
               const CHAR *ExternalID, const CHAR *SystemID, CHAR *content);
 extern void xmlAddDtdEntity(xmlDocPtr doc, const CHAR *name, int type,
               const CHAR *ExternalID, const CHAR *SystemID, CHAR *content);
+extern xmlEntityPtr xmlGetPredefinedEntity(const CHAR *name);
 extern xmlEntityPtr xmlGetDocEntity(xmlDocPtr doc, const CHAR *name);
 extern xmlEntityPtr xmlGetDtdEntity(xmlDocPtr doc, const CHAR *name);
 extern CHAR *xmlEncodeEntities(xmlDocPtr doc, const CHAR *input);
 extern xmlEntitiesTablePtr xmlCreateEntitiesTable(void);
 extern void xmlFreeEntitiesTable(xmlEntitiesTablePtr table);
 extern void xmlDumpEntitiesTable(xmlEntitiesTablePtr table);
+extern xmlParserInputPtr xmlNewEntityInputStream(xmlParserCtxtPtr ctxt,
+                                                 xmlEntityPtr entity);
 
 #ifdef __cplusplus
 }
diff --git a/include/libxml/entities.h b/include/libxml/entities.h
index 0065245..6f971c0 100644
--- a/include/libxml/entities.h
+++ b/include/libxml/entities.h
@@ -8,8 +8,8 @@
 
 #ifndef __XML_ENTITIES_H__
 #define __XML_ENTITIES_H__
-#include "parser.h"
 
+#include "parser.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -48,6 +48,7 @@
     xmlEntityPtr table;		/* the table of entities */
 } xmlEntitiesTable, *xmlEntitiesTablePtr;
 
+
 /*
  * External functions :
  */
@@ -56,12 +57,15 @@
               const CHAR *ExternalID, const CHAR *SystemID, CHAR *content);
 extern void xmlAddDtdEntity(xmlDocPtr doc, const CHAR *name, int type,
               const CHAR *ExternalID, const CHAR *SystemID, CHAR *content);
+extern xmlEntityPtr xmlGetPredefinedEntity(const CHAR *name);
 extern xmlEntityPtr xmlGetDocEntity(xmlDocPtr doc, const CHAR *name);
 extern xmlEntityPtr xmlGetDtdEntity(xmlDocPtr doc, const CHAR *name);
 extern CHAR *xmlEncodeEntities(xmlDocPtr doc, const CHAR *input);
 extern xmlEntitiesTablePtr xmlCreateEntitiesTable(void);
 extern void xmlFreeEntitiesTable(xmlEntitiesTablePtr table);
 extern void xmlDumpEntitiesTable(xmlEntitiesTablePtr table);
+extern xmlParserInputPtr xmlNewEntityInputStream(xmlParserCtxtPtr ctxt,
+                                                 xmlEntityPtr entity);
 
 #ifdef __cplusplus
 }
diff --git a/include/libxml/parser.h b/include/libxml/parser.h
index d0ca958..51ba467 100644
--- a/include/libxml/parser.h
+++ b/include/libxml/parser.h
@@ -128,6 +128,8 @@
 extern xmlSAXLocator xmlDefaultSAXLocator;
 extern xmlSAXHandler xmlDefaultSAXHandler;
 
+#include "entities.h"
+
 /*
  * Interfaces
  */
diff --git a/include/libxml/tree.h b/include/libxml/tree.h
index 91677a6..2ebe2cd 100644
--- a/include/libxml/tree.h
+++ b/include/libxml/tree.h
@@ -16,7 +16,30 @@
 #endif
 
 /*
- * Type definitions
+ * 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/
+ */
+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
+} xmlElementType;
+
+/*
+ * Currently we use only 8bit chars internal representation, but
+ * the parser is not tied to that, just define UNICODE to switch to
+ * a 16 bits representation.
  */
 #ifdef UNICODE
 typedef unsigned short CHAR;
@@ -84,37 +107,22 @@
     void           *_private;	/* for Corba, must be first ! */
     void           *vepv;	/* for Corba, must be next ! */
 #endif
-    int             type;       /* XML_ATTRIBUTE_NODE, must be third ! */
+    xmlElementType  type;       /* XML_ATTRIBUTE_NODE, must be third ! */
     struct xmlNode *node;	/* attr->node link */
     struct xmlAttr *next;	/* parent->childs link */
     const CHAR     *name;       /* the name of the property */
-    const CHAR     *value;      /* the value of the property */
+    struct xmlNode *val;        /* the value of the property */
 } xmlAttr, *xmlAttrPtr;
 
 /*
  * A node in an XML tree.
- * NOTE: This is synchronized with DOM Level1 values
- *       See http://www.w3.org/TR/REC-DOM-Level-1/
  */
-#define XML_ELEMENT_NODE	1
-#define XML_ATTRIBUTE_NODE	2
-#define XML_TEXT_NODE		3
-#define XML_CDATA_SECTION_NODE	4
-#define XML_ENTITY_REF_NODE	5
-#define XML_ENTITY_NODE		6
-#define XML_PI_NODE		7
-#define XML_COMMENT_NODE	8
-#define XML_DOCUMENT_NODE	9
-#define XML_DOCUMENT_TYPE_NODE	10
-#define XML_DOCUMENT_FRAG_NODE	11
-#define XML_NOTATION_NODE	12
-
 typedef struct xmlNode {
 #ifndef XML_WITHOUT_CORBA
     void           *_private;	/* for Corba, must be first ! */
     void           *vepv;	/* for Corba, must be next ! */
 #endif
-    int             type;	/* type number in the DTD, must be third ! */
+    xmlElementType  type;	/* type number in the DTD, must be third ! */
     struct xmlDoc  *doc;	/* the containing document */
     struct xmlNode *parent;	/* child->parent link */
     struct xmlNode *next;	/* next sibling link  */
@@ -135,7 +143,7 @@
     void           *_private;	/* for Corba, must be first ! */
     void           *vepv;	/* for Corba, must be next ! */
 #endif
-    int             type;       /* XML_DOCUMENT_NODE, must be second ! */
+    xmlElementType  type;       /* XML_DOCUMENT_NODE, must be second ! */
     char           *name;	/* name/filename/URI of the document */
     const CHAR     *version;	/* the XML version string */
     const CHAR     *encoding;   /* encoding, if any */
@@ -165,22 +173,27 @@
 extern void xmlFreeNs(xmlNsPtr cur);
 extern xmlDocPtr xmlNewDoc(const CHAR *version);
 extern void xmlFreeDoc(xmlDocPtr cur);
+extern xmlAttrPtr xmlNewDocProp(xmlDocPtr doc, const CHAR *name,
+                                const CHAR *value);
 extern xmlAttrPtr xmlNewProp(xmlNodePtr node, const CHAR *name,
                              const CHAR *value);
 extern xmlAttrPtr xmlSetProp(xmlNodePtr node, const CHAR *name,
                              const CHAR *value);
 extern const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name);
+extern xmlNodePtr xmlStringGetNodeList(xmlDocPtr doc, const CHAR *value);
+extern CHAR *xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine);
 extern void xmlFreePropList(xmlAttrPtr cur);
 extern void xmlFreeProp(xmlAttrPtr cur);
 extern xmlNodePtr xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns,
                              const CHAR *name, CHAR *content);
-extern xmlNodePtr xmlNewNode(xmlNsPtr ns, const CHAR *name, CHAR *content);
+extern xmlNodePtr xmlNewNode(xmlNsPtr ns, const CHAR *name);
 extern xmlNodePtr xmlNewDocText(xmlDocPtr doc, const CHAR *content);
 extern xmlNodePtr xmlNewText(const CHAR *content);
 extern xmlNodePtr xmlNewDocTextLen(xmlDocPtr doc, const CHAR *content, int len);
 extern xmlNodePtr xmlNewTextLen(const CHAR *content, int len);
 extern xmlNodePtr xmlNewDocComment(xmlDocPtr doc, CHAR *content);
 extern xmlNodePtr xmlNewComment(CHAR *content);
+extern xmlNodePtr xmlNewReference(xmlDocPtr doc, const CHAR *name);
 extern xmlNodePtr xmlAddChild(xmlNodePtr parent, xmlNodePtr cur);
 extern xmlNodePtr xmlGetLastChild(xmlNodePtr node);
 extern int xmlNodeIsText(xmlNodePtr node);
diff --git a/parser.c b/parser.c
index 299a09a..47323e0 100644
--- a/parser.c
+++ b/parser.c
@@ -58,7 +58,10 @@
 type name##Pop(xmlParserCtxtPtr ctxt) {					\
     if (ctxt->name##Nr <= 0) return(0);					\
     ctxt->name##Nr--;							\
-    ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1];			\
+    if (ctxt->name##Nr > 0)						\
+	ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1];		\
+    else								\
+        ctxt->name = NULL;						\
     return(ctxt->name);							\
 }									\
 
@@ -123,31 +126,33 @@
  * @entity:  an Entity pointer
  *
  * Create a new input stream based on a memory buffer.
+ * return vakues: the new input stream
  */
-void xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
+xmlParserInputPtr
+xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
     xmlParserInputPtr input;
 
     if (entity == NULL) {
         xmlParserError(ctxt,
 	      "internal: xmlNewEntityInputStream entity = NULL\n");
-	return;
+	return(NULL);
     }
     if (entity->content == NULL) {
         xmlParserError(ctxt,
 	      "internal: xmlNewEntityInputStream entity->input = NULL\n");
-	return;
+	return(NULL);
     }
     input = (xmlParserInputPtr) malloc(sizeof(xmlParserInput));
     if (input == NULL) {
 	xmlParserError(ctxt, "malloc: couldn't allocate a new input stream\n");
-	return;
+	return(NULL);
     }
     input->filename = entity->SystemID; /* TODO !!! char <- CHAR */
     input->base = entity->content;
     input->cur = entity->content;
     input->line = 1;
     input->col = 1;
-    xmlPushInput(ctxt, input);
+    return(input);
 }
 
 /*
@@ -876,6 +881,7 @@
 
 void xmlHandleEntity(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
     int len;
+    xmlParserInputPtr input;
 
     if (entity->content == NULL) {
         xmlParserError(ctxt, "xmlHandleEntity %s: content == NULL\n",
@@ -888,7 +894,8 @@
     /*
      * Redefine its content as an input stream.
      */
-    xmlNewEntityInputStream(ctxt, entity);
+    input = xmlNewEntityInputStream(ctxt, entity);
+    xmlPushInput(ctxt, input);
     return;
 
 handle_as_char:
@@ -904,8 +911,8 @@
  * Forward definition for recusive behaviour.
  */
 xmlNodePtr xmlParseElement(xmlParserCtxtPtr ctxt);
-CHAR *xmlParsePEReference(xmlParserCtxtPtr ctxt, int inLine);
-CHAR *xmlParseReference(xmlParserCtxtPtr ctxt, int inLine);
+CHAR *xmlParsePEReference(xmlParserCtxtPtr ctxt);
+CHAR *xmlParseReference(xmlParserCtxtPtr ctxt);
 
 /************************************************************************
  *									*
@@ -1231,13 +1238,22 @@
 	while ((IS_CHAR(CUR)) && (CUR != '"')) {
 	    if (CUR == '%') {
 	        ret = xmlStrncat(ret, q, CUR_PTR - q);
-	        cur = xmlParsePEReference(ctxt, 1);
+	        cur = xmlParsePEReference(ctxt);
 		ret = xmlStrcat(ret, cur);
 		q = CUR_PTR;
 	    } else if (CUR == '&') {
 	        ret = xmlStrncat(ret, q, CUR_PTR - q);
-	        cur = xmlParseReference(ctxt, 1);
-		ret = xmlStrcat(ret, cur);
+	        cur = xmlParseReference(ctxt);
+		if (cur != NULL) {
+		    CHAR buf[2];
+		    buf[0] = '&';
+		    buf[1] = 0;
+		    ret = xmlStrncat(ret, buf, 1);
+		    ret = xmlStrcat(ret, cur);
+		    buf[0] = ';';
+		    buf[1] = 0;
+		    ret = xmlStrncat(ret, buf, 1);
+		}
 		q = CUR_PTR;
 	    } else 
 	        NEXT;
@@ -1254,13 +1270,22 @@
 	while ((IS_CHAR(CUR)) && (CUR != '\'')) {
 	    if (CUR == '%') {
 	        ret = xmlStrncat(ret, q, CUR_PTR - q);
-	        cur = xmlParsePEReference(ctxt, 1);
+	        cur = xmlParsePEReference(ctxt);
 		ret = xmlStrcat(ret, cur);
 		q = CUR_PTR;
 	    } else if (CUR == '&') {
 	        ret = xmlStrncat(ret, q, CUR_PTR - q);
-	        cur = xmlParseReference(ctxt, 1);
-		ret = xmlStrcat(ret, cur);
+	        cur = xmlParseReference(ctxt);
+		if (cur != NULL) {
+		    CHAR buf[2];
+		    buf[0] = '&';
+		    buf[1] = 0;
+		    ret = xmlStrncat(ret, buf, 1);
+		    ret = xmlStrcat(ret, cur);
+		    buf[0] = ';';
+		    buf[1] = 0;
+		    ret = xmlStrncat(ret, buf, 1);
+		}
 		q = CUR_PTR;
 	    } else 
 	        NEXT;
@@ -1300,11 +1325,32 @@
 	while ((IS_CHAR(CUR)) && (CUR != '"')) {
 	    if (CUR == '&') {
 	        ret = xmlStrncat(ret, q, CUR_PTR - q);
-	        cur = xmlParseReference(ctxt, 1);
-		ret = xmlStrcat(ret, cur);
+	        cur = xmlParseReference(ctxt);
+		if (cur != NULL) {
+		    /*
+		     * Special case for '&amp;', we don't want to
+		     * resolve it here since it will break later
+		     * when searching entities in the string.
+		     */
+		    if ((cur[0] == '&') && (cur[1] == 0)) {
+		        CHAR buf[6] = { '&', 'a', 'm', 'p', ';', 0 };
+		        ret = xmlStrncat(ret, buf, 5);
+		    } else
+		        ret = xmlStrcat(ret, cur);
+		    free(cur);
+		}
 		q = CUR_PTR;
 	    } else 
 	        NEXT;
+	    /*
+	     * Pop out finished entity references.
+	     */
+	    while ((CUR == 0) && (ctxt->inputNr > 1)) {
+		if (CUR_PTR != q)
+		    ret = xmlStrncat(ret, q, CUR_PTR - q);
+	        xmlPopInput(ctxt);
+		q = CUR_PTR;
+	    }
 	}
 	if (!IS_CHAR(CUR)) {
 	    xmlParserError(ctxt, "Unfinished AttValue\n");
@@ -1318,11 +1364,32 @@
 	while ((IS_CHAR(CUR)) && (CUR != '\'')) {
 	    if (CUR == '&') {
 	        ret = xmlStrncat(ret, q, CUR_PTR - q);
-	        cur = xmlParseReference(ctxt, 1);
-		ret = xmlStrcat(ret, cur);
+	        cur = xmlParseReference(ctxt);
+		if (cur != NULL) {
+		    /*
+		     * Special case for '&amp;', we don't want to
+		     * resolve it here since it will break later
+		     * when searching entities in the string.
+		     */
+		    if ((cur[0] == '&') && (cur[1] == 0)) {
+		        CHAR buf[6] = { '&', 'a', 'm', 'p', ';', 0 };
+		        ret = xmlStrncat(ret, buf, 5);
+		    } else
+		        ret = xmlStrcat(ret, cur);
+		    free(cur);
+		}
 		q = CUR_PTR;
 	    } else 
 	        NEXT;
+	    /*
+	     * Pop out finished entity references.
+	     */
+	    while ((CUR == 0) && (ctxt->inputNr > 1)) {
+		if (CUR_PTR != q)
+		    ret = xmlStrncat(ret, q, CUR_PTR - q);
+	        xmlPopInput(ctxt);
+		q = CUR_PTR;
+	    }
 	}
 	if (!IS_CHAR(CUR)) {
 	    xmlParserError(ctxt, "Unfinished AttValue\n");
@@ -2060,7 +2127,6 @@
 /**
  * xmlParseCharRef:
  * @ctxt:  an XML parser context
- * @inLine:  handle it as inline or pass it to SAX as chars ?
  *
  * parse Reference declarations
  *
@@ -2068,7 +2134,7 @@
  *                  '&#x' [0-9a-fA-F]+ ';'
  * return values: the value parsed
  */
-CHAR *xmlParseCharRef(xmlParserCtxtPtr ctxt, int inLine) {
+CHAR *xmlParseCharRef(xmlParserCtxtPtr ctxt) {
     int val = 0;
     CHAR buf[2];
 
@@ -2114,10 +2180,7 @@
     if (IS_CHAR(val)) {
         buf[0] = (CHAR) val;
 	buf[1] = 0;
-	if (inLine)
-	    return(xmlStrndup(buf, 1));
-	else if (ctxt->sax != NULL)
-	    ctxt->sax->characters(ctxt, buf, 0, 1);
+	return(xmlStrndup(buf, 1));
     } else {
 	xmlParserError(ctxt, "xmlParseCharRef: invalid value");
     }
@@ -2127,18 +2190,19 @@
 /**
  * xmlParseEntityRef:
  * @ctxt:  an XML parser context
- * @inLine:  handle it as inline or pass it to SAX as chars ?
  *
  * parse ENTITY references declarations
  *
  * [68] EntityRef ::= '&' Name ';'
- * return values: the entity content, or NULL if directly handled (inLine == 0)
+ * return values: the entity ref string or NULL if directly as input stream.
  */
-CHAR *xmlParseEntityRef(xmlParserCtxtPtr ctxt, int inLine) {
+CHAR *xmlParseEntityRef(xmlParserCtxtPtr ctxt) {
     CHAR *ret = NULL;
+    const CHAR *q;
     CHAR *name;
-    xmlEntityPtr entity;
+    xmlParserInputPtr input = NULL;
 
+    q = CUR_PTR;
     if (CUR == '&') {
         NEXT;
         name = xmlParseName(ctxt);
@@ -2147,40 +2211,18 @@
 	} else {
 	    if (CUR == ';') {
 	        NEXT;
-		entity = xmlGetDocEntity(ctxt->doc, name);
-		if (entity == NULL) {
-		    /* TODO !!! Create a reference ! */
-		    xmlParserWarning(ctxt,
-		         "xmlParseEntityRef: &%s; not found\n", name);
-		}
 		/*
-		 * If we can get the content, push the entity content
-		 * as the next input stream.
+		 * We parsed the entity reference correctly, call SAX
+		 * interface for the proper behaviour:
+		 *   - get a new input stream
+		 *   - or keep the reference inline
 		 */
+		if (ctxt->sax)
+		    input = ctxt->sax->resolveEntity(ctxt, NULL, name);
+		if (input != NULL)
+		    xmlPushInput(ctxt, input);
 		else {
-		    switch (entity->type) {
-		        case XML_INTERNAL_PARAMETER_ENTITY:
-			case XML_EXTERNAL_PARAMETER_ENTITY:
-			    xmlParserError(ctxt,
-		"internal: xmlGetDtdEntity returned a general entity\n");
-		            break;
-			case XML_INTERNAL_GENERAL_ENTITY:
-			    if (inLine)
-			        ret = entity->content;
-			    else
-				xmlHandleEntity(ctxt, entity);
-			    break;
-			case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
-			case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
-			    xmlParserWarning(ctxt,
-	    "xmlParseEntityRef: external entity &%s; not supported\n",
-	                                     name);
-	                    break;
-			default:
-			    xmlParserError(ctxt, 
-		    "internal: xmlParseEntityRef: unknown entity type %d\n",
-			                   entity->type);
-		    }
+		    ret = xmlStrndup(q, CUR_PTR - q);
 		}
 	    } else {
 		char cst[2] = { '&', 0 };
@@ -2198,18 +2240,18 @@
 /**
  * xmlParseReference:
  * @ctxt:  an XML parser context
- * @inLine:  handle it as inline or pass it to SAX as chars ?
  * 
  * parse Reference declarations
  *
  * [67] Reference ::= EntityRef | CharRef
- * return values: the entity content or NULL is handled directly
+ * return values: the entity string or NULL if handled directly by pushing
+ *      the entity value as the input.
  */
-CHAR *xmlParseReference(xmlParserCtxtPtr ctxt, int inLine) {
+CHAR *xmlParseReference(xmlParserCtxtPtr ctxt) {
     if ((CUR == '&') && (NXT(1) == '#')) {
-        return(xmlParseCharRef(ctxt, inLine));
+        return(xmlParseCharRef(ctxt));
     } else if (CUR == '&') {
-        return(xmlParseEntityRef(ctxt, inLine));
+        return(xmlParseEntityRef(ctxt));
     }
     return(NULL);
 }
@@ -2217,17 +2259,17 @@
 /**
  * xmlParsePEReference:
  * @ctxt:  an XML parser context
- * @inLine:  handle it as inline or pass it to SAX as chars ?
  *
  * parse PEReference declarations
  *
  * [69] PEReference ::= '%' Name ';'
- * return values: the entity content or NULL if handled differently.
+ * return values: the entity content or NULL if handled directly.
  */
-CHAR *xmlParsePEReference(xmlParserCtxtPtr ctxt, int inLine) {
+CHAR *xmlParsePEReference(xmlParserCtxtPtr ctxt) {
     CHAR *ret = NULL;
     CHAR *name;
     xmlEntityPtr entity;
+    xmlParserInputPtr input;
 
     if (CUR == '%') {
         NEXT;
@@ -2241,37 +2283,12 @@
 		if (entity == NULL) {
 		    xmlParserWarning(ctxt,
 		         "xmlParsePEReference: %%%s; not found\n");
-		}
-		/*
-		 * If we can get the content, push the entity content
-		 * as the next input stream.
-		 */
-		else {
-		    switch (entity->type) {
-		        case XML_INTERNAL_PARAMETER_ENTITY:
-			    if (inLine)
-			        ret = entity->content;
-			    else
-				xmlNewEntityInputStream(ctxt, entity);
-			    break;
-			case XML_EXTERNAL_PARAMETER_ENTITY:
-			    xmlParserWarning(ctxt,
-	    "xmlParsePEReference: external entity %%%s; not supported\n");
-	                    break;
-			case XML_INTERNAL_GENERAL_ENTITY:
-			case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
-			case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
-			    xmlParserError(ctxt,
-		"internal: xmlGetDtdEntity returned a general entity\n");
-		            break;
-			default:
-			    xmlParserError(ctxt, 
-		    "internal: xmlParsePEReference: unknown entity type %d\n",
-			                   entity->type);
-		    }
+		} else {
+		    input = xmlNewEntityInputStream(ctxt, entity);
+		    xmlPushInput(ctxt, input);
 		}
 	    } else {
-		char cst[2] = { '&', 0 };
+		char cst[2] = { '%', 0 };
 
 		xmlParserError(ctxt, "xmlParsePEReference: expecting ';'\n");
 		ret = xmlStrndup(cst, 1);
@@ -2339,7 +2356,7 @@
 
 	    SKIP_BLANKS;
 	    xmlParseMarkupDecl(ctxt);
-	    xmlParsePEReference(ctxt, 0);
+	    xmlParsePEReference(ctxt);
 
 	    if (CUR_PTR == check) {
 		xmlParserError(ctxt, 
@@ -2387,15 +2404,16 @@
  * definition.
  */
 
-void xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlNodePtr node) {
-    CHAR *name, *value = NULL;
+xmlAttrPtr xmlParseAttribute(xmlParserCtxtPtr ctxt, xmlNodePtr node) {
+    CHAR *name;
     CHAR *ns;
-    xmlNodePtr val = NULL;
+    CHAR *value = NULL;
+    xmlAttrPtr ret;
 
     name = xmlNamespaceParseQName(ctxt, &ns);
     if (name == NULL) {
 	xmlParserError(ctxt, "error parsing attribute name\n");
-        return;
+        return(NULL);
     }
 
     /*
@@ -2423,31 +2441,30 @@
 	    free(name);
 	if (value != NULL)
 	    free(value);
-	return;
+	return(NULL);
     }
     if ((ns != NULL) && (ns[0] == 'x') && (ns[1] == 'm') && (ns[2] == 'l') &&
         (ns[3] == 'n') && (ns[4] == 's') && (ns[5] == 0)) {
 	/* a standard namespace definition */
 	xmlNewNs(node, value, name);
+	free(ns);
 	if (name != NULL) 
 	    free(name);
 	if (value != NULL)
 	    free(value);
-	return;
+	return(NULL);
     }
 
-    /*
-     * Handle the attribute, this is done by the the SAX back end. The
-     * DOM default handling is to build the attribute content tree and
-     * link it to the element.
-     */
-    if (name != NULL) {
-	if (ctxt->sax)
-	    ctxt->sax->attribute(ctxt, name, value);
-        free(name);
-    }
+    ret = xmlNewProp(ctxt->node, name, NULL);
+    if (ret != NULL)
+        ret->val = xmlStringGetNodeList(ctxt->doc, value);
+
+    if (ns != NULL)
+      free(ns);
     if (value != NULL)
-      free(value);
+	free(value);
+    free(name);
+    return(ret);
 }
 
 /**
@@ -2474,11 +2491,13 @@
     CHAR *namespace, *name;
     xmlNsPtr ns = NULL;
     xmlNodePtr ret = NULL;
+    xmlNodePtr parent = ctxt->node;
 
     if (CUR != '<') return(NULL);
     NEXT;
 
     name = xmlNamespaceParseQName(ctxt, &namespace);
+    if (name == NULL) return(NULL);
 
     /*
      * Note : the namespace resolution is deferred until the end of the
@@ -2486,6 +2505,17 @@
      *        an attribute at this level.
      */
     ret = xmlNewDocNode(ctxt->doc, ns, name, NULL);
+    if (ret == NULL) {
+	if (namespace != NULL)
+	    free(namespace);
+	free(name);
+        return(NULL);
+    }
+
+    /*
+     * We are parsing a new node.
+     */
+    nodePush(ctxt, ret);
 
     /*
      * Now parse the attributes, it ends up with the ending
@@ -2513,21 +2543,25 @@
      */
     ns = xmlSearchNs(ctxt->doc, ret, namespace);
     if (ns == NULL) /* ret still doesn't have a parent yet ! */
-	ns = xmlSearchNs(ctxt->doc, ctxt->node, namespace);
+	ns = xmlSearchNs(ctxt->doc, parent, namespace);
     xmlSetNs(ret, ns);
     if (namespace != NULL)
 	free(namespace);
 
     /*
-     * We are parsing a new node.
-     */
-    nodePush(ctxt, ret);
-
-    /*
      * SAX: Start of Element !
      */
     if (ctxt->sax != NULL)
         ctxt->sax->startElement(ctxt, name);
+    free(name);
+
+    /*
+     * Link the child element
+     */
+    if (ctxt->nodeNr < 2) return(ret);
+    parent = ctxt->nodeTab[ctxt->nodeNr - 2];
+    if (parent != NULL)
+	xmlAddChild(parent, ctxt->node);
 
     return(ret);
 }
@@ -2688,10 +2722,27 @@
 	    ret = xmlParseElement(ctxt);
 	}
 	/*
-	 * Fifth case : a reference.
+	 * Fifth case : a reference. If if has not been resolved,
+	 *    parsing returns it's Name, create the node 
 	 */
 	else if (CUR == '&') {
-	    xmlParseReference(ctxt, 0);
+	    CHAR *val = xmlParseReference(ctxt);
+	    if (val != NULL) {
+	        if (val[0] != '&') {
+		    /*
+		     * inline predefined entity.
+		     */
+                    if (ctxt->sax != NULL)
+			ctxt->sax->characters(ctxt, val, 0, xmlStrlen(val));
+		} else {
+		    /*
+		     * user defined entity, create a node.
+		     */
+		    ret = xmlNewReference(ctxt->doc, val);
+		    xmlAddChild(ctxt->node, ret);
+		}
+		free(val);
+	    }
 	}
 	/*
 	 * Last case, text. Note that References are handled directly.
@@ -3266,6 +3317,11 @@
 
     xmlParseDocument(ctxt);
     ret = ctxt->doc;
+    free(ctxt->nodeTab);
+    free(ctxt->inputTab);
+    if (input->filename != NULL)
+	free((char *)input->filename);
+    free(input);
     free(ctxt);
     
     return(ret);
@@ -3381,6 +3437,11 @@
 
     ret = ctxt->doc;
     free(buffer);
+    free(ctxt->nodeTab);
+    free(ctxt->inputTab);
+    if (inputStream->filename != NULL)
+	free((char *)inputStream->filename);
+    free(inputStream);
     free(ctxt);
     
     return(ret);
@@ -3415,6 +3476,8 @@
     input = (xmlParserInputPtr) malloc(sizeof(xmlParserInput));
     if (input == NULL) {
         perror("malloc");
+        free(ctxt->nodeTab);
+	free(ctxt->inputTab);
 	free(ctxt);
 	return(NULL);
     }
@@ -3434,6 +3497,11 @@
     xmlParseDocument(ctxt);
 
     ret = ctxt->doc;
+    free(ctxt->nodeTab);
+    free(ctxt->inputTab);
+    if (input->filename != NULL)
+	free((char *)input->filename);
+    free(input);
     free(ctxt);
     
     return(ret);
diff --git a/parser.h b/parser.h
index d0ca958..51ba467 100644
--- a/parser.h
+++ b/parser.h
@@ -128,6 +128,8 @@
 extern xmlSAXLocator xmlDefaultSAXLocator;
 extern xmlSAXHandler xmlDefaultSAXHandler;
 
+#include "entities.h"
+
 /*
  * Interfaces
  */
diff --git a/result/ent1 b/result/ent1
index 14bf428..04e280e 100644
--- a/result/ent1
+++ b/result/ent1
@@ -3,5 +3,4 @@
 <!ENTITY xml "Extensible Markup Language">
 ]>
 <EXAMPLE>
-    Extensible Markup Language
-</EXAMPLE>
+    &xml;</EXAMPLE>
diff --git a/result/ent2 b/result/ent2
index 754f257..670ce74 100644
--- a/result/ent2
+++ b/result/ent2
@@ -5,6 +5,5 @@
 <!ENTITY image SYSTEM "img.gif" NDATA GIF>
 ]>
 <EXAMPLE>
-  
-  This text is about XML, the Extensible Markup Language and this is an embedded 
-</EXAMPLE>
+  &title;
+  This text is about XML, the &xml; and this is an embedded &image;</EXAMPLE>
diff --git a/result/ent3 b/result/ent3
index b1c0b14..7fb4c7b 100644
--- a/result/ent3
+++ b/result/ent3
@@ -2,6 +2,6 @@
 <!DOCTYPE EXAMPLE SYSTEM "example.dtd" [
 <!ENTITY xml "Extensible Markup Language">
 ]>
-<EXAMPLE prop1="a&amp;b" prop2="Extensible Markup Language">
+<EXAMPLE prop1="a&amp;b" prop2="&xml;">
   Test of entities in attributes.
 </EXAMPLE>
diff --git a/result/ent4 b/result/ent4
new file mode 100644
index 0000000..a92194c
--- /dev/null
+++ b/result/ent4
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE EXAMPLE SYSTEM "example.dtd" [
+<!ENTITY xml "Extensible Markup Language">
+]>
+<EXAMPLE>
+  Test of &amp;amp; behaviour a&amp;b .
+</EXAMPLE>
diff --git a/result/p3p b/result/p3p
index 75eec90..5ebda7a 100644
--- a/result/p3p
+++ b/result/p3p
@@ -13,7 +13,7 @@
       </STATEMENT>
     </USES>
     <USES>
-      <STATEMENT action="read&amp;write" purp="0" recpnt="0" id="1">
+      <STATEMENT action="read" purp="0" recpnt="0" id="1">
         <REF name="User.Shipping."/>
       </STATEMENT>
     </USES>
diff --git a/test/ent4 b/test/ent4
new file mode 100644
index 0000000..e668b40
--- /dev/null
+++ b/test/ent4
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<!DOCTYPE EXAMPLE SYSTEM "example.dtd" [
+<!ENTITY xml "Extensible Markup Language">
+]>
+<EXAMPLE >
+  Test of &amp;amp; behaviour a&amp;b .
+</EXAMPLE>
+
diff --git a/tree.c b/tree.c
index 0aeff3c..202f0b8 100644
--- a/tree.c
+++ b/tree.c
@@ -346,6 +346,125 @@
 }
 
 /**
+ * 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.
+ * return values: a pointer to the first child
+ */
+xmlNodePtr xmlStringGetNodeList(xmlDocPtr doc, const CHAR *value) {
+    xmlNodePtr ret = NULL, last = NULL;
+    xmlNodePtr node;
+    CHAR *val;
+    const CHAR *cur = value;
+    const CHAR *q;
+
+    if (value == NULL) return(NULL);
+
+    q = cur;
+    while (*cur != 0) {
+	if (*cur == '&') {
+            if (cur != q) {
+	        node = xmlNewTextLen(q, cur - q);
+		if (node == NULL) return(ret);
+		if (last == NULL)
+		    last = ret = node;
+		else {
+		    last->next = node;
+		    last = node;
+		}
+	    }
+	    cur++;
+	    q = cur;
+	    while ((*cur != 0) && (*cur != ';')) cur++;
+	    if (*cur == 0) {
+	        fprintf(stderr,
+		        "xmlStringGetNodeList: unterminated entity %30s\n", q);
+	        return(ret);
+	    }
+            if (cur != q) {
+		val = xmlStrndup(q, cur - q);
+		node = xmlNewReference(doc, val);
+		if (node == NULL) return(ret);
+		if (last == NULL)
+		    last = ret = node;
+		else {
+		    last->next = node;
+		    last = node;
+		}
+		free(val);
+	    }
+	    cur++;
+	    q = cur;
+	} else 
+	    cur++;
+    }
+    if (cur != q) {
+	node = xmlNewTextLen(q, cur - q);
+	if (node == NULL) return(ret);
+	if (last == NULL)
+	    last = ret = node;
+	else {
+	    last->next = node;
+	    last = node;
+	}
+    }
+    return(ret);
+}
+
+/**
+ * xmlNodeListGetString:
+ * @doc:  the document
+ * @list:  a Node list
+ * @inLine:  should we replace entity contents or show their external form
+ *
+ * Returns the string equivalent to the text contained in the Node list
+ * made of TEXTs and ENTITY_REFs
+ * return values: a pointer to the string copy, the calller must free it.
+ */
+CHAR *xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine) {
+    xmlNodePtr node = list;
+    CHAR *ret = NULL;
+    xmlEntityPtr ent;
+
+    if (list == NULL) return(NULL);
+
+    while (node != NULL) {
+        if (node->type == XML_TEXT_NODE) {
+	    if (inLine)
+		ret = xmlStrcat(ret, node->content);
+	    else
+		ret = xmlStrcat(ret, xmlEncodeEntities(doc, node->content));
+	} else if (node->type == XML_ENTITY_REF_NODE) {
+	    if (inLine) {
+		ent = xmlGetDocEntity(doc, node->name);
+		if (ent != NULL)
+		    ret = xmlStrcat(ret, ent->content);
+		else
+		    ret = xmlStrcat(ret, node->content);
+            } else {
+	        CHAR 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 {
+	    fprintf(stderr, "xmlGetNodeListString : invalide node type %d\n",
+	            node->type);
+	}
+#endif
+	node = node->next;
+    }
+    return(ret);
+}
+
+/**
  * xmlNewProp:
  * @node:  the holding node
  * @name:  the name of the attribute
@@ -375,9 +494,9 @@
     cur->node = node; 
     cur->name = xmlStrdup(name);
     if (value != NULL)
-	cur->value = xmlStrdup(value);
+	cur->val = xmlStringGetNodeList(node->doc, value);
     else 
-	cur->value = NULL;
+	cur->val = NULL;
 #ifndef WITHOUT_CORBA
     cur->_private = NULL;
     cur->vepv = NULL;
@@ -401,6 +520,48 @@
 }
 
 /**
+ * xmlNewDocProp:
+ * @doc:  the document
+ * @name:  the name of the attribute
+ * @value:  the value of the attribute
+ *
+ * Create a new property carried by a document.
+ * return values: a pointer to the attribute
+ */
+xmlAttrPtr xmlNewDocProp(xmlDocPtr doc, const CHAR *name, const CHAR *value) {
+    xmlAttrPtr cur;
+
+    if (name == NULL) {
+        fprintf(stderr, "xmlNewProp : name == NULL\n");
+	return(NULL);
+    }
+
+    /*
+     * Allocate a new property and fill the fields.
+     */
+    cur = (xmlAttrPtr) malloc(sizeof(xmlAttr));
+    if (cur == NULL) {
+        fprintf(stderr, "xmlNewProp : malloc failed\n");
+	return(NULL);
+    }
+
+    cur->type = XML_ATTRIBUTE_NODE;
+    cur->node = NULL; 
+    cur->name = xmlStrdup(name);
+    if (value != NULL)
+	cur->val = xmlStringGetNodeList(doc, value);
+    else 
+	cur->val = NULL;
+#ifndef WITHOUT_CORBA
+    cur->_private = NULL;
+    cur->vepv = NULL;
+#endif
+
+    cur->next = NULL;
+    return(cur);
+}
+
+/**
  * xmlFreePropList:
  * @cur:  the first property in the list
  *
@@ -431,7 +592,7 @@
 	return;
     }
     if (cur->name != NULL) free((char *) cur->name);
-    if (cur->value != NULL) free((char *) cur->value);
+    if (cur->val != NULL) xmlFreeNodeList(cur->val);
     memset(cur, -1, sizeof(xmlAttr));
     free(cur);
 }
@@ -443,9 +604,11 @@
  * @content:  the text content if any
  *
  * Creation of a new node element. @ns and @content are optionnal (NULL).
+ * If content is non NULL, a child list containing the TEXTs and
+ * ENTITY_REFs node will be created.
  * return values: a pointer to the new node object.
  */
-xmlNodePtr xmlNewNode(xmlNsPtr ns, const CHAR *name, CHAR *content) {
+xmlNodePtr xmlNewNode(xmlNsPtr ns, const CHAR *name) {
     xmlNodePtr cur;
 
     if (name == NULL) {
@@ -473,14 +636,11 @@
     cur->name = xmlStrdup(name);
     cur->ns = ns;
     cur->nsDef = NULL;
+    cur->content = NULL;
 #ifndef WITHOUT_CORBA
     cur->_private = NULL;
     cur->vepv = NULL;
 #endif
-    if (content != NULL)
-	cur->content = xmlStrdup(content);
-    else 
-	cur->content = NULL;
     return(cur);
 }
 
@@ -499,8 +659,12 @@
                          const CHAR *name, CHAR *content) {
     xmlNodePtr cur;
 
-    cur = xmlNewNode(ns, name, content);
-    if (cur != NULL) cur->doc = doc;
+    cur = xmlNewNode(ns, name);
+    if (cur != NULL) {
+        cur->doc = doc;
+	if (content != NULL)
+	    cur->childs = xmlStringGetNodeList(doc, content);
+    }
     return(cur);
 }
 
@@ -543,6 +707,55 @@
 }
 
 /**
+ * xmlNewReference:
+ * @doc: the document
+ * @name:  the reference name, or the reference string with & and ;
+ *
+ * Creation of a new reference node.
+ * return values: a pointer to the new node object.
+ */
+xmlNodePtr xmlNewReference(xmlDocPtr doc, const CHAR *name) {
+    xmlNodePtr cur;
+    xmlEntityPtr ent;
+
+    /*
+     * Allocate a new node and fill the fields.
+     */
+    cur = (xmlNodePtr) malloc(sizeof(xmlNode));
+    if (cur == NULL) {
+        fprintf(stderr, "xmlNewText : malloc failed\n");
+	return(NULL);
+    }
+
+    cur->type = XML_ENTITY_REF_NODE;
+    cur->doc = NULL;
+    cur->parent = NULL; 
+    cur->next = NULL; 
+    cur->prev = NULL; 
+    cur->childs = NULL; 
+    cur->properties = NULL; 
+    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);
+    cur->ns = NULL;
+    cur->nsDef = NULL;
+
+    ent = xmlGetDocEntity(doc, cur->name);
+    if (ent != NULL)
+	cur->content = ent->content;
+    else
+        cur->content = NULL;
+    return(cur);
+}
+
+/**
  * xmlNewDocText:
  * @doc: the document
  * @content:  the text content
@@ -559,7 +772,7 @@
 }
 
 /**
- * xmlNewText:
+ * xmlNewTextLen:
  * @content:  the text content
  * @len:  the text len.
  *
@@ -676,7 +889,8 @@
  *
  * 
  * Creation of a new child element, added at the end of @parent childs list.
- * @ns and @content parameters are optionnal (NULL).
+ * @ns and @content parameters are optionnal (NULL). If content is non NULL,
+ * a child list containing the TEXTs and ENTITY_REFs node will be created.
  * return values: a pointer to the new node object.
  */
 xmlNodePtr xmlNewChild(xmlNodePtr parent, xmlNsPtr ns,
@@ -697,18 +911,15 @@
      * Allocate a new node
      */
     if (ns == NULL)
-	cur = xmlNewNode(parent->ns, name, content);
+	cur = xmlNewDocNode(parent->doc, parent->ns, name, content);
     else
-	cur = xmlNewNode(ns, name, content);
+	cur = xmlNewDocNode(parent->doc, ns, name, content);
     if (cur == NULL) return(NULL);
 
     /*
      * add the new element at the end of the childs list.
      */
-    if (content == NULL)
-	cur->type = XML_ELEMENT_NODE;
-    else
-	cur->type = XML_TEXT_NODE;
+    cur->type = XML_ELEMENT_NODE;
     cur->parent = parent;
     cur->doc = parent->doc;
     if (parent->childs == NULL) {
@@ -754,6 +965,23 @@
      */
     cur->parent = parent;
     cur->doc = parent->doc; /* the parent may not be linked to a doc ! */
+    /*
+     * Handle the case where parent->content != NULL, in that case it will
+     * create a intermediate TEXT node.
+     */
+    if (parent->content != NULL) {
+        xmlNodePtr text;
+	
+	text = xmlNewDocText(parent->doc, parent->content);
+	if (text != NULL) {
+	    text->next = parent->childs;
+	    if (text->next != NULL)
+		text->next->prev = text;
+	    parent->childs = text;
+	    free(parent->content);
+	    parent->content = NULL;
+	}
+    }
     if (parent->childs == NULL) {
         parent->childs = cur;
     } else {
@@ -824,9 +1052,14 @@
         fprintf(stderr, "xmlFreeNode : node == NULL\n");
 	return;
     }
-    if (cur->properties != NULL) xmlFreePropList(cur->properties);
+    cur->doc = NULL;
+    cur->parent = NULL;
+    cur->next = NULL;
+    cur->prev = NULL;
     if (cur->childs != NULL) xmlFreeNodeList(cur->childs);
-    if (cur->content != NULL) free(cur->content);
+    if (cur->properties != NULL) xmlFreePropList(cur->properties);
+    if (cur->type != XML_ENTITY_REF_NODE)
+	if (cur->content != NULL) free(cur->content);
     if (cur->name != NULL) free((char *) cur->name);
     if (cur->nsDef != NULL) xmlFreeNsList(cur->nsDef);
     memset(cur, -1, sizeof(xmlNode));
@@ -989,20 +1222,22 @@
  * @name:  the attribute name
  *
  * Search and get the value of an attribute associated to a node
+ * This does the entity substitution.
  * return values: the attribute value or NULL if not found.
  */
 const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name) {
     xmlAttrPtr prop = node->properties;
 
     while (prop != NULL) {
-        if (!xmlStrcmp(prop->name, name)) return(prop->value);
+        if (!xmlStrcmp(prop->name, name)) 
+	    return(xmlNodeListGetString(node->doc, prop->val, 1));
 	prop = prop->next;
     }
     return(NULL);
 }
 
 /**
- * xmlGetProp:
+ * xmlSetProp:
  * @node:  the node
  * @name:  the attribute name
  * @value:  the attribute value
@@ -1015,11 +1250,11 @@
 
     while (prop != NULL) {
         if (!xmlStrcmp(prop->name, name)) {
-	    if (prop->value != NULL) 
-	        free((char *) prop->value);
-	    prop->value = NULL;
+	    if (prop->val != NULL) 
+	        xmlFreeNode(prop->val);
+	    prop->val = NULL;
 	    if (value != NULL)
-		prop->value = xmlStrdup(value);
+		prop->val = xmlStringGetNodeList(node->doc, value);
 	    return(prop);
 	}
 	prop = prop->next;
@@ -1267,16 +1502,20 @@
  * Dump an XML attribute
  */
 static void xmlAttrDump(xmlDocPtr doc, xmlAttrPtr cur) {
+    CHAR *value;
+
     if (cur == NULL) {
         fprintf(stderr, "xmlAttrDump : property == NULL\n");
 	return;
     }
     xmlBufferWriteChar(" ");
     xmlBufferWriteCHAR(cur->name);
-    if (cur->value) {
+    value = xmlNodeListGetString(doc, cur->val, 0);
+    if (value) {
 	xmlBufferWriteChar("=\"");
-	xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->value));
+	xmlBufferWriteCHAR(value);
 	xmlBufferWriteChar("\"");
+	free(value);
     }
 }
 
@@ -1309,18 +1548,30 @@
  * Dump an XML node list, recursive behaviour,children are printed too.
  */
 static void xmlNodeListDump(xmlDocPtr doc, xmlNodePtr cur, int level) {
+    int needIndent = 0, i;
+
     if (cur == NULL) {
         fprintf(stderr, "xmlNodeListDump : node == NULL\n");
 	return;
     }
     while (cur != NULL) {
+        if ((cur->type != XML_TEXT_NODE) &&
+	    (cur->type != XML_ENTITY_REF_NODE)) {
+	    if (!needIndent) {
+	        needIndent = 1;
+		xmlBufferWriteChar("\n");
+	    }
+	}
         xmlNodeDump(doc, cur, level);
 	cur = cur->next;
     }
+    if ((xmlIndentTreeOutput) && (needIndent))
+	for (i = 1;i < level;i++)
+	    xmlBufferWriteChar("  ");
 }
 
 /**
- * xmlNodeListDump:
+ * xmlNodeDump:
  * @doc:  the document
  * @cur:  the current node
  * @level: the imbrication level for indenting
@@ -1347,6 +1598,12 @@
 	}
 	return;
     }
+    if (cur->type == XML_ENTITY_REF_NODE) {
+        xmlBufferWriteChar("&");
+	xmlBufferWriteCHAR(cur->name);
+        xmlBufferWriteChar(";");
+	return;
+    }
     if (xmlIndentTreeOutput)
 	for (i = 0;i < level;i++)
 	    xmlBufferWriteChar("  ");
@@ -1371,11 +1628,7 @@
     if (cur->content != NULL)
 	xmlBufferWriteCHAR(xmlEncodeEntities(doc, cur->content));
     if (cur->childs != NULL) {
-	xmlBufferWriteChar("\n");
 	xmlNodeListDump(doc, cur->childs, level + 1);
-	if (xmlIndentTreeOutput)
-	    for (i = 0;i < level;i++)
-		xmlBufferWriteChar("  ");
     }
     xmlBufferWriteChar("</");
     if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
@@ -1531,7 +1784,7 @@
     gzFile zoutput = NULL;
     char mode[15];
 #endif
-    FILE *output;
+    FILE *output = NULL;
     int ret;
 
 #ifdef HAVE_ZLIB_H
@@ -1584,7 +1837,7 @@
     doc = xmlNewDoc("1.0");
     ns1 = xmlNewNs(doc, "http://www.ietf.org/standards/dav/", "D");
     ns2 = xmlNewNs(doc, "http://www.w3.com/standards/z39.50/", "Z");
-    doc->root = xmlNewNode(ns1, "multistatus", NULL);
+    doc->root = xmlNewDocNode(doc, ns1, "multistatus", NULL);
     tree = xmlNewChild(doc->root, NULL, "response", NULL);
     subtree = xmlNewChild(tree, NULL, "prop", NULL);
     xmlNewChild(subtree, ns2, "Authors", NULL);
diff --git a/tree.h b/tree.h
index 91677a6..2ebe2cd 100644
--- a/tree.h
+++ b/tree.h
@@ -16,7 +16,30 @@
 #endif
 
 /*
- * Type definitions
+ * 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/
+ */
+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
+} xmlElementType;
+
+/*
+ * Currently we use only 8bit chars internal representation, but
+ * the parser is not tied to that, just define UNICODE to switch to
+ * a 16 bits representation.
  */
 #ifdef UNICODE
 typedef unsigned short CHAR;
@@ -84,37 +107,22 @@
     void           *_private;	/* for Corba, must be first ! */
     void           *vepv;	/* for Corba, must be next ! */
 #endif
-    int             type;       /* XML_ATTRIBUTE_NODE, must be third ! */
+    xmlElementType  type;       /* XML_ATTRIBUTE_NODE, must be third ! */
     struct xmlNode *node;	/* attr->node link */
     struct xmlAttr *next;	/* parent->childs link */
     const CHAR     *name;       /* the name of the property */
-    const CHAR     *value;      /* the value of the property */
+    struct xmlNode *val;        /* the value of the property */
 } xmlAttr, *xmlAttrPtr;
 
 /*
  * A node in an XML tree.
- * NOTE: This is synchronized with DOM Level1 values
- *       See http://www.w3.org/TR/REC-DOM-Level-1/
  */
-#define XML_ELEMENT_NODE	1
-#define XML_ATTRIBUTE_NODE	2
-#define XML_TEXT_NODE		3
-#define XML_CDATA_SECTION_NODE	4
-#define XML_ENTITY_REF_NODE	5
-#define XML_ENTITY_NODE		6
-#define XML_PI_NODE		7
-#define XML_COMMENT_NODE	8
-#define XML_DOCUMENT_NODE	9
-#define XML_DOCUMENT_TYPE_NODE	10
-#define XML_DOCUMENT_FRAG_NODE	11
-#define XML_NOTATION_NODE	12
-
 typedef struct xmlNode {
 #ifndef XML_WITHOUT_CORBA
     void           *_private;	/* for Corba, must be first ! */
     void           *vepv;	/* for Corba, must be next ! */
 #endif
-    int             type;	/* type number in the DTD, must be third ! */
+    xmlElementType  type;	/* type number in the DTD, must be third ! */
     struct xmlDoc  *doc;	/* the containing document */
     struct xmlNode *parent;	/* child->parent link */
     struct xmlNode *next;	/* next sibling link  */
@@ -135,7 +143,7 @@
     void           *_private;	/* for Corba, must be first ! */
     void           *vepv;	/* for Corba, must be next ! */
 #endif
-    int             type;       /* XML_DOCUMENT_NODE, must be second ! */
+    xmlElementType  type;       /* XML_DOCUMENT_NODE, must be second ! */
     char           *name;	/* name/filename/URI of the document */
     const CHAR     *version;	/* the XML version string */
     const CHAR     *encoding;   /* encoding, if any */
@@ -165,22 +173,27 @@
 extern void xmlFreeNs(xmlNsPtr cur);
 extern xmlDocPtr xmlNewDoc(const CHAR *version);
 extern void xmlFreeDoc(xmlDocPtr cur);
+extern xmlAttrPtr xmlNewDocProp(xmlDocPtr doc, const CHAR *name,
+                                const CHAR *value);
 extern xmlAttrPtr xmlNewProp(xmlNodePtr node, const CHAR *name,
                              const CHAR *value);
 extern xmlAttrPtr xmlSetProp(xmlNodePtr node, const CHAR *name,
                              const CHAR *value);
 extern const CHAR *xmlGetProp(xmlNodePtr node, const CHAR *name);
+extern xmlNodePtr xmlStringGetNodeList(xmlDocPtr doc, const CHAR *value);
+extern CHAR *xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine);
 extern void xmlFreePropList(xmlAttrPtr cur);
 extern void xmlFreeProp(xmlAttrPtr cur);
 extern xmlNodePtr xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns,
                              const CHAR *name, CHAR *content);
-extern xmlNodePtr xmlNewNode(xmlNsPtr ns, const CHAR *name, CHAR *content);
+extern xmlNodePtr xmlNewNode(xmlNsPtr ns, const CHAR *name);
 extern xmlNodePtr xmlNewDocText(xmlDocPtr doc, const CHAR *content);
 extern xmlNodePtr xmlNewText(const CHAR *content);
 extern xmlNodePtr xmlNewDocTextLen(xmlDocPtr doc, const CHAR *content, int len);
 extern xmlNodePtr xmlNewTextLen(const CHAR *content, int len);
 extern xmlNodePtr xmlNewDocComment(xmlDocPtr doc, CHAR *content);
 extern xmlNodePtr xmlNewComment(CHAR *content);
+extern xmlNodePtr xmlNewReference(xmlDocPtr doc, const CHAR *name);
 extern xmlNodePtr xmlAddChild(xmlNodePtr parent, xmlNodePtr cur);
 extern xmlNodePtr xmlGetLastChild(xmlNodePtr node);
 extern int xmlNodeIsText(xmlNodePtr node);