In preparation to use normalized values of facets during validation:

* xmlschemastypes.c xmlschemastypes.h: In preparation to use
  normalized values of facets during validation: changed the
  arguments of some string comparison functions; added a static
  xmlSchemaValidateFacetInternal() with more arguments to be
  more flexible. Prepared XML_SCHEMA_FACET_ENUMERATION validation
  to use the comparison functions. Fixed some assignments in
  xmlSchemaValAtomicType(): total digit count, lo, mi, hi.
diff --git a/xmlschemastypes.c b/xmlschemastypes.c
index a1cdf7f..d7249e0 100644
--- a/xmlschemastypes.c
+++ b/xmlschemastypes.c
@@ -1930,7 +1930,7 @@
 			/*
 		 	* If a mixed decimal, get rid of trailing zeroes
 		 	*/
-			if (dec) {
+			if (dec != -1) {
 			    while ((cptr > cval) && (*(cptr-1) == '0')) {
 				cptr--;
 				len--;
@@ -2065,9 +2065,14 @@
                     if (type == xmlSchemaTypeFloatDef) {
                         v = xmlSchemaNewValue(XML_SCHEMAS_FLOAT);
                         if (v != NULL) {
+			    /*
+			    * TODO: sscanf seems not to give the correct
+			    * value for extremely high/low values.
+			    * E.g. "1E-149" results in zero.
+			    */
                             if (sscanf((const char *) value, "%f",
                                  &(v->value.f)) == 1) {
-                                *val = v;				
+                                *val = v;
                             } else {
                                 xmlSchemaFreeValue(v);
                                 goto return1;
@@ -2078,6 +2083,10 @@
                     } else {
                         v = xmlSchemaNewValue(XML_SCHEMAS_DOUBLE);
                         if (v != NULL) {
+			    /*
+			    * TODO: sscanf seems not to give the correct
+			    * value for extremely high/low values.
+			    */
                             if (sscanf((const char *) value, "%lf",
                                  &(v->value.d)) == 1) {
                                 *val = v;
@@ -2628,7 +2637,7 @@
         case XML_SCHEMAS_NNINTEGER:{
                 const xmlChar *cur = value;
                 unsigned long lo, mi, hi;
-                int sign = 0;
+                int sign = 0, total = 0;
 
                 if (cur == NULL)
                     goto return1;
@@ -2637,11 +2646,22 @@
                     cur++;
                 } else if (*cur == '+')
                     cur++;
-                ret = xmlSchemaParseUInt(&cur, &lo, &mi, &hi);
-                if (ret == 0)
-                    goto return1;
-                if (*cur != 0)
-                    goto return1;
+		/* Skip leading zeroes. */
+		while ((*cur == '0') && ((*(cur + 1)) != 0))
+		    cur++;
+		if (*cur != '0') {
+		    total = xmlSchemaParseUInt(&cur, &lo, &mi, &hi);
+		    if (total <= 0)
+			goto return1;
+		    if (*cur != 0)
+			goto return1;
+		} else {
+		    /* Tiny speedup for "0" */
+		    total = 1;
+		    lo = 0;
+		    mi = 0;
+		    hi = 0;
+		}                
                 if (type->builtInType == XML_SCHEMAS_NPINTEGER) {
                     if ((sign == 0) &&
                         ((hi != 0) || (mi != 0) || (lo != 0)))
@@ -2664,15 +2684,15 @@
                 /*
                  * We can store a value only if no overflow occured
                  */
-                if ((ret > 0) && (val != NULL)) {
+                if (val != NULL) {
                     v = xmlSchemaNewValue(type->builtInType);
                     if (v != NULL) {
                         v->value.decimal.lo = lo;
-                        v->value.decimal.mi = lo;
-                        v->value.decimal.hi = lo;
+                        v->value.decimal.mi = mi;
+                        v->value.decimal.hi = hi;
                         v->value.decimal.sign = sign;
                         v->value.decimal.frac = 0;
-                        v->value.decimal.total = cur - value;
+                        v->value.decimal.total = total;
                         *val = v;
                     }
                 }
@@ -2694,11 +2714,22 @@
                     cur++;
                 } else if (*cur == '+')
                     cur++;
-                ret = xmlSchemaParseUInt(&cur, &lo, &mi, &hi);
-                if (ret <= 0)
-                    goto return1;
-                if (*cur != 0)
-                    goto return1;
+		/* Skip leading zeroes. */
+		while ((*cur == '0') && ((*(cur + 1)) != 0))
+		    cur++;
+		if (*cur != '0') {
+		    total = xmlSchemaParseUInt(&cur, &lo, &mi, &hi);
+		    if (total <= 0)
+			goto return1;
+		    if (*cur != 0)
+			goto return1;
+		} else {
+		    /* Tiny speedup for "0" */
+		    total = 1;
+		    lo = 0;
+		    mi = 0;
+		    hi = 0;
+		}
                 if (type->builtInType == XML_SCHEMAS_LONG) {
                     if (hi >= 922) {
                         if (hi > 922)
@@ -2742,8 +2773,8 @@
                     v = xmlSchemaNewValue(type->builtInType);
                     if (v != NULL) {
                         v->value.decimal.lo = lo;
-                        v->value.decimal.mi = lo;
-                        v->value.decimal.hi = lo;
+                        v->value.decimal.mi = mi;
+                        v->value.decimal.hi = hi;
                         v->value.decimal.sign = sign;
                         v->value.decimal.frac = 0;
                         v->value.decimal.total = total;
@@ -2762,11 +2793,23 @@
 
                 if (cur == NULL)
                     goto return1;
-                ret = xmlSchemaParseUInt(&cur, &lo, &mi, &hi);
-                if (ret <= 0)
-                    goto return1;
-                if (*cur != 0)
-                    goto return1;
+		/* Note that "+" is not allowed. */
+		/* Skip leading zeroes. */
+		while ((*cur == '0') && ((*(cur + 1)) != 0))
+		    cur++;
+		if (*cur != '0') {
+		    total = xmlSchemaParseUInt(&cur, &lo, &mi, &hi);
+		    if (total <= 0)
+			goto return1;
+		    if (*cur != 0)
+			goto return1;
+		} else {
+		    /* Tiny speedup for "0" */
+		    total = 1;
+		    lo = 0;
+		    mi = 0;
+		    hi = 0;
+		}
                 if (type->builtInType == XML_SCHEMAS_ULONG) {
                     if (hi >= 1844) {
                         if (hi > 1844)
@@ -3684,8 +3727,8 @@
 
 /**
  * xmlSchemaComparePreserveReplaceStrings:
- * @x:  a first string value
- * @y:  a second string value
+ * @xv:  a first string value
+ * @yv:  a second string value
  * @invert: inverts the result if x < y or x > y.
  *
  * Compare 2 string for their normalized values.
@@ -3697,22 +3740,16 @@
  * case of error
  */
 static int
-xmlSchemaComparePreserveReplaceStrings(xmlSchemaValPtr x, xmlSchemaValPtr y,
+xmlSchemaComparePreserveReplaceStrings(const xmlChar *xv,
+				       const xmlChar *yv,
 				       int invert)
 {
-    const xmlChar *utf1;
-    const xmlChar *utf2;
     int tmp;
-
-    if ((x == NULL) || (y == NULL))
-	return(-2);
-    utf1 = x->value.str;
-    utf2 = y->value.str;
     
-    while ((*utf1 != 0) && (*utf2 != 0)) {
-	if (IS_WSP_REPLACE_CH(*utf2)) {
-	    if (! IS_WSP_SPACE_CH(*utf1)) {
-		if ((*utf1 - 0x20) < 0) {
+    while ((*xv != 0) && (*yv != 0)) {
+	if (IS_WSP_REPLACE_CH(*yv)) {
+	    if (! IS_WSP_SPACE_CH(*xv)) {
+		if ((*xv - 0x20) < 0) {
 		    if (invert)
 			return(1);
 		    else
@@ -3725,7 +3762,7 @@
 		}
 	    }	    
 	} else {
-	    tmp = *utf1 - *utf2;
+	    tmp = *xv - *yv;
 	    if (tmp < 0) {
 		if (invert)
 		    return(1);
@@ -3739,16 +3776,16 @@
 		    return(1);
 	    }
 	}
-	utf1++;
-	utf2++;
+	xv++;
+	yv++;
     }
-    if (*utf1 != 0) {
+    if (*xv != 0) {
 	if (invert)
 	    return(-1);
 	else
 	    return(1);
     }
-    if (*utf2 != 0) {
+    if (*yv != 0) {
 	if (invert)
 	    return(1);
 	else
@@ -3771,31 +3808,25 @@
  * case of error
  */
 static int
-xmlSchemaComparePreserveCollapseStrings(xmlSchemaValPtr x, xmlSchemaValPtr y,
+xmlSchemaComparePreserveCollapseStrings(const xmlChar *xv,
+				        const xmlChar *yv,
 					int invert)
 {
-    const xmlChar *utf1;
-    const xmlChar *utf2;
     int tmp;
 
-    if ((x == NULL) || (y == NULL))
-	return(-2);
-    utf1 = x->value.str;
-    utf2 = y->value.str;
-
     /* 
     * Skip leading blank chars of the collapsed string.
     */
-    while (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2))
-	utf2++;
+    while (IS_WSP_SPACE_CH(*yv) || IS_WSP_REPLACE_CH(*yv))
+	yv++;
 
-    while ((*utf1 != 0) && (*utf2 != 0)) {
-	if (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2)) {
-	    if (! IS_WSP_SPACE_CH(*utf1)) {
+    while ((*xv != 0) && (*yv != 0)) {
+	if (IS_WSP_SPACE_CH(*yv) || IS_WSP_REPLACE_CH(*yv)) {
+	    if (! IS_WSP_SPACE_CH(*xv)) {
 		/*
 		* The utf2 character would have been replaced to 0x20.
 		*/
-		if ((*utf1 - 0x20) < 0) {
+		if ((*xv - 0x20) < 0) {
 		    if (invert)
 			return(1);
 		    else
@@ -3807,15 +3838,15 @@
 			return(1);
 		}
 	    }
-	    utf1++;
-	    utf2++;
+	    xv++;
+	    yv++;
 	    /*
 	    * Skip contiguous blank chars of the collapsed string.
 	    */
-	    while (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2))
-		utf2++;
+	    while (IS_WSP_SPACE_CH(*yv) || IS_WSP_REPLACE_CH(*yv))
+		yv++;
 	} else {
-	    tmp = *utf1++ - *utf2++;
+	    tmp = *xv++ - *yv++;
 	    if (tmp < 0) {
 		if (invert)
 		    return(1);
@@ -3830,19 +3861,19 @@
 	    }
 	}
     }
-    if (*utf1 != 0) {
+    if (*xv != 0) {
 	 if (invert)
 	     return(-1);
 	 else
 	     return(1);
     }
-    if (*utf2 != 0) {
+    if (*yv != 0) {
 	/*
 	* Skip trailing blank chars of the collapsed string.
 	*/
-	while (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2))
-	    utf2++;
-	if (*utf2 != 0) {
+	while (IS_WSP_SPACE_CH(*yv) || IS_WSP_REPLACE_CH(*yv))
+	    yv++;
+	if (*yv != 0) {
 	    if (invert)
 		return(1);
 	    else
@@ -3866,31 +3897,25 @@
  * case of error
  */
 static int
-xmlSchemaCompareReplaceCollapseStrings(xmlSchemaValPtr x, xmlSchemaValPtr y,
+xmlSchemaCompareReplaceCollapseStrings(const xmlChar *xv,
+				       const xmlChar *yv,
 				       int invert)
 {
-    const xmlChar *utf1;
-    const xmlChar *utf2;
     int tmp;
 
-    if ((x == NULL) || (y == NULL))
-	return(-2);
-    utf1 = x->value.str;
-    utf2 = y->value.str;
-
     /* 
     * Skip leading blank chars of the collapsed string.
     */
-    while (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2))
-	utf2++;
+    while (IS_WSP_SPACE_CH(*yv) || IS_WSP_REPLACE_CH(*yv))
+	yv++;
     
-    while ((*utf1 != 0) && (*utf2 != 0)) {
-	if (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2)) {
-	    if (! (IS_WSP_SPACE_CH(*utf1) || IS_WSP_REPLACE_CH(*utf1))) {
+    while ((*xv != 0) && (*yv != 0)) {
+	if (IS_WSP_SPACE_CH(*yv) || IS_WSP_REPLACE_CH(*yv)) {
+	    if (! (IS_WSP_SPACE_CH(*xv) || IS_WSP_REPLACE_CH(*xv))) {
 		/*
 		* The utf2 character would have been replaced to 0x20.
 		*/
-		if ((*utf1 - 0x20) < 0) {
+		if ((*xv - 0x20) < 0) {
 		    if (invert)
 			return(1);
 		    else
@@ -3902,19 +3927,19 @@
 			return(1);
 		}
 	    }
-	    utf1++;
-	    utf2++;	    
+	    xv++;
+	    yv++;	    
 	    /* 
 	    * Skip contiguous blank chars of the collapsed string.
 	    */
-	    while (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2))
-		utf2++;
+	    while (IS_WSP_SPACE_CH(*yv) || IS_WSP_REPLACE_CH(*yv))
+		yv++;
 	} else {
-	    if (IS_WSP_SPACE_CH(*utf1) || IS_WSP_REPLACE_CH(*utf1)) {
+	    if (IS_WSP_SPACE_CH(*xv) || IS_WSP_REPLACE_CH(*xv)) {
 		/*
 		* The utf1 character would have been replaced to 0x20.
 		*/
-		if ((0x20 - *utf2) < 0) {
+		if ((0x20 - *yv) < 0) {
 		    if (invert)
 			return(1);
 		    else
@@ -3926,26 +3951,26 @@
 			return(1);
 		}
 	    }
-	    tmp = *utf1++ - *utf2++;
+	    tmp = *xv++ - *yv++;
 	    if (tmp < 0)
 		return(-1);
 	    if (tmp > 0)
 		return(1);
 	}
     }
-    if (*utf1 != 0) {
+    if (*xv != 0) {
 	 if (invert)
 	     return(-1);
 	 else
 	     return(1);
     }   
-    if (*utf2 != 0) {
+    if (*yv != 0) {
 	/*
 	* Skip trailing blank chars of the collapsed string.
 	*/
-	while (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2))
-	    utf2++;
-	if (*utf2 != 0) {
+	while (IS_WSP_SPACE_CH(*yv) || IS_WSP_REPLACE_CH(*yv))
+	    yv++;
+	if (*yv != 0) {
 	    if (invert)
 		return(1);
 	    else
@@ -3967,44 +3992,38 @@
  * case of error
  */
 static int
-xmlSchemaCompareReplacedStrings(xmlSchemaValPtr x, xmlSchemaValPtr y)
+xmlSchemaCompareReplacedStrings(const xmlChar *xv,
+				const xmlChar *yv)
 {
-    const xmlChar *utf1;
-    const xmlChar *utf2;
     int tmp;
-
-    if ((x == NULL) || (y == NULL))
-	return(-2);
-    utf1 = x->value.str;
-    utf2 = y->value.str;
-    
-    while ((*utf1 != 0) && (*utf2 != 0)) {
-	if (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2)) {
-	    if (! (IS_WSP_SPACE_CH(*utf1) || IS_WSP_REPLACE_CH(*utf1))) {
-		if ((*utf1 - 0x20) < 0)
+   
+    while ((*xv != 0) && (*yv != 0)) {
+	if (IS_WSP_SPACE_CH(*yv) || IS_WSP_REPLACE_CH(*yv)) {
+	    if (! (IS_WSP_SPACE_CH(*xv) || IS_WSP_REPLACE_CH(*xv))) {
+		if ((*xv - 0x20) < 0)
     		    return(-1);
 		else
 		    return(1);
 	    }	    
 	} else {
-	    if (IS_WSP_SPACE_CH(*utf1) || IS_WSP_REPLACE_CH(*utf1)) {
-		if ((0x20 - *utf2) < 0)
+	    if (IS_WSP_SPACE_CH(*xv) || IS_WSP_REPLACE_CH(*xv)) {
+		if ((0x20 - *yv) < 0)
     		    return(-1);
 		else
 		    return(1);
 	    }
-	    tmp = *utf1 - *utf2;
+	    tmp = *xv - *yv;
 	    if (tmp < 0)
     		return(-1);
 	    if (tmp > 0)
     		return(1);
 	}
-	utf1++;
-	utf2++;
+	xv++;
+	yv++;
     }
-    if (*utf1 != 0)
+    if (*xv != 0)
         return(1);
-    if (*utf2 != 0)
+    if (*yv != 0)
         return(-1);
     return(0);
 }
@@ -4020,42 +4039,36 @@
  * case of error
  */
 static int
-xmlSchemaCompareNormStrings(xmlSchemaValPtr x, xmlSchemaValPtr y) {
-    const xmlChar *utf1;
-    const xmlChar *utf2;
+xmlSchemaCompareNormStrings(const xmlChar *xv,
+			    const xmlChar *yv) {
     int tmp;
-
-    if ((x == NULL) || (y == NULL))
-	return(-2);
-    utf1 = x->value.str;
-    utf2 = y->value.str;
     
-    while (IS_BLANK_CH(*utf1)) utf1++;
-    while (IS_BLANK_CH(*utf2)) utf2++;
-    while ((*utf1 != 0) && (*utf2 != 0)) {
-	if (IS_BLANK_CH(*utf1)) {
-	    if (!IS_BLANK_CH(*utf2)) {
-		tmp = *utf1 - *utf2;
+    while (IS_BLANK_CH(*xv)) xv++;
+    while (IS_BLANK_CH(*yv)) yv++;
+    while ((*xv != 0) && (*yv != 0)) {
+	if (IS_BLANK_CH(*xv)) {
+	    if (!IS_BLANK_CH(*yv)) {
+		tmp = *xv - *yv;
 		return(tmp);
 	    }
-	    while (IS_BLANK_CH(*utf1)) utf1++;
-	    while (IS_BLANK_CH(*utf2)) utf2++;
+	    while (IS_BLANK_CH(*xv)) xv++;
+	    while (IS_BLANK_CH(*yv)) yv++;
 	} else {
-	    tmp = *utf1++ - *utf2++;
+	    tmp = *xv++ - *yv++;
 	    if (tmp < 0)
 		return(-1);
 	    if (tmp > 0)
 		return(1);
 	}
     }
-    if (*utf1 != 0) {
-	while (IS_BLANK_CH(*utf1)) utf1++;
-	if (*utf1 != 0)
+    if (*xv != 0) {
+	while (IS_BLANK_CH(*xv)) xv++;
+	if (*xv != 0)
 	    return(1);
     }
-    if (*utf2 != 0) {
-	while (IS_BLANK_CH(*utf2)) utf2++;
-	if (*utf2 != 0)
+    if (*yv != 0) {
+	while (IS_BLANK_CH(*yv)) yv++;
+	if (*yv != 0)
 	    return(-1);
     }
     return(0);
@@ -4137,8 +4150,10 @@
 /**
  * xmlSchemaCompareValues:
  * @x:  a first value
+ * @xvalue: the first value as a string (optional)
  * @xwtsp: the whitespace type
  * @y:  a second value
+ * @xvalue: the second value as a string (optional)
  * @ywtsp: the whitespace type
  *
  * Compare 2 values
@@ -4147,14 +4162,18 @@
  * case of error
  */
 static int
-xmlSchemaCompareValuesInternal(xmlSchemaValPtr x,
+xmlSchemaCompareValuesInternal(xmlSchemaValType xtype,
+			       xmlSchemaValPtr x,
+			       const xmlChar *xvalue,
 			       xmlSchemaWhitespaceValueType xws,
+			       xmlSchemaValType ytype,
 			       xmlSchemaValPtr y,
+			       const xmlChar *yvalue,
 			       xmlSchemaWhitespaceValueType yws) {
     if ((x == NULL) || (y == NULL))
 	return(-2);
 
-    switch (x->type) {
+    switch (xtype) {
 	case XML_SCHEMAS_UNKNOWN:
 	case XML_SCHEMAS_ANYTYPE:
 	    return(-2);
@@ -4172,25 +4191,29 @@
         case XML_SCHEMAS_BYTE:
         case XML_SCHEMAS_UBYTE:
 	case XML_SCHEMAS_DECIMAL:
-	    if (y->type == x->type)
+	    if ((x == NULL) || (y == NULL))
+		return(-2);
+	    if (ytype == xtype)
 		return(xmlSchemaCompareDecimals(x, y));
-	    if ((y->type == XML_SCHEMAS_DECIMAL) ||
-		(y->type == XML_SCHEMAS_INTEGER) ||
-		(y->type == XML_SCHEMAS_NPINTEGER) ||
-		(y->type == XML_SCHEMAS_NINTEGER) ||
-		(y->type == XML_SCHEMAS_NNINTEGER) ||
-		(y->type == XML_SCHEMAS_PINTEGER) ||
-		(y->type == XML_SCHEMAS_INT) ||
-		(y->type == XML_SCHEMAS_UINT) ||
-		(y->type == XML_SCHEMAS_LONG) ||
-		(y->type == XML_SCHEMAS_ULONG) ||
-		(y->type == XML_SCHEMAS_SHORT) ||
-		(y->type == XML_SCHEMAS_USHORT) ||
-		(y->type == XML_SCHEMAS_BYTE) ||
-		(y->type == XML_SCHEMAS_UBYTE))
+	    if ((ytype == XML_SCHEMAS_DECIMAL) ||
+		(ytype == XML_SCHEMAS_INTEGER) ||
+		(ytype == XML_SCHEMAS_NPINTEGER) ||
+		(ytype == XML_SCHEMAS_NINTEGER) ||
+		(ytype == XML_SCHEMAS_NNINTEGER) ||
+		(ytype == XML_SCHEMAS_PINTEGER) ||
+		(ytype == XML_SCHEMAS_INT) ||
+		(ytype == XML_SCHEMAS_UINT) ||
+		(ytype == XML_SCHEMAS_LONG) ||
+		(ytype == XML_SCHEMAS_ULONG) ||
+		(ytype == XML_SCHEMAS_SHORT) ||
+		(ytype == XML_SCHEMAS_USHORT) ||
+		(ytype == XML_SCHEMAS_BYTE) ||
+		(ytype == XML_SCHEMAS_UBYTE))
 		return(xmlSchemaCompareDecimals(x, y));
 	    return(-2);
         case XML_SCHEMAS_DURATION:
+	    if ((x == NULL) || (y == NULL))
+		return(-2);
 	    if (y->type == XML_SCHEMAS_DURATION)
                 return(xmlSchemaCompareDurations(x, y));
             return(-2);
@@ -4202,14 +4225,16 @@
         case XML_SCHEMAS_GYEARMONTH:
         case XML_SCHEMAS_DATE:
         case XML_SCHEMAS_DATETIME:
-            if ((y->type == XML_SCHEMAS_DATETIME)  ||
-                (y->type == XML_SCHEMAS_TIME)      ||
-                (y->type == XML_SCHEMAS_GDAY)      ||
-                (y->type == XML_SCHEMAS_GMONTH)    ||
-                (y->type == XML_SCHEMAS_GMONTHDAY) ||
-                (y->type == XML_SCHEMAS_GYEAR)     ||
-                (y->type == XML_SCHEMAS_DATE)      ||
-                (y->type == XML_SCHEMAS_GYEARMONTH))
+	    if ((x == NULL) || (y == NULL))
+		return(-2);
+            if ((ytype == XML_SCHEMAS_DATETIME)  ||
+                (ytype == XML_SCHEMAS_TIME)      ||
+                (ytype == XML_SCHEMAS_GDAY)      ||
+                (ytype == XML_SCHEMAS_GMONTH)    ||
+                (ytype == XML_SCHEMAS_GMONTHDAY) ||
+                (ytype == XML_SCHEMAS_GYEAR)     ||
+                (ytype == XML_SCHEMAS_DATE)      ||
+                (ytype == XML_SCHEMAS_GYEARMONTH))
                 return (xmlSchemaCompareDates(x, y));
             return (-2);
 	/* 
@@ -4229,64 +4254,80 @@
         case XML_SCHEMAS_ENTITY:
         case XML_SCHEMAS_NOTATION:
         case XML_SCHEMAS_ANYURI:
+	{
+	    const xmlChar *xv, *yv;
+
+	    if (x == NULL)
+		xv = xvalue;
+	    else
+		xv = x->value.str;
+	    if (y == NULL)
+		yv = yvalue;
+	    else
+		yv = y->value.str;
 	    /*
 	    * TODO: Compare those against QName.
 	    */
-	    if (y->type == XML_SCHEMAS_QNAME) {
+	    if (ytype == XML_SCHEMAS_QNAME) {		
 		TODO
+		if (y == NULL)
+		    return(-2);    
 		return (-2);
 	    }
-            if ((y->type == XML_SCHEMAS_ANYSIMPLETYPE) ||
-		(y->type == XML_SCHEMAS_STRING) ||
-		(y->type == XML_SCHEMAS_NORMSTRING) ||
-                (y->type == XML_SCHEMAS_TOKEN) ||
-                (y->type == XML_SCHEMAS_LANGUAGE) ||
-                (y->type == XML_SCHEMAS_NMTOKEN) ||
-                (y->type == XML_SCHEMAS_NAME) ||
-                (y->type == XML_SCHEMAS_NCNAME) ||
-                (y->type == XML_SCHEMAS_ID) ||
-                (y->type == XML_SCHEMAS_IDREF) ||
-                (y->type == XML_SCHEMAS_ENTITY) ||
-                (y->type == XML_SCHEMAS_NOTATION) ||
-                (y->type == XML_SCHEMAS_ANYURI)) {
+            if ((ytype == XML_SCHEMAS_ANYSIMPLETYPE) ||
+		(ytype == XML_SCHEMAS_STRING) ||
+		(ytype == XML_SCHEMAS_NORMSTRING) ||
+                (ytype == XML_SCHEMAS_TOKEN) ||
+                (ytype == XML_SCHEMAS_LANGUAGE) ||
+                (ytype == XML_SCHEMAS_NMTOKEN) ||
+                (ytype == XML_SCHEMAS_NAME) ||
+                (ytype == XML_SCHEMAS_NCNAME) ||
+                (ytype == XML_SCHEMAS_ID) ||
+                (ytype == XML_SCHEMAS_IDREF) ||
+                (ytype == XML_SCHEMAS_ENTITY) ||
+                (ytype == XML_SCHEMAS_NOTATION) ||
+                (ytype == XML_SCHEMAS_ANYURI)) {
 
 		if (xws == XML_SCHEMA_WHITESPACE_PRESERVE) {
 
 		    if (yws == XML_SCHEMA_WHITESPACE_PRESERVE) {
 			/* TODO: What about x < y or x > y. */
-			if (xmlStrEqual(x->value.str, y->value.str))
+			if (xmlStrEqual(xv, yv))
 			    return (0);
 			else 
 			    return (2);
 		    } else if (yws == XML_SCHEMA_WHITESPACE_REPLACE)
-			return (xmlSchemaComparePreserveReplaceStrings(x, y, 0));
+			return (xmlSchemaComparePreserveReplaceStrings(xv, yv, 0));
 		    else if (yws == XML_SCHEMA_WHITESPACE_COLLAPSE)
-			return (xmlSchemaComparePreserveCollapseStrings(x, y, 0));
+			return (xmlSchemaComparePreserveCollapseStrings(xv, yv, 0));
 
 		} else if (xws == XML_SCHEMA_WHITESPACE_REPLACE) {
 
 		    if (yws == XML_SCHEMA_WHITESPACE_PRESERVE)
-			return (xmlSchemaComparePreserveReplaceStrings(y, x, 1));
+			return (xmlSchemaComparePreserveReplaceStrings(yv, xv, 1));
 		    if (yws == XML_SCHEMA_WHITESPACE_REPLACE)
-			return (xmlSchemaCompareReplacedStrings(x, y));
+			return (xmlSchemaCompareReplacedStrings(xv, yv));
 		    if (yws == XML_SCHEMA_WHITESPACE_COLLAPSE)
-			return (xmlSchemaCompareReplaceCollapseStrings(x, y, 0));
+			return (xmlSchemaCompareReplaceCollapseStrings(xv, yv, 0));
 
 		} else if (xws == XML_SCHEMA_WHITESPACE_COLLAPSE) {
 
 		    if (yws == XML_SCHEMA_WHITESPACE_PRESERVE)
-			return (xmlSchemaComparePreserveCollapseStrings(y, x, 1));
+			return (xmlSchemaComparePreserveCollapseStrings(yv, xv, 1));
 		    if (yws == XML_SCHEMA_WHITESPACE_REPLACE)
-			return (xmlSchemaCompareReplaceCollapseStrings(y, x, 1));
+			return (xmlSchemaCompareReplaceCollapseStrings(yv, xv, 1));
 		    if (yws == XML_SCHEMA_WHITESPACE_COLLAPSE)
-			return (xmlSchemaCompareNormStrings(x, y));
+			return (xmlSchemaCompareNormStrings(xv, yv));
 		} else
 		    return (-2);
                 
 	    }
             return (-2);
+	}
         case XML_SCHEMAS_QNAME:
-            if (y->type == XML_SCHEMAS_QNAME) {
+	    if ((x == NULL) || (y == NULL))
+		return(-2);
+            if (ytype == XML_SCHEMAS_QNAME) {
 		if ((xmlStrEqual(x->value.qname.name, y->value.qname.name)) &&
 		    (xmlStrEqual(x->value.qname.uri, y->value.qname.uri)))
 		    return(0);
@@ -4295,12 +4336,16 @@
 	    return (-2);
         case XML_SCHEMAS_FLOAT:
         case XML_SCHEMAS_DOUBLE:
-            if ((y->type == XML_SCHEMAS_FLOAT) ||
-                (y->type == XML_SCHEMAS_DOUBLE))
+	    if ((x == NULL) || (y == NULL))
+		return(-2);
+            if ((ytype == XML_SCHEMAS_FLOAT) ||
+                (ytype == XML_SCHEMAS_DOUBLE))
                 return (xmlSchemaCompareFloats(x, y));
             return (-2);
         case XML_SCHEMAS_BOOLEAN:
-            if (y->type == XML_SCHEMAS_BOOLEAN) {
+	    if ((x == NULL) || (y == NULL))
+		return(-2);
+            if (ytype == XML_SCHEMAS_BOOLEAN) {
 		if (x->value.b == y->value.b)
 		    return(0);
 		if (x->value.b == 0)
@@ -4309,7 +4354,9 @@
 	    }
 	    return (-2);
         case XML_SCHEMAS_HEXBINARY:
-            if (y->type == XML_SCHEMAS_HEXBINARY) {
+	    if ((x == NULL) || (y == NULL))
+		return(-2);
+            if (ytype == XML_SCHEMAS_HEXBINARY) {
 	        if (x->value.hex.total == y->value.hex.total) {
 		    int ret = xmlStrcmp(x->value.hex.str, y->value.hex.str);
 		    if (ret > 0)
@@ -4324,7 +4371,9 @@
             }
             return (-2);
         case XML_SCHEMAS_BASE64BINARY:
-            if (y->type == XML_SCHEMAS_BASE64BINARY) {
+	    if ((x == NULL) || (y == NULL))
+		return(-2);
+            if (ytype == XML_SCHEMAS_BASE64BINARY) {
                 if (x->value.base64.total == y->value.base64.total) {
                     int ret = xmlStrcmp(x->value.base64.str,
 		                        y->value.base64.str);
@@ -4378,7 +4427,8 @@
     else
         yws = XML_SCHEMA_WHITESPACE_COLLAPSE;
 
-    return(xmlSchemaCompareValuesInternal(x, xws, y, yws));
+    return(xmlSchemaCompareValuesInternal(x->type, x, NULL, xws, y->type,
+	y, NULL, yws));
 }
 
 /**
@@ -4395,10 +4445,38 @@
  */
 int
 xmlSchemaCompareValuesWhtsp(xmlSchemaValPtr x,
-				 xmlSchemaWhitespaceValueType xws,
-				 xmlSchemaValPtr y,
-				 xmlSchemaWhitespaceValueType yws) {
-    return(xmlSchemaCompareValuesInternal(x, xws, y, yws));
+			    xmlSchemaWhitespaceValueType xws,
+			    xmlSchemaValPtr y,
+			    xmlSchemaWhitespaceValueType yws)
+{
+    return(xmlSchemaCompareValuesInternal(x->type, x, NULL, xws, y->type,
+	y, NULL, yws));
+}
+
+/**
+ * xmlSchemaCompareValuesWhtspExt:
+ * @x:  a first value
+ * @xws: the whitespace value of x
+ * @y:  a second value
+ * @yws: the whitespace value of y
+ *
+ * Compare 2 values
+ *
+ * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
+ * case of error
+ */
+static int
+xmlSchemaCompareValuesWhtspExt(xmlSchemaValType xtype,
+			       xmlSchemaValPtr x,
+			       const xmlChar *xvalue,
+			       xmlSchemaWhitespaceValueType xws,
+			       xmlSchemaValType ytype,
+			       xmlSchemaValPtr y,
+			       const xmlChar *yvalue,
+			       xmlSchemaWhitespaceValueType yws)
+{
+    return(xmlSchemaCompareValuesInternal(xtype, x, xvalue, xws, ytype, y,
+	yvalue, yws));
 }
 
 /**
@@ -4599,7 +4677,7 @@
 }
 
 /**
- * xmlSchemaValidateFacet:
+ * xmlSchemaValidateFacetInternal:
  * @base:  the base type
  * @facet:  the facet to check
  * @value:  the lexical repr of the value to validate
@@ -4610,63 +4688,60 @@
  * Returns 0 if the element is schemas valid, a positive error code
  *     number otherwise and -1 in case of internal or API error.
  */
-int
-xmlSchemaValidateFacet(xmlSchemaTypePtr base ATTRIBUTE_UNUSED,
-	               xmlSchemaFacetPtr facet,
-	               const xmlChar *value, xmlSchemaValPtr val)
+static int
+xmlSchemaValidateFacetInternal(xmlSchemaFacetPtr facet,
+			       xmlSchemaWhitespaceValueType fws,
+			       xmlSchemaValType valType,
+			       xmlSchemaValPtr val,
+			       const xmlChar *value,
+			       xmlSchemaWhitespaceValueType ws)
 {
     int ret;
 
-    if ((facet == NULL) || (value == NULL))
-        return(-1);
+    if (facet == NULL)
+	return(-1);
+
     switch (facet->type) {
 	case XML_SCHEMA_FACET_PATTERN:
+	    /* 
+	    * NOTE that for patterns, the @value needs to be the normalized
+	    * value, *not* the lexical initial value or the canonical value.
+	    */
+	    if (value == NULL)
+		return(-1);
 	    ret = xmlRegexpExec(facet->regexp, value);
 	    if (ret == 1)
 		return(0);
-	    if (ret == 0) {
+	    if (ret == 0)
 		return(XML_SCHEMAV_CVC_PATTERN_VALID);
-	    }
 	    return(ret);
 	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
 	    ret = xmlSchemaCompareValues(val, facet->val);
-	    if (ret == -2) {
-		/* TODO error code */
+	    if (ret == -2)
 		return(-1);
-	    }
 	    if (ret == -1)
 		return(0);
-	    /* error code */
 	    return(XML_SCHEMAV_CVC_MAXEXCLUSIVE_VALID);
 	case XML_SCHEMA_FACET_MAXINCLUSIVE:
 	    ret = xmlSchemaCompareValues(val, facet->val);
-	    if (ret == -2) {
-		/* TODO error code */
+	    if (ret == -2)
 		return(-1);
-	    }
 	    if ((ret == -1) || (ret == 0))
 		return(0);
-	    /* error code */
 	    return(XML_SCHEMAV_CVC_MAXINCLUSIVE_VALID);
 	case XML_SCHEMA_FACET_MINEXCLUSIVE:
 	    ret = xmlSchemaCompareValues(val, facet->val);
-	    if (ret == -2) {
-		/* TODO error code */
+	    if (ret == -2)
 		return(-1);
-	    }
 	    if (ret == 1)
 		return(0);
-	    /* error code */
 	    return(XML_SCHEMAV_CVC_MINEXCLUSIVE_VALID);
 	case XML_SCHEMA_FACET_MININCLUSIVE:
 	    ret = xmlSchemaCompareValues(val, facet->val);
-	    if (ret == -2) {
-		/* TODO error code */
+	    if (ret == -2)
 		return(-1);
-	    }
 	    if ((ret == 1) || (ret == 0))
 		return(0);
-	    /* error code */
 	    return(XML_SCHEMAV_CVC_MININCLUSIVE_VALID);
 	case XML_SCHEMA_FACET_WHITESPACE:
 	    /* TODO whitespaces */
@@ -4677,14 +4752,25 @@
 	    */
 	    return(0);
 	case  XML_SCHEMA_FACET_ENUMERATION:
-	    if ((facet->value != NULL) &&
-		(xmlStrEqual(facet->value, value)))
-		return(0);
+	    if (fws == XML_SCHEMA_WHITESPACE_UNKNOWN) {	    
+		if ((facet->value != NULL) &&
+		    (xmlStrEqual(facet->value, value)))
+		    return(0);
+	    } else {
+		ret = xmlSchemaCompareValuesWhtspExt(facet->val->type,
+		    facet->val, facet->value, fws, valType, val,
+		    value, ws);
+		if (ret == -2)
+		    return(-1);
+		if (ret == 0)
+		    return(0);
+	    }
 	    return(XML_SCHEMAV_CVC_ENUMERATION_VALID);
 	case XML_SCHEMA_FACET_LENGTH:
 	case XML_SCHEMA_FACET_MAXLENGTH:
 	case XML_SCHEMA_FACET_MINLENGTH: {
 	    unsigned int len = 0;
+	    /* TODO: Take the whitespace of the value into account. */
 
 	    if ((facet->val == NULL) ||
 		((facet->val->type != XML_SCHEMAS_DECIMAL) &&
@@ -4697,7 +4783,7 @@
 	    else if ((val != NULL) && (val->type == XML_SCHEMAS_BASE64BINARY))
 		len = val->value.base64.total;
 	    else {
-		switch (base->builtInType) {
+		switch (valType) {
 	    	    case XML_SCHEMAS_IDREF:
 		    case XML_SCHEMAS_NORMSTRING:
 		    case XML_SCHEMAS_TOKEN:
@@ -4775,6 +4861,71 @@
 }
 
 /**
+ * xmlSchemaValidateFacet:
+ * @base:  the base type
+ * @facet:  the facet to check
+ * @value:  the lexical repr of the value to validate
+ * @val:  the precomputed value
+ *
+ * Check a value against a facet condition
+ *
+ * Returns 0 if the element is schemas valid, a positive error code
+ *     number otherwise and -1 in case of internal or API error.
+ */
+int
+xmlSchemaValidateFacet(xmlSchemaTypePtr base ATTRIBUTE_UNUSED,
+	               xmlSchemaFacetPtr facet,
+	               const xmlChar *value,
+		       xmlSchemaValPtr val)
+{
+    /*
+    * This tries to ensure API compatibility regarding the old
+    * xmlSchemaValidateFacet() and the new xmlSchemaValidateFacetInternal() and
+    * xmlSchemaValidateFacetWhtsp().
+    */
+    if (val != NULL)
+	return(xmlSchemaValidateFacetInternal(facet,
+	    XML_SCHEMA_WHITESPACE_UNKNOWN, val->type, val, value,
+	    XML_SCHEMA_WHITESPACE_UNKNOWN));
+    else {
+	return(xmlSchemaValidateFacetInternal(facet,
+	    XML_SCHEMA_WHITESPACE_UNKNOWN, base->builtInType, val, value,
+	    XML_SCHEMA_WHITESPACE_UNKNOWN));	
+    }
+}
+
+/**
+ * xmlSchemaValidateFacetWhtsp:
+ * @facet:  the facet to check
+ * @fws: the whitespace type of the facet's value
+ * @valType: the built-in type of the value
+ * @value:  the lexical (or normalized for pattern) repr of the value to validate
+ * @val:  the precomputed value
+ * @ws: the whitespace type of the value
+ *
+ * Check a value against a facet condition. This takes value normalization
+ * according to the specified whitespace types into account.
+ * Note that @value needs to be the *normalized* value if the facet
+ * is of type "pattern".
+ *
+ * Returns 0 if the element is schemas valid, a positive error code
+ *     number otherwise and -1 in case of internal or API error.
+ */
+#if 0
+int
+xmlSchemaValidateFacetWhtsp(xmlSchemaFacetPtr facet,
+			    xmlSchemaWhitespaceValueType fws,
+			    xmlSchemaValType valType,
+			    xmlSchemaValPtr val,
+			    const xmlChar *value,
+			    xmlSchemaWhitespaceValueType ws)
+{
+     return(xmlSchemaValidateFacetInternal(facet, fws, valType,
+	 val, value, ws));
+}
+#endif
+
+/**
  * xmlSchemaGetCanonValue:
  * @val: the precomputed value
  * @retValue: the returned value