Christian Glahn found a problem with a recent patch to

* parser.c: Christian Glahn found a problem with a recent
  patch to xmlParseBalancedChunkMemoryRecover()
* xmlschemas.c: Charles Bozeman fixed some Schemas validation
  problems
* result/schemas/elem* result/schemas/seq* test/schemas.elem*
  test/schemas/seq*: added the test cases from Charles
Daniel
diff --git a/ChangeLog b/ChangeLog
index 1ad4edc..4b8a363 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Sat Oct 26 15:27:00 CEST 2002 Daniel Veillard <daniel@veillard.com>
+
+	* parser.c: Christian Glahn found a problem with a recent
+	  patch to xmlParseBalancedChunkMemoryRecover()
+	* xmlschemas.c: Charles Bozeman fixed some Schemas validation
+	  problems
+	* result/schemas/elem* result/schemas/seq* test/schemas.elem*
+	  test/schemas/seq*: added the test cases from Charles
+
 Wed Oct 23 16:42:29 CEST 2002 Daniel Veillard <daniel@veillard.com>
 
 	* Makefile.am config.h.in libxml.spec.in doc/Makefile.am:
diff --git a/parser.c b/parser.c
index 75d2221..304dc67 100644
--- a/parser.c
+++ b/parser.c
@@ -9831,11 +9831,15 @@
     ctxt->validate = 0;
     ctxt->loadsubset = 0;
 
