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/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;