applied patch from Richard Jinks for the namespace axis + fixed a memory

* xpath.c: applied patch from Richard Jinks for the namespace
  axis + fixed a memory error.
* parser.c parserInternals.c: applied patches from Peter Jacobi
  removing ctxt->token for good.
* xmlschemas.c xmlschemastypes.c: fixed a few memory leaks
  popped out by the regression tests.
* Makefile.am: patch for threads makefile from Gary Pennington
Daniel
diff --git a/ChangeLog b/ChangeLog
index ae121b8..f5d21b2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,16 @@
+Mon Jul  1 23:23:41 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* xpath.c: applied patch from Richard Jinks for the namespace
+	  axis + fixed a memory error.
+	* parser.c parserInternals.c: applied patches from Peter Jacobi
+	  removing ctxt->token for good.
+	* xmlschemas.c xmlschemastypes.c: fixed a few memory leaks
+	  popped out by the regression tests.
+	* Makefile.am: patch for threads makefile from Gary Pennington
+
 Fri Jun 28 19:38:00 HKT 2002 William Brack <wbrack@mmm.com.hk>
 
-	* xpath.c enhanced behaviour of position() after usage of
+	* xpath.c: enhanced behaviour of position() after usage of
 	  expressions involving preceding-sibling (et al).
 
 Tue Jun 18 09:58:48 CEST 2002 Daniel Veillard <daniel@veillard.com>
diff --git a/Makefile.am b/Makefile.am
index 9643396..0d3162f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -13,7 +13,7 @@
 bin_SCRIPTS=xml2-config
 
 lib_LTLIBRARIES = libxml2.la
-libxml2_la_LIBADD = @Z_LIBS@ $(ICONV_LIBS) -lm
+libxml2_la_LIBADD = @THREAD_LIBS@ @Z_LIBS@ $(ICONV_LIBS) -lm
 
 libxml2_la_LDFLAGS = -version-info @LIBXML_VERSION_INFO@
 
diff --git a/hash.c b/hash.c
index f1bfb92..28bf014 100644
--- a/hash.c
+++ b/hash.c
@@ -42,13 +42,14 @@
     xmlChar *name2;
     xmlChar *name3;
     void *payload;
+    int valid;
 };
 
 /*
  * The entire hash table
  */
 struct _xmlHashTable {
-    struct _xmlHashEntry **table;
+    struct _xmlHashEntry *table;
     int size;
     int nbElems;
 };