-    content = doc->children;
-    doc->children = NULL;
-    xmlParseContent(ctxt);
-    doc->children = content;
-   
+    if ( doc != NULL ){
+        content = doc->children;
+        doc->children = NULL;
+        xmlParseContent(ctxt);
+        doc->children = content;
+    }
+    else {
+        xmlParseContent(ctxt);
+    }
     if ((RAW == '<') && (NXT(1) == '/')) {
 	ctxt->errNo = XML_ERR_NOT_WELL_BALANCED;
 	if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
diff --git a/result/schemas/elem0_0_0 b/result/schemas/elem0_0_0
new file mode 100644
index 0000000..0ab06b4
--- /dev/null
+++ b/result/schemas/elem0_0_0
@@ -0,0 +1 @@
+./test/schemas/elem0_0.xml validates
diff --git a/result/schemas/elem0_0_0.err b/result/schemas/elem0_0_0.err
new file mode 100644
index 0000000..8d518f4
--- /dev/null
+++ b/result/schemas/elem0_0_0.err
@@ -0,0 +1,5 @@
+Type of sequence 2 : ./test/schemas/elem0_0.xsd:11 :elements
+Type of anontype1 : ./test/schemas/elem0_0.xsd:10 :elements
+Type of sequence 2 : ./test/schemas/elem0_0.xsd:11 :elements
+Building content model for doc
+Element doc content check succeeded
diff --git a/result/schemas/seq0_0_0 b/result/schemas/seq0_0_0
new file mode 100644
index 0000000..d4c8431
--- /dev/null
+++ b/result/schemas/seq0_0_0
@@ -0,0 +1 @@
+./test/schemas/seq0_0.xml validates
diff --git a/result/schemas/seq0_0_0.err b/result/schemas/seq0_0_0.err
new file mode 100644
index 0000000..3ca2aff
--- /dev/null
+++ b/result/schemas/seq0_0_0.err
@@ -0,0 +1,88 @@
+Type of sequence 14 : ./test/schemas/seq0_0.xsd:55 :elements
+Type of anontype13 : ./test/schemas/seq0_0.xsd:54 :elements
+Type of sequence 12 : ./test/schemas/seq0_0.xsd:47 :elements
+Type of sequence 4 : ./test/schemas/seq0_0.xsd:15 :elements
+Type of anontype3 : ./test/schemas/seq0_0.xsd:14 :elements
+Type of sequence 8 : ./test/schemas/seq0_0.xsd:31 :elements
+Type of anontype7 : ./test/schemas/seq0_0.xsd:30 :elements
+Type of sequence 12 : ./test/schemas/seq0_0.xsd:47 :elements
+Type of anontype11 : ./test/schemas/seq0_0.xsd:46 :elements
+Type of sequence 10 : ./test/schemas/seq0_0.xsd:39 :elements
+Type of sequence 2 : ./test/schemas/seq0_0.xsd:11 :elements
+Type of anontype1 : ./test/schemas/seq0_0.xsd:10 :elements
+Type of sequence 6 : ./test/schemas/seq0_0.xsd:23 :elements
+Type of anontype5 : ./test/schemas/seq0_0.xsd:22 :elements
+Type of sequence 8 : ./test/schemas/seq0_0.xsd:31 :elements
+Type of sequence 4 : ./test/schemas/seq0_0.xsd:15 :elements
+Type of sequence 6 : ./test/schemas/seq0_0.xsd:23 :elements
+Type of sequence 10 : ./test/schemas/seq0_0.xsd:39 :elements
+Type of anontype9 : ./test/schemas/seq0_0.xsd:38 :elements
+Type of sequence 2 : ./test/schemas/seq0_0.xsd:11 :elements
+Type of sequence 14 : ./test/schemas/seq0_0.xsd:55 :elements
+Building content model for z-o
+Building content model for z-3
+Building content model for o-o
+Building content model for z-u
+Building content model for o-u
+Building content model for doc
+Building content model for o-3
+xmlSchemaValidateCallback: z-o, z-o, z-o
+xmlSchemaValidateCallback: b, b, b
+Element z-o content check succeeded
+xmlSchemaValidateCallback: o-o, o-o, o-o
+xmlSchemaValidateCallback: c, c, c
+Element o-o content check succeeded
+xmlSchemaValidateCallback: z-u, z-u, z-u
+xmlSchemaValidateCallback: d, d, d
+Element z-u content check succeeded
+xmlSchemaValidateCallback: o-u, o-u, o-u
+xmlSchemaValidateCallback: e, e, e
+Element o-u content check succeeded
+xmlSchemaValidateCallback: z-3, z-3, z-3
+xmlSchemaValidateCallback: f, f, f
+Element z-3 content check succeeded
+xmlSchemaValidateCallback: o-3, o-3, o-3
+xmlSchemaValidateCallback: g, g, g
+Element o-3 content check succeeded
+xmlSchemaValidateCallback: z-o, z-o, z-o
+xmlSchemaValidateCallback: b, b, b
+Element z-o content check succeeded
+xmlSchemaValidateCallback: o-o, o-o, o-o
+xmlSchemaValidateCallback: c, c, c
+Element o-o content check succeeded
+xmlSchemaValidateCallback: z-u, z-u, z-u
+xmlSchemaValidateCallback: d, d, d
+xmlSchemaValidateCallback: d, d, d
+xmlSchemaValidateCallback: d, d, d
+Element z-u content check succeeded
+xmlSchemaValidateCallback: o-u, o-u, o-u
+xmlSchemaValidateCallback: e, e, e
+xmlSchemaValidateCallback: e, e, e
+xmlSchemaValidateCallback: e, e, e
+Element o-u content check succeeded
+xmlSchemaValidateCallback: z-3, z-3, z-3
+xmlSchemaValidateCallback: f, f, f
+xmlSchemaValidateCallback: f, f, f
+xmlSchemaValidateCallback: f, f, f
+Element z-3 content check succeeded
+xmlSchemaValidateCallback: o-3, o-3, o-3
+xmlSchemaValidateCallback: g, g, g
+xmlSchemaValidateCallback: g, g, g
+xmlSchemaValidateCallback: g, g, g
+Element o-3 content check succeeded
+xmlSchemaValidateCallback: z-o, z-o, z-o
+Element z-o content check succeeded
+xmlSchemaValidateCallback: o-o, o-o, o-o
+xmlSchemaValidateCallback: c, c, c
+Element o-o content check succeeded
+xmlSchemaValidateCallback: z-u, z-u, z-u
+Element z-u content check succeeded
+xmlSchemaValidateCallback: o-u, o-u, o-u
+xmlSchemaValidateCallback: e, e, e
+Element o-u content check succeeded
+xmlSchemaValidateCallback: z-3, z-3, z-3
+Element z-3 content check succeeded
+xmlSchemaValidateCallback: o-3, o-3, o-3
+xmlSchemaValidateCallback: g, g, g
+Element o-3 content check succeeded
+Element doc content check succeeded
diff --git a/test/schemas/elem0_0.xml b/test/schemas/elem0_0.xml
new file mode 100644
index 0000000..f741c58
--- /dev/null
+++ b/test/schemas/elem0_0.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>

+<doc/>

+

diff --git a/test/schemas/elem0_0.xsd b/test/schemas/elem0_0.xsd
new file mode 100644
index 0000000..2c5bf5f
--- /dev/null
+++ b/test/schemas/elem0_0.xsd
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+  <xsd:annotation>
+    <xsd:documentation>
+      Testing min and max occurance attributes on element
+    </xsd:documentation>
+  </xsd:annotation>
+
+  <xsd:element name="doc">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element name='a' minOccurs='0' maxOccurs='3'/>
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+</xsd:schema>
diff --git a/test/schemas/seq0_0.xml b/test/schemas/seq0_0.xml
new file mode 100644
index 0000000..54b1c1c
--- /dev/null
+++ b/test/schemas/seq0_0.xml
@@ -0,0 +1,61 @@
+<doc>
+  <!-- at least one present -->
+  <z-o>
+    <b/>
+  </z-o>
+  <o-o>
+    <c/>
+  </o-o>
+  <z-u>
+    <d/>
+  </z-u>
+  <o-u>
+    <e/>
+  </o-u>
+  <z-3>
+    <f/>
+  </z-3>
+  <o-3>
+    <g/>
+  </o-3>
+  <!-- more than one present when allowed -->
+  <z-o>
+    <b/>
+  </z-o>
+  <o-o>
+    <c/>
+  </o-o>
+  <z-u>
+    <d/>
+    <d/>
+    <d/>
+  </z-u>
+  <o-u>
+    <e/>
+    <e/>
+    <e/>
+  </o-u>
+  <z-3>
+    <f/>
+    <f/>
+    <f/>
+  </z-3>
+  <o-3>
+    <g/>
+    <g/>
+    <g/>
+  </o-3>
+  <!-- min 0 are not present -->
+  <z-o/>
+  <o-o>
+    <c/>
+  </o-o>
+  <z-u/>
+  <o-u>
+    <e/>
+  </o-u>
+  <z-3/>
+  <o-3>
+    <g/>
+  </o-3>
+</doc>
diff --git a/test/schemas/seq0_0.xsd b/test/schemas/seq0_0.xsd
new file mode 100644
index 0000000..34d3a78
--- /dev/null
+++ b/test/schemas/seq0_0.xsd
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+  <xsd:annotation>
+    <xsd:documentation>
+      Testing min and max occurance attributes on sequences
+    </xsd:documentation>
+  </xsd:annotation>
+
+  <xsd:element name="doc">
+    <xsd:complexType>
+      <xsd:sequence minOccurs='0' maxOccurs='unbounded'>
+
+        <xsd:element name="z-o">
+          <xsd:complexType>
+            <xsd:sequence minOccurs='0' maxOccurs='1'>
+              <xsd:element name='b'/>
+            </xsd:sequence>
+          </xsd:complexType>
+        </xsd:element>
+
+        <xsd:element name="o-o">
+          <xsd:complexType>
+            <xsd:sequence minOccurs='1' maxOccurs='1'>
+              <xsd:element name='c'/>
+            </xsd:sequence>
+          </xsd:complexType>
+        </xsd:element>
+
+        <xsd:element name="z-u">
+          <xsd:complexType>
+            <xsd:sequence minOccurs='0' maxOccurs='unbounded'>
+              <xsd:element name='d'/>
+            </xsd:sequence>
+          </xsd:complexType>
+        </xsd:element>
+
+        <xsd:element name="o-u">
+          <xsd:complexType>
+            <xsd:sequence minOccurs='1' maxOccurs='unbounded'>
+              <xsd:element name='e'/>
+            </xsd:sequence>
+          </xsd:complexType>
+        </xsd:element>
+
+        <xsd:element name="z-3">
+          <xsd:complexType>
+            <xsd:sequence minOccurs='0' maxOccurs='3'>
+              <xsd:element name='f'/>
+            </xsd:sequence>
+          </xsd:complexType>
+        </xsd:element>
+
+        <xsd:element name="o-3">
+          <xsd:complexType>
+            <xsd:sequence minOccurs='1' maxOccurs='3'>
+              <xsd:element name='g'/>
+            </xsd:sequence>
+          </xsd:complexType>
+        </xsd:element>
+
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+</xsd:schema>
diff --git a/xmlschemas.c b/xmlschemas.c
index 721f326..773fe6e 100644
--- a/xmlschemas.c
+++ b/xmlschemas.c
@@ -3165,6 +3165,10 @@
 					   counter);
 		ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, tmp,
 					   NULL, counter);
+		if (elem->minOccurs == 0) {
+		    /* basically an elem? */
+		    xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
+		}
 
 	    } else {
 		if (elem->refDecl != NULL) {
@@ -3186,12 +3190,87 @@
 	    xmlSchemaTypePtr subtypes;
 
 	    /*
-	     * Simply iterate over the subtypes
+	     * If max and min occurances are default (1) then
+	     * simply iterate over the subtypes
 	     */
-	    subtypes = type->subtypes;
-	    while (subtypes != NULL) {
-		xmlSchemaBuildAContentModel(subtypes, ctxt, name);
-		subtypes = subtypes->next;
+	    if ((type->minOccurs == 1 ) && (type->maxOccurs == 1)) {
+	        subtypes = type->subtypes;
+	        while (subtypes != NULL) {
+		    xmlSchemaBuildAContentModel(subtypes, ctxt, name);
+		    subtypes = subtypes->next;
+	        }
+	    } else {
+	        xmlAutomataStatePtr oldstate = ctxt->state;
+	        if (type->maxOccurs >= UNBOUNDED) {
+		    if (type->minOccurs > 1) {
+		        xmlAutomataStatePtr tmp;
+		        int counter;
+
+		        ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
+			                                oldstate, NULL);
+		        oldstate = ctxt->state;
+
+		        counter = xmlAutomataNewCounter(ctxt->am,
+			        	    type->minOccurs - 1, UNBOUNDED);
+
+	                subtypes = type->subtypes;
+	                while (subtypes != NULL) {
+		            xmlSchemaBuildAContentModel(subtypes, ctxt, name);
+		            subtypes = subtypes->next;
+	                }
+		        tmp = ctxt->state;
+		        xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate,
+		                            counter);
+		        ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, tmp,
+		                            NULL, counter);
+
+		    } else {
+	                subtypes = type->subtypes;
+	                while (subtypes != NULL) {
+		            xmlSchemaBuildAContentModel(subtypes, ctxt, name);
+		            subtypes = subtypes->next;
+	                }
+		        xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldstate);
+		        if (type->minOccurs == 0) {
+			    xmlAutomataNewEpsilon(ctxt->am, oldstate,
+				                  ctxt->state);
+		        }
+		    }
+	        } else if ((type->maxOccurs > 1) || (type->minOccurs > 1)) {
+		    xmlAutomataStatePtr tmp;
+		    int counter;
+
+		    ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
+						    oldstate, NULL);
+		    oldstate = ctxt->state;
+
+		    counter = xmlAutomataNewCounter(ctxt->am,
+		                  type->minOccurs - 1, type->maxOccurs - 1);
+
+	            subtypes = type->subtypes;
+	            while (subtypes != NULL) {
+		        xmlSchemaBuildAContentModel(subtypes, ctxt, name);
+		        subtypes = subtypes->next;
+	            }
+		    tmp = ctxt->state;
+		    xmlAutomataNewCountedTrans(ctxt->am, tmp, oldstate,
+		          counter);
+		    ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, tmp,
+		                                             NULL, counter);
+		    if (type->minOccurs == 0) {
+		        xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
+		    }
+
+	        } else {
+	            subtypes = type->subtypes;
+	            while (subtypes != NULL) {
+		        xmlSchemaBuildAContentModel(subtypes, ctxt, name);
+		        subtypes = subtypes->next;
+	            }
+		    if (type->minOccurs == 0) {
+		        xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
+		    }
+	        }
 	    }
 	    break;
 	}
@@ -3217,18 +3296,15 @@
 	    } else {
 		int counter;
 		xmlAutomataStatePtr hop;
+		int maxOccurs = type->maxOccurs == UNBOUNDED ?
+		                      UNBOUNDED : type->maxOccurs - 1;
+		int minOccurs = type->minOccurs < 1 ? 0 : type->minOccurs - 1;
 
 		/*
 		 * use a counter to keep track of the number of transtions
 		 * which went through the choice.
 		 */
-		if (type->minOccurs < 1) {
-		    counter = xmlAutomataNewCounter(ctxt->am, 0,
-			                            type->maxOccurs - 1);
-		} else {
-		    counter = xmlAutomataNewCounter(ctxt->am,
-			    type->minOccurs - 1, type->maxOccurs - 1);
-		}
+		counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
 		hop = xmlAutomataNewState(ctxt->am);
 
 		subtypes = type->subtypes;