@@ -101,9 +102,9 @@
     if (table) {
         table->size = size;
 	table->nbElems = 0;
-        table->table = xmlMalloc(size * sizeof(xmlHashEntryPtr));
+        table->table = xmlMalloc(size * sizeof(xmlHashEntry));
         if (table->table) {
-  	    memset(table->table, 0, size * sizeof(xmlHashEntryPtr));
+  	    memset(table->table, 0, size * sizeof(xmlHashEntry));
   	    return(table);
         }
         xmlFree(table);
@@ -125,7 +126,7 @@
     unsigned long key;
     int oldsize, i;
     xmlHashEntryPtr iter, next;
-    struct _xmlHashEntry **oldtable;
+    struct _xmlHashEntry *oldtable;
 #ifdef DEBUG_GROW
     unsigned long nbElem = 0;
 #endif
@@ -142,16 +143,31 @@
     if (oldtable == NULL)
         return(-1);
   
-    table->table = xmlMalloc(size * sizeof(xmlHashEntryPtr));
+    table->table = xmlMalloc(size * sizeof(xmlHashEntry));
     if (table->table == NULL) {
 	table->table = oldtable;
 	return(-1);
     }
-    memset(table->table, 0, size * sizeof(xmlHashEntryPtr));
+    memset(table->table, 0, size * sizeof(xmlHashEntry));
     table->size = size;
 
+    /*	If the two loops are merged, there would be situations where
+	a new entry needs to allocated and data copied into it from 
+	the main table. So instead, we run through the array twice, first
+	copying all the elements in the main array (where we can't get
+	conflicts) and then the rest, so we only free (and don't allocate)
+    */
     for (i = 0; i < oldsize; i++) {
-	iter = oldtable[i];
+	if (oldtable[i].valid == 0) 
+	    continue;
+	key = xmlHashComputeKey(table, oldtable[i].name, oldtable[i].name2,
+				oldtable[i].name3);
+	memcpy(&(table->table[key]), &(oldtable[i]), sizeof(xmlHashEntry));
+	table->table[key].next = NULL;
+    }
+
+    for (i = 0; i < oldsize; i++) {
+	iter = oldtable[i].next;
 	while (iter) {
 	    next = iter->next;
 
@@ -161,8 +177,14 @@
 
 	    key = xmlHashComputeKey(table, iter->name, iter->name2,
 		                    iter->name3);
-	    iter->next = table->table[key];
-	    table->table[key] = iter;
+	    if (table->table[key].valid == 0) {
+		memcpy(&(table->table[key]), iter, sizeof(xmlHashEntry));
+		table->table[key].next = NULL;
+		xmlFree(iter);
+	    } else {
+	    	iter->next = table->table[key].next;
+	    	table->table[key].next = iter;
+	    }
 
 #ifdef DEBUG_GROW
 	    nbElem++;
@@ -195,12 +217,16 @@
     int i;
     xmlHashEntryPtr iter;
     xmlHashEntryPtr next;
+    int inside_table = 0;
 
     if (table == NULL)
 	return;
     if (table->table) {
 	for(i = 0; i < table->size; i++) {
-	    iter = table->table[i];
+	    iter = &(table->table[i]);
+	    if (iter->valid == 0)
+		continue;
+	    inside_table = 1;
 	    while (iter) {
 		next = iter->next;
 		if (f)
@@ -212,10 +238,12 @@
 		if (iter->name3)
 		    xmlFree(iter->name3);
 		iter->payload = NULL;
-		xmlFree(iter);
+		if (!inside_table)
+		    xmlFree(iter);
+		inside_table = 0;
 		iter = next;
 	    }
-	    table->table[i] = NULL;
+	    inside_table = 0;
 	}
 	xmlFree(table->table);
     }
@@ -355,10 +383,10 @@
      * Check for duplicate and insertion location.
      */
     key = xmlHashComputeKey(table, name, name2, name3);
-    if (table->table[key] == NULL) {
+    if (table->table[key].valid == 0) {
 	insert = NULL;
     } else {
-	for (insert = table->table[key]; insert->next != NULL;
+	for (insert = &(table->table[key]); insert->next != NULL;
 	     insert = insert->next) {
 	    if ((xmlStrEqual(insert->name, name)) &&
 		(xmlStrEqual(insert->name2, name2)) &&
@@ -372,21 +400,25 @@
 	    return(-1);
     }
 
-    entry = xmlMalloc(sizeof(xmlHashEntry));
-    if (entry == NULL)
-	return(-1);
+    if (insert == NULL) {
+	entry = &(table->table[key]);
+    } else {
+	entry = xmlMalloc(sizeof(xmlHashEntry));
+	if (entry == NULL)
+	     return(-1);
+    }
+
     entry->name = xmlStrdup(name);
     entry->name2 = xmlStrdup(name2);
     entry->name3 = xmlStrdup(name3);
     entry->payload = userdata;
     entry->next = NULL;
+    entry->valid = 1;
 
 
-    if (insert == NULL) {
-	table->table[key] = entry;
-    } else {
+    if (insert != NULL) 
 	insert->next = entry;
-    }
+
     table->nbElems++;
 
     if (len > MAX_HASH_LEN)
@@ -425,10 +457,10 @@
      * Check for duplicate and insertion location.
      */
     key = xmlHashComputeKey(table, name, name2, name3);
-    if (table->table[key] == NULL) {
+    if (table->table[key].valid == 0) {
 	insert = NULL;
     } else {
-	for (insert = table->table[key]; insert->next != NULL;
+	for (insert = &(table->table[key]); insert->next != NULL;
 	     insert = insert->next) {
 	    if ((xmlStrEqual(insert->name, name)) &&
 		(xmlStrEqual(insert->name2, name2)) &&
@@ -449,20 +481,24 @@
 	}
     }
 
-    entry = xmlMalloc(sizeof(xmlHashEntry));
-    if (entry == NULL)
-	return(-1);
+    if (insert == NULL) {
+	entry =  &(table->table[key]);
+    } else {
+	entry = xmlMalloc(sizeof(xmlHashEntry));
+	if (entry == NULL)
+	     return(-1);
+    }
+
     entry->name = xmlStrdup(name);
     entry->name2 = xmlStrdup(name2);
     entry->name3 = xmlStrdup(name3);
     entry->payload = userdata;
     entry->next = NULL;
+    entry->valid = 1;
     table->nbElems++;
 
 
-    if (insert == NULL) {
-	table->table[key] = entry;
-    } else {
+    if (insert != NULL) {
 	insert->next = entry;
     }
     return(0);
@@ -490,7 +526,9 @@
     if (name == NULL)
 	return(NULL);
     key = xmlHashComputeKey(table, name, name2, name3);
-    for (entry = table->table[key]; entry != NULL; entry = entry->next) {
+    if (table->table[key].valid == 0)
+	return(NULL);
+    for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
 	if ((xmlStrEqual(entry->name, name)) &&
 	    (xmlStrEqual(entry->name2, name2)) &&
 	    (xmlStrEqual(entry->name3, name3)))
@@ -549,7 +587,9 @@
 
     if (table->table) {
 	for(i = 0; i < table->size; i++) {
-	    iter = table->table[i];
+	    if (table->table[i].valid == 0) 
+		continue;
+	    iter = &(table->table[i]);
 	    while (iter) {
 		next = iter->next;
 		if (f)
@@ -610,7 +650,9 @@
 
     if (table->table) {
 	for(i = 0; i < table->size; i++) {
-	    iter = table->table[i];
+	    if (table->table[i].valid == 0)
+		continue;
+	    iter = &(table->table[i]);
 	    while (iter) {
 		next = iter->next;
 		if (((name == NULL) || (xmlStrEqual(name, iter->name))) &&
@@ -649,7 +691,9 @@
     ret = xmlHashCreate(table->size);
     if (table->table) {
 	for(i = 0; i < table->size; i++) {
-	    iter = table->table[i];
+	    if (table->table[i].valid == 0)
+		continue;
+	    iter = &(table->table[i]);
 	    while (iter) {
 		next = iter->next;
 		xmlHashAddEntry3(ret, iter->name, iter->name2,
@@ -737,10 +781,10 @@
         return(-1);
 
     key = xmlHashComputeKey(table, name, name2, name3);
-    if (table->table[key] == NULL) {
+    if (table->table[key].valid == 0) {
         return(-1);
     } else {
-        for (entry = table->table[key]; entry != NULL; entry = entry->next) {
+        for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
             if (xmlStrEqual(entry->name, name) &&
                     xmlStrEqual(entry->name2, name2) &&
                     xmlStrEqual(entry->name3, name3)) {
@@ -753,11 +797,18 @@
                     xmlFree(entry->name2);
                 if(entry->name3)
                     xmlFree(entry->name3);
-                if(prev)
+                if(prev) {
                     prev->next = entry->next;
-                else
-                    table->table[key] = entry->next;
-                xmlFree(entry);
+		    xmlFree(entry);
+		} else {
+		    if (entry->next == NULL) {
+			entry->valid = 0;
+		    } else {
+			entry = entry->next;
+			memcpy(&(table->table[key]), entry, sizeof(xmlHashEntry));
+			xmlFree(entry);
+		    }
+		}
                 table->nbElems--;
                 return(0);
             }
diff --git a/parser.c b/parser.c
index 2d08673..2338100 100644
--- a/parser.c
+++ b/parser.c
@@ -268,8 +268,8 @@
  *   GROW, SHRINK  handling of input buffers
  */
 
-#define RAW (ctxt->token ? -1 : (*ctxt->input->cur))
-#define CUR (ctxt->token ? ctxt->token : (*ctxt->input->cur))
+#define RAW (*ctxt->input->cur)
+#define CUR (*ctxt->input->cur)
 #define NXT(val) ctxt->input->cur[(val)]
 #define CUR_PTR ctxt->input->cur
 
@@ -316,7 +316,7 @@
     if (*(ctxt->input->cur) == '\n') {					\
 	ctxt->input->line++; ctxt->input->col = 1;			\
     } else ctxt->input->col++;						\
-    ctxt->token = 0; ctxt->input->cur += l;				\
+    ctxt->input->cur += l;				\
     if (*ctxt->input->cur == '%') xmlParserHandlePEReference(ctxt);	\
   } while (0)
 
@@ -341,12 +341,6 @@
 xmlSkipBlankChars(xmlParserCtxtPtr ctxt) {
     int res = 0;
 
-    if (ctxt->token != 0) {
-	if (!IS_BLANK(ctxt->token))
-	    return(0);
-	ctxt->token = 0;
-	res++;
-    }
     /*
      * It's Okay to use CUR/NEXT here since all the blanks are on
      * the ASCII range.
@@ -465,11 +459,6 @@
     unsigned int val = 0;
     int count = 0;
 
-    if (ctxt->token != 0) {
-	val = ctxt->token;
-        ctxt->token = 0;
-        return(val);
-    }
     /*
      * Using RAW/CUR/NEXT is okay since we are working on ASCII range here
      */
@@ -754,9 +743,6 @@
     xmlEntityPtr entity = NULL;
     xmlParserInputPtr input;
 
-    if (ctxt->token != 0) {
-        return;
-    }	
     if (RAW != '%') return;
     switch(ctxt->instate) {
 	case XML_PARSER_CDATA_SECTION:
@@ -2363,32 +2349,10 @@
      * OK loop until we reach one of the ending char or a size limit.
      */
     c = CUR_CHAR(l);
-    while (((NXT(0) != limit) && /* checked */
-	   (c != '<')) || (ctxt->token != 0)) {
+    while ((NXT(0) != limit) && /* checked */
+	   (c != '<')) {
 	if (c == 0) break;
-	if (ctxt->token == '&') {
-	    if (ctxt->replaceEntities) {
-		if (len > buf_size - 10) {
-		    growBuffer(buf);
-		}
-		buf[len++] = '&';
-	    } else {
-		/*
-		 * The reparsing will be done in xmlStringGetNodeList()
-		 * called by the attribute() function in SAX.c
-		 */
-		static xmlChar buffer[6] = "&#38;";
-
-		if (len > buf_size - 10) {
-		    growBuffer(buf);
-		}
-		current = &buffer[0];
-		while (*current != 0) { /* non input consuming */
-		    buf[len++] = *current++;
-		}
-		ctxt->token = 0;
-	    }
-	} else if (c == '&') {
+	if (c == '&') {
 	    if (NXT(1) == '#') {
 		int val = xmlParseCharRef(ctxt);
 		if (val == '&') {
@@ -2707,7 +2671,7 @@
      * Accelerated common case where input don't need to be
      * modified before passing it to the handler.
      */
-    if ((ctxt->token == 0) && (!cdata)) {
+    if (!cdata) {
 	in = ctxt->input->cur;
 	do {
 get_more:
@@ -2799,9 +2763,9 @@
     SHRINK;
     GROW;
     cur = CUR_CHAR(l);
-    while (((cur != '<') || (ctxt->token == '<')) && /* checked */
-           ((cur != '&') || (ctxt->token == '&')) && 
-	    (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
+    while ((cur != '<') && /* checked */
+           (cur != '&') && 
+	   (IS_CHAR(cur))) /* test also done in xmlCurrentChar() */ {
 	if ((cur == ']') && (NXT(1) == ']') &&
 	    (NXT(2) == '>')) {
 	    if (cdata) break;
@@ -4960,7 +4924,6 @@
 	       (NXT(2) != '>'))) {
 	    const xmlChar *check = CUR_PTR;
 	    int cons = ctxt->input->consumed;
-	    int tok = ctxt->token;
 
 	    if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
 		xmlParseConditionalSections(ctxt);
@@ -4977,8 +4940,7 @@
 	    while ((RAW == 0) && (ctxt->inputNr > 1))
 		xmlPopInput(ctxt);
 
-	    if ((CUR_PTR == check) && (cons == ctxt->input->consumed) &&
-		(tok == ctxt->token)) {
+	    if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
 		ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
 		if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
 		    ctxt->sax->error(ctxt->userData,
@@ -5270,7 +5232,6 @@
 	   (RAW == '%') || IS_BLANK(CUR)) {
 	const xmlChar *check = CUR_PTR;
 	int cons = ctxt->input->consumed;
-	int tok = ctxt->token;
 
 	GROW;
         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
@@ -5288,8 +5249,7 @@
 	while ((RAW == 0) && (ctxt->inputNr > 1))
 	    xmlPopInput(ctxt);
 
-	if ((CUR_PTR == check) && (cons == ctxt->input->consumed) &&
-	    (tok == ctxt->token)) {
+	if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
 	    ctxt->errNo = XML_ERR_EXT_SUBSET_NOT_FINISHED;
 	    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
 		ctxt->sax->error(ctxt->userData,
@@ -6884,23 +6844,16 @@
 void
 xmlParseContent(xmlParserCtxtPtr ctxt) {
     GROW;
-    while (((RAW != 0) || (ctxt->token != 0)) &&
+    while ((RAW != 0) &&
 	   ((RAW != '<') || (NXT(1) != '/'))) {
 	const xmlChar *test = CUR_PTR;
 	int cons = ctxt->input->consumed;
-	int tok = ctxt->token;
 	const xmlChar *cur = ctxt->input->cur;
 
 	/*
-	 * Handle  possible processed charrefs.
-	 */
-	if (ctxt->token != 0) {
-	    xmlParseCharData(ctxt, 0);
-	}
-	/*
 	 * First case : a Processing Instruction.
 	 */
-	else if ((*cur == '<') && (cur[1] == '?')) {
+	if ((*cur == '<') && (cur[1] == '?')) {
 	    xmlParsePI(ctxt);
 	}
 
@@ -6955,8 +6908,7 @@
 	    xmlPopInput(ctxt);
 	SHRINK;
 
-	if ((cons == ctxt->input->consumed) && (test == CUR_PTR) &&
-	    (tok == ctxt->token)) {
+	if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
 	    ctxt->errNo = XML_ERR_INTERNAL_ERROR;
 	    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
 	        ctxt->sax->error(ctxt->userData,
@@ -8573,20 +8525,6 @@
             case XML_PARSER_CONTENT: {
 		const xmlChar *test;
 		int cons;
-		int tok;
-
-                /*
-		 * Handle preparsed entities and charRef
-		 */
-		if (ctxt->token != 0) {
-		    xmlChar current[2] = { 0 , 0 } ;
-
-		    current[0] = (xmlChar) ctxt->token;
-		    if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
-			(ctxt->sax->characters != NULL))
-			ctxt->sax->characters(ctxt->userData, current, 1);
-		    ctxt->token = 0;
-		}
 		if ((avail < 2) && (ctxt->inputNr == 1))
 		    goto done;
 		cur = ctxt->input->cur[0];
@@ -8594,7 +8532,6 @@
 
 		test = CUR_PTR;
 	        cons = ctxt->input->consumed;
-	        tok = ctxt->token;
 	        if ((cur == '<') && (next == '?')) {
 		    if ((!terminate) &&
 		        (xmlParseLookupSequence(ctxt, '?', '>', 0) < 0))
@@ -8684,8 +8621,7 @@
 		 */
 		while ((RAW == 0) && (ctxt->inputNr > 1))
 		    xmlPopInput(ctxt);
-		if ((cons == ctxt->input->consumed) && (test == CUR_PTR) &&
-		    (tok == ctxt->token)) {
+		if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
 		    ctxt->errNo = XML_ERR_INTERNAL_ERROR;
 		    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
 			ctxt->sax->error(ctxt->userData,
diff --git a/parserInternals.c b/parserInternals.c
index 68ac538..8d4e680 100644
--- a/parserInternals.c
+++ b/parserInternals.c
@@ -1110,8 +1110,7 @@
      *   literal #xD, an XML processor must pass to the application
      *   the single character #xA. 
      */
-    if (ctxt->token != 0) ctxt->token = 0;
-    else if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
+    if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
 	if ((*ctxt->input->cur == 0) &&
 	    (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0) &&
 	    (ctxt->instate != XML_PARSER_COMMENT)) {
@@ -1260,10 +1259,6 @@
     if (ctxt->instate == XML_PARSER_EOF)
 	return(0);
 
-    if (ctxt->token != 0) {
-	*len = 0;
-	return(ctxt->token);
-    }	
     if ((*ctxt->input->cur >= 0x20) && (*ctxt->input->cur <= 0x7F)) {
 	    *len = 1;
 	    return((int) *ctxt->input->cur);
@@ -2785,11 +2780,11 @@
            (c != end2) && (c != end3)) {
 	GROW;
 	if (c == 0) break;
-        if (((c == '&') && (ctxt->token != '&')) && (NXT(1) == '#')) {
+        if ((c == '&') && (NXT(1) == '#')) {
 	    int val = xmlParseCharRef(ctxt);
 	    COPY_BUF(0,buffer,nbchars,val);
 	    NEXTL(l);
-	} else if ((c == '&') && (ctxt->token != '&') &&
+	} else if (c == '&') &&
 		   (what & XML_SUBSTITUTE_REF)) {
 	    if (xmlParserDebugEntities)
 		xmlGenericError(xmlGenericErrorContext,
@@ -3321,229 +3316,6 @@
 	deprecated = 1;
     }
 
-#if 0
-    xmlParserInputPtr input;
-    xmlChar *name;
-    xmlEntityPtr ent = NULL;
-
-    if (ctxt->token != 0) {
-        return;
-    }	
-    if (RAW != '&') return;
-    GROW;
-    if ((RAW == '&') && (NXT(1) == '#')) {
-	switch(ctxt->instate) {
-	    case XML_PARSER_ENTITY_DECL:
-	    case XML_PARSER_PI:
-	    case XML_PARSER_CDATA_SECTION:
-	    case XML_PARSER_COMMENT:
-	    case XML_PARSER_SYSTEM_LITERAL:
-		/* we just ignore it there */
-		return;
-	    case XML_PARSER_START_TAG:
-		return;
-	    case XML_PARSER_END_TAG:
-		return;
-	    case XML_PARSER_EOF:
-		ctxt->errNo = XML_ERR_CHARREF_AT_EOF;
-		if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-		    ctxt->sax->error(ctxt->userData, "CharRef at EOF\n");
-		ctxt->wellFormed = 0;
-		ctxt->disableSAX = 1;
-		return;
-	    case XML_PARSER_PROLOG:
-	    case XML_PARSER_START:
-	    case XML_PARSER_MISC:
-		ctxt->errNo = XML_ERR_CHARREF_IN_PROLOG;
-		if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-		    ctxt->sax->error(ctxt->userData, "CharRef in prolog!\n");
-		ctxt->wellFormed = 0;
-		ctxt->disableSAX = 1;
-		return;
-	    case XML_PARSER_EPILOG:
-		ctxt->errNo = XML_ERR_CHARREF_IN_EPILOG;
-		if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-		    ctxt->sax->error(ctxt->userData, "CharRef in epilog!\n");
-		ctxt->wellFormed = 0;
-		ctxt->disableSAX = 1;
-		return;
-	    case XML_PARSER_DTD:
-		ctxt->errNo = XML_ERR_CHARREF_IN_DTD;
-		if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-		    ctxt->sax->error(ctxt->userData, 
-		           "CharRef are forbidden in DTDs!\n");
-		ctxt->wellFormed = 0;
-		ctxt->disableSAX = 1;
-		return;
-	    case XML_PARSER_ENTITY_VALUE:
-	        /*
-		 * NOTE: in the case of entity values, we don't do the
-		 *       substitution here since we need the literal
-		 *       entity value to be able to save the internal
-		 *       subset of the document.
-		 *       This will be handled by xmlStringDecodeEntities
-		 */
-		return;
-	    case XML_PARSER_CONTENT:
-		return;
-	    case XML_PARSER_ATTRIBUTE_VALUE:
-		/* ctxt->token = xmlParseCharRef(ctxt); */
-		return;
-            case XML_PARSER_IGNORE:
-	        return;
-	}
-	return;
-    }
-
-    switch(ctxt->instate) {
-	case XML_PARSER_CDATA_SECTION:
-	    return;
-	case XML_PARSER_PI:
-        case XML_PARSER_COMMENT:
-	case XML_PARSER_SYSTEM_LITERAL:
-        case XML_PARSER_CONTENT:
-	    return;
-	case XML_PARSER_START_TAG:
-	    return;
-	case XML_PARSER_END_TAG:
-	    return;
-        case XML_PARSER_EOF:
-	    ctxt->errNo = XML_ERR_ENTITYREF_AT_EOF;
-	    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-	        ctxt->sax->error(ctxt->userData, "Reference at EOF\n");
-	    ctxt->wellFormed = 0;
-	    ctxt->disableSAX = 1;
-	    return;
-        case XML_PARSER_PROLOG:
-	case XML_PARSER_START:
-	case XML_PARSER_MISC:
-	    ctxt->errNo = XML_ERR_ENTITYREF_IN_PROLOG;
-	    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-	        ctxt->sax->error(ctxt->userData, "Reference in prolog!\n");
-	    ctxt->wellFormed = 0;
-	    ctxt->disableSAX = 1;
-	    return;
-        case XML_PARSER_EPILOG:
-	    ctxt->errNo = XML_ERR_ENTITYREF_IN_EPILOG;
-	    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-	        ctxt->sax->error(ctxt->userData, "Reference in epilog!\n");
-	    ctxt->wellFormed = 0;
-	    ctxt->disableSAX = 1;
-	    return;
-	case XML_PARSER_ENTITY_VALUE:
-	    /*
-	     * NOTE: in the case of entity values, we don't do the
-	     *       substitution here since we need the literal
-	     *       entity value to be able to save the internal
-	     *       subset of the document.
-	     *       This will be handled by xmlStringDecodeEntities
-	     */
-	    return;
-        case XML_PARSER_ATTRIBUTE_VALUE:
-	    /*
-	     * NOTE: in the case of attributes values, we don't do the
-	     *       substitution here unless we are in a mode where
-	     *       the parser is explicitly asked to substitute
-	     *       entities. The SAX callback is called with values
-	     *       without entity substitution.
-	     *       This will then be handled by xmlStringDecodeEntities
-	     */
-	    return;
-	case XML_PARSER_ENTITY_DECL:
-	    /*
-	     * we just ignore it there
-	     * the substitution will be done once the entity is referenced
-	     */
-	    return;
-        case XML_PARSER_DTD:
-	    ctxt->errNo = XML_ERR_ENTITYREF_IN_DTD;
-	    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-		ctxt->sax->error(ctxt->userData, 
-		       "Entity references are forbidden in DTDs!\n");
-	    ctxt->wellFormed = 0;
-	    ctxt->disableSAX = 1;
-	    return;
-        case XML_PARSER_IGNORE:
-	    return;
-    }
-
-/* TODO: this seems not reached anymore .... Verify ... */
-xmlGenericError(xmlGenericErrorContext,
-	"Reached deprecated section in xmlParserHandleReference()\n");
-xmlGenericError(xmlGenericErrorContext,
-	"Please forward the document to daniel@veillard.com\n");
-xmlGenericError(xmlGenericErrorContext,
-	"indicating the version: %s, thanks !\n", xmlParserVersion);
-    NEXT;
-    name = xmlScanName(ctxt);
-    if (name == NULL) {
-	ctxt->errNo = XML_ERR_ENTITYREF_NO_NAME;
-	if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-	    ctxt->sax->error(ctxt->userData, "Entity reference: no name\n");
-	ctxt->wellFormed = 0;
-	ctxt->disableSAX = 1;
-	ctxt->token = '&';
-	return;
-    }
-    if (NXT(xmlStrlen(name)) != ';') {
-	ctxt->errNo = XML_ERR_ENTITYREF_SEMICOL_MISSING;
-	if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-	    ctxt->sax->error(ctxt->userData, 
-	                     "Entity reference: ';' expected\n");
-	ctxt->wellFormed = 0;
-	ctxt->disableSAX = 1;
-	ctxt->token = '&';
-	xmlFree(name);
-	return;
-    }
-    SKIP(xmlStrlen(name) + 1);
-    if (ctxt->sax != NULL) {
-	if (ctxt->sax->getEntity != NULL)
-	    ent = ctxt->sax->getEntity(ctxt->userData, name);
-    }
-
-    /*
-     * [ WFC: Entity Declared ]
-     * the Name given in the entity reference must match that in an entity
-     * declaration, except that well-formed documents need not declare any
-     * of the following entities: amp, lt, gt, apos, quot. 
-     */
-    if (ent == NULL)
-	ent = xmlGetPredefinedEntity(name);
-    if (ent == NULL) {
-        ctxt->errNo = XML_ERR_UNDECLARED_ENTITY;
-	if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-	    ctxt->sax->error(ctxt->userData, 
-			     "Entity reference: entity %s not declared\n",
-			     name);
-	ctxt->wellFormed = 0;
-	ctxt->disableSAX = 1;
-	xmlFree(name);
-	return;
-    }
-
-    /*
-     * [ WFC: Parsed Entity ]
-     * An entity reference must not contain the name of an unparsed entity
-     */
-    if (ent->etype == XML_EXTERNAL_GENERAL_UNPARSED_ENTITY) {
-        ctxt->errNo = XML_ERR_UNPARSED_ENTITY;
-	if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
-	    ctxt->sax->error(ctxt->userData, 
-			 "Entity reference to unparsed entity %s\n", name);
-	ctxt->wellFormed = 0;
-	ctxt->disableSAX = 1;
-    }
-
-    if (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY) {
-        ctxt->token = ent->content[0];
-	xmlFree(name);
-	return;
-    }
-    input = xmlNewEntityInputStream(ctxt, ent);
-    xmlPushInput(ctxt, input);
-    xmlFree(name);
-#endif
     return;
 }
 
diff --git a/result/XPath/expr/floats b/result/XPath/expr/floats
index bc3801d..b6255ce 100644
--- a/result/XPath/expr/floats
+++ b/result/XPath/expr/floats
@@ -222,3 +222,23 @@
 ========================
 Expression: -(1 div 0) div 1
 Object is a number : -Infinity
+
+========================
+Expression: 5 mod 2
+Object is a number : 1
+
+========================
+Expression: 5 mod -2
+Object is a number : 1
+
+========================
+Expression: -5 mod 2
+Object is a number : -1
+
+========================
+Expression: -5 mod -2
+Object is a number : -1
+
+========================
+Expression: 8 mod 3 = 2
+Object is a Boolean : true
diff --git a/test/XPath/expr/floats b/test/XPath/expr/floats
index 2453186..96c10d1 100644
--- a/test/XPath/expr/floats
+++ b/test/XPath/expr/floats
@@ -54,3 +54,8 @@
 1 div (1 div 0)
 (1 div 0) div 1
 -(1 div 0) div 1
+5 mod 2
+5 mod -2
+-5 mod 2
+-5 mod -2
+8 mod 3 = 2
diff --git a/xmlschemas.c b/xmlschemas.c
index bae2c7a..99956d4 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -210,6 +210,20 @@
 }
 
 /**
+ * xmlSchemaFreeAnnot:
+ * @annot:  a schema type structure
+ *
+ * Deallocate a annotation structure
+ */
+static void
+xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
+{
+    if (annot == NULL)
+        return;
+    xmlFree(annot);
+}
+
+/**
  * xmlSchemaFreeNotation:
  * @schema:  a schema notation structure
  *
@@ -310,6 +324,8 @@
 	xmlSchemaFreeValue(facet->val);
     if (facet->regexp != NULL)
 	xmlRegFreeRegexp(facet->regexp);
+    if (facet->annot != NULL)
+	xmlSchemaFreeAnnot(facet->annot);
     xmlFree(facet);
 }
 
@@ -346,20 +362,6 @@
 }
 
 /**
- * xmlSchemaFreeAnnot:
- * @annot:  a schema type structure
- *
- * Deallocate a annotation structure
- */
-static void
-xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
-{
-    if (annot == NULL)
-        return;
-    xmlFree(annot);
-}
-
-/**
  * xmlSchemaFree:
  * @schema:  a schema structure
  *
diff --git a/xmlschemastypes.c b/xmlschemastypes.c
index 4d63224..0615025 100644
--- a/xmlschemastypes.c
+++ b/xmlschemastypes.c
@@ -1463,18 +1463,25 @@
             q1 = xmlSchemaDateNormalize(y, (14 * SECS_PER_HOUR));
 
             q1d = _xmlSchemaDateCastYMToDays(q1) + q1->value.date.day;
-            if (p1d < q1d)
+            if (p1d < q1d) {
+		xmlSchemaFreeValue(p1);
+		xmlSchemaFreeValue(q1);
                 return -1;
-            else if (p1d == q1d) {
+	    } else if (p1d == q1d) {
                 double sec;
 
                 sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1);
-                if (sec < 0.0)
+                if (sec < 0.0) {
+		    xmlSchemaFreeValue(p1);
+		    xmlSchemaFreeValue(q1);
                     return -1;
-                else {
+		} else {
                     /* normalize y - 14:00 */
                     q2 = xmlSchemaDateNormalize(y, -(14 * SECS_PER_HOUR));
                     q2d = _xmlSchemaDateCastYMToDays(q2) + q2->value.date.day;
+		    xmlSchemaFreeValue(p1);
+		    xmlSchemaFreeValue(q1);
+		    xmlSchemaFreeValue(q2);
                     if (p1d > q2d)
                         return 1;
                     else if (p1d == q2d) {
@@ -1485,7 +1492,10 @@
                             return 2; /* indeterminate */
                     }
                 }
-            }
+            } else {
+		xmlSchemaFreeValue(p1);
+		xmlSchemaFreeValue(q1);
+	    }
         }
     } else if (y->value.date.tz_flag) {
         q1 = xmlSchemaDateNormalize(y, 0);
@@ -1495,19 +1505,26 @@
         p1 = xmlSchemaDateNormalize(x, -(14 * SECS_PER_HOUR));
         p1d = _xmlSchemaDateCastYMToDays(p1) + p1->value.date.day;
 
-        if (p1d < q1d)
+        if (p1d < q1d) {
+	    xmlSchemaFreeValue(p1);
+	    xmlSchemaFreeValue(q1);
             return -1;
-        else if (p1d == q1d) {
+	} else if (p1d == q1d) {
             double sec;
 
             sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1);
-            if (sec < 0.0)
+            if (sec < 0.0) {
+		xmlSchemaFreeValue(p1);
+		xmlSchemaFreeValue(q1);
                 return -1;
-            else {
+	    } else {
                 /* normalize x + 14:00 */
                 p2 = xmlSchemaDateNormalize(x, (14 * SECS_PER_HOUR));
                 p2d = _xmlSchemaDateCastYMToDays(p2) + p2->value.date.day;
 
+		xmlSchemaFreeValue(p1);
+		xmlSchemaFreeValue(q1);
+		xmlSchemaFreeValue(p2);
                 if (p2d > q1d)
                     return 1;
                 else if (p2d == q1d) {
@@ -1518,6 +1535,9 @@
                         return 2; /* indeterminate */
                 }
             }
+	} else {
+	    xmlSchemaFreeValue(p1);
+	    xmlSchemaFreeValue(q1);
         }
     }
 
@@ -1531,14 +1551,20 @@
         p1 = xmlSchemaDateNormalize(x, 0);
         p1d = _xmlSchemaDateCastYMToDays(p1) + p1->value.date.day;
 
-        if (p1d < q1d)
+        if (p1d < q1d) {
+	    xmlSchemaFreeValue(p1);
+	    xmlSchemaFreeValue(q1);
             return -1;
-        else if (p1d > q1d)
+	} else if (p1d > q1d) {
+	    xmlSchemaFreeValue(p1);
+	    xmlSchemaFreeValue(q1);
             return 1;
-        else {
+	} else {
             double sec;
 
             sec = TIME_TO_NUMBER(p1) - TIME_TO_NUMBER(q1);
+	    xmlSchemaFreeValue(p1);
+	    xmlSchemaFreeValue(q1);
             if (sec < 0.0)
                 return -1;
             else if (sec > 0.0)
diff --git a/xpath.c b/xpath.c
index 4d2fcd7..f824989 100644
--- a/xpath.c
+++ b/xpath.c
@@ -4873,7 +4873,7 @@
 void
 xmlXPathModValues(xmlXPathParserContextPtr ctxt) {
     xmlXPathObjectPtr arg;
-    double arg1, arg2, tmp;
+    double arg1, arg2;
 
     arg = valuePop(ctxt);
     if (arg == NULL)
@@ -4887,8 +4887,7 @@
     if (arg2 == 0)
 	ctxt->value->floatval = xmlXPathNAN;
     else {
-	tmp=arg1/arg2;
-	ctxt->value->floatval = arg2 * (tmp - (double)((int)tmp));
+	ctxt->value->floatval = fmod(arg1, arg2);
     }
 }
 
@@ -5443,26 +5442,28 @@
  */
 xmlNodePtr
 xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
-    xmlNodePtr ret;
-
     if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL);
-    if (cur == (xmlNodePtr) xmlXPathXMLNamespace)
-	return(NULL);
-    if ((cur == NULL) || (ctxt->context->tmpNsList == NULL)) {
+    if (ctxt->context->tmpNsList == NULL && cur != (xmlNodePtr) xmlXPathXMLNamespace) {
         if (ctxt->context->tmpNsList != NULL)
 	    xmlFree(ctxt->context->tmpNsList);
 	ctxt->context->tmpNsList = 
 	    xmlGetNsList(ctxt->context->doc, ctxt->context->node);
-	if (ctxt->context->tmpNsList == NULL) return(NULL);
 	ctxt->context->tmpNsNr = 0;
-    }
-    ret = (xmlNodePtr)ctxt->context->tmpNsList[ctxt->context->tmpNsNr++];
-    if (ret == NULL) {
-	xmlFree(ctxt->context->tmpNsList);
-	ctxt->context->tmpNsList = NULL;
+	if (ctxt->context->tmpNsList != NULL) {
+	    while (ctxt->context->tmpNsList[ctxt->context->tmpNsNr] != NULL) {
+		ctxt->context->tmpNsNr++;
+	    }
+	}
 	return((xmlNodePtr) xmlXPathXMLNamespace);
     }
-    return(ret);
+    if (ctxt->context->tmpNsNr > 0) {
+	return (xmlNodePtr)ctxt->context->tmpNsList[--ctxt->context->tmpNsNr];
+    } else {
+	if (ctxt->context->tmpNsList != NULL)
+	    xmlFree(ctxt->context->tmpNsList);
+	ctxt->context->tmpNsList = NULL;
+	return(NULL);
+    }
 }
 
 /**