Added: 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaStateMachineGenerator.java
URL: 
http://svn.apache.org/viewvc/webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaStateMachineGenerator.java?rev=1625632&view=auto
==============================================================================
--- 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaStateMachineGenerator.java
 (added)
+++ 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaStateMachineGenerator.java
 Wed Sep 17 15:32:44 2014
@@ -0,0 +1,542 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ws.commons.schema.docpath;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+
+import javax.xml.namespace.QName;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.ws.commons.schema.XmlSchemaCollection;
+import org.apache.ws.commons.schema.XmlSchemaElement;
+import org.apache.ws.commons.schema.testutils.UtilsForTests;
+import org.apache.ws.commons.schema.walker.XmlSchemaBaseSimpleType;
+import org.apache.ws.commons.schema.walker.XmlSchemaTypeInfo;
+import org.apache.ws.commons.schema.walker.XmlSchemaWalker;
+import org.junit.Test;
+
+public class TestXmlSchemaStateMachineGenerator {
+
+    private static final String TESTSCHEMA_NS = 
"http://avro.apache.org/AvroTest";;
+    private static final String COMPLEX_SCHEMA_NS = "urn:avro:complex_schema";
+
+    @Test
+    public void testSchema() throws IOException {
+        final File schemaFile = UtilsForTests.buildFile("src", "test", 
"resources", "test_schema.xsd");
+
+        XmlSchemaStateMachineNode stateMachine = buildSchema(schemaFile, new 
QName(TESTSCHEMA_NS, "root"));
+
+        HashSet<QName> seen = new HashSet<QName>();
+
+        // avro:root
+        ExpectedElement rootElem = new ExpectedElement(new 
XmlSchemaTypeInfo(false));
+
+        ExpectedStateMachineNode rootState = new ExpectedStateMachineNode(
+                                                                          
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                          new 
QName(TESTSCHEMA_NS, "root"),
+                                                                          
rootElem);
+
+        ExpectedStateMachineNode groupSequence = new ExpectedStateMachineNode(
+                                                                              
XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                              
null, null);
+
+        rootState.addNextState(groupSequence);
+
+        ExpectedStateMachineNode groupChoice = new ExpectedStateMachineNode(
+                                                                            
XmlSchemaStateMachineNode.Type.CHOICE,
+                                                                            
null, null);
+
+        groupSequence.addNextState(groupChoice);
+
+        // avro:primitive
+        ExpectedElement primitiveElem = new ExpectedElement(
+                                                            new 
XmlSchemaTypeInfo(
+                                                                               
   XmlSchemaBaseSimpleType.STRING));
+
+        QName primitiveQName = new QName(TESTSCHEMA_NS, "primitive");
+
+        ExpectedStateMachineNode primitiveState = new ExpectedStateMachineNode(
+                                                                               
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                               
primitiveQName, primitiveElem);
+
+        groupChoice.addNextState(primitiveState);
+
+        // avro:nonNullPrimitive
+        ExpectedElement nonNullPrimitiveElem = new ExpectedElement(
+                                                                   new 
XmlSchemaTypeInfo(
+                                                                               
          XmlSchemaBaseSimpleType.STRING));
+
+        QName nonNullPrimitiveQName = new QName(TESTSCHEMA_NS, 
"nonNullPrimitive");
+
+        ExpectedStateMachineNode nonNullPrimitiveState = new 
ExpectedStateMachineNode(
+                                                                               
       XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                               
       nonNullPrimitiveQName,
+                                                                               
       nonNullPrimitiveElem);
+
+        groupChoice.addNextState(nonNullPrimitiveState);
+
+        // avro:record
+        ExpectedElement recordElem = new ExpectedElement(new 
XmlSchemaTypeInfo(false));
+
+        QName recordQName = new QName(TESTSCHEMA_NS, "record");
+
+        ExpectedStateMachineNode recordState = new ExpectedStateMachineNode(
+                                                                            
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                            
recordQName, recordElem);
+
+        recordState.addNextState(groupSequence);
+
+        // avro:map
+        ExpectedElement mapElem = new ExpectedElement(new 
XmlSchemaTypeInfo(false));
+
+        QName mapQName = new QName(TESTSCHEMA_NS, "map");
+
+        ExpectedStateMachineNode mapState = new ExpectedStateMachineNode(
+                                                                         
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                         
mapQName, mapElem);
+
+        mapState.addNextState(groupSequence);
+
+        ExpectedStateMachineNode recordSubstGrp = new ExpectedStateMachineNode(
+                                                                               
XmlSchemaStateMachineNode.Type.SUBSTITUTION_GROUP,
+                                                                               
null, null);
+
+        recordSubstGrp.addNextState(recordState);
+        recordSubstGrp.addNextState(mapState);
+
+        groupChoice.addNextState(recordSubstGrp);
+
+        // avro:list
+        ExpectedElement listElem = new ExpectedElement(new 
XmlSchemaTypeInfo(false));
+
+        QName listQName = new QName(TESTSCHEMA_NS, "list");
+
+        ExpectedStateMachineNode listState = new ExpectedStateMachineNode(
+                                                                          
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                          
listQName, listElem);
+
+        groupChoice.addNextState(listState);
+
+        ExpectedStateMachineNode listChoice = new ExpectedStateMachineNode(
+                                                                           
XmlSchemaStateMachineNode.Type.CHOICE,
+                                                                           
null, null);
+
+        listChoice.addNextState(primitiveState);
+        listChoice.addNextState(recordSubstGrp);
+
+        listState.addNextState(listChoice);
+
+        // avro:tuple
+        ExpectedElement tupleElem = new ExpectedElement(new 
XmlSchemaTypeInfo(false));
+
+        QName tupleQName = new QName(TESTSCHEMA_NS, "tuple");
+
+        ExpectedStateMachineNode tupleState = new ExpectedStateMachineNode(
+                                                                           
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                           
tupleQName, tupleElem);
+
+        groupChoice.addNextState(tupleState);
+
+        ExpectedStateMachineNode groupOfAll = new ExpectedStateMachineNode(
+                                                                           
XmlSchemaStateMachineNode.Type.ALL,
+                                                                           
null, null);
+
+        groupOfAll.addNextState(primitiveState);
+        groupOfAll.addNextState(nonNullPrimitiveState);
+        groupOfAll.addNextState(recordSubstGrp);
+        groupOfAll.addNextState(listState);
+
+        tupleState.addNextState(groupOfAll);
+
+        validate(rootState, stateMachine, seen);
+    }
+
+    @Test
+    public void testComplex() throws IOException {
+        final File schemaFile = UtilsForTests.buildFile("src", "test", 
"resources", "complex_schema.xsd");
+
+        XmlSchemaStateMachineNode stateMachine = buildSchema(schemaFile, new 
QName(COMPLEX_SCHEMA_NS, "root"));
+
+        HashSet<QName> seen = new HashSet<QName>();
+
+        ExpectedStateMachineNode rootSubstGrp = new ExpectedStateMachineNode(
+                                                                             
XmlSchemaStateMachineNode.Type.SUBSTITUTION_GROUP,
+                                                                             
null, null);
+
+        // realRoot
+        ExpectedElement realRootElem = new ExpectedElement(new 
XmlSchemaTypeInfo(false));
+
+        QName realRootQName = new QName(COMPLEX_SCHEMA_NS, "realRoot");
+
+        ExpectedStateMachineNode realRootState = new ExpectedStateMachineNode(
+                                                                              
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                              
realRootQName, realRootElem);
+
+        ExpectedStateMachineNode realRootSeq = new ExpectedStateMachineNode(
+                                                                            
XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                            
null, null);
+
+        // backtrack
+        ExpectedElement backtrackElem = new ExpectedElement(new 
XmlSchemaTypeInfo(false));
+
+        QName backtrackQName = new QName(COMPLEX_SCHEMA_NS, "backtrack");
+
+        ExpectedStateMachineNode backtrackState = new ExpectedStateMachineNode(
+                                                                               
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                               
backtrackQName, backtrackElem);
+
+        ExpectedStateMachineNode backtrackSeq = new ExpectedStateMachineNode(
+                                                                             
XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                             
null, null);
+
+        ExpectedStateMachineNode backtrackChoice = new 
ExpectedStateMachineNode(
+                                                                               
 XmlSchemaStateMachineNode.Type.CHOICE,
+                                                                               
 null, null);
+
+        ExpectedStateMachineNode backtrackChoiceChoice = new 
ExpectedStateMachineNode(
+                                                                               
       XmlSchemaStateMachineNode.Type.CHOICE,
+                                                                               
       null, null);
+
+        // avro:qName
+        ExpectedElement qNameElem = new ExpectedElement(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.QNAME));
+
+        QName qNameQName = new QName(COMPLEX_SCHEMA_NS, "qName");
+
+        ExpectedStateMachineNode qNameState = new ExpectedStateMachineNode(
+                                                                           
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                           
qNameQName, qNameElem);
+
+        // avro:avroEnum
+        ExpectedElement avroEnumElem = new ExpectedElement(
+                                                           new 
XmlSchemaTypeInfo(
+                                                                               
  XmlSchemaBaseSimpleType.STRING));
+
+        QName avroEnumQName = new QName(COMPLEX_SCHEMA_NS, "avroEnum");
+
+        ExpectedStateMachineNode avroEnumState = new ExpectedStateMachineNode(
+                                                                              
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                              
avroEnumQName, avroEnumElem);
+
+        // avro:xmlEnum
+        ExpectedElement xmlEnumElem = new ExpectedElement(
+                                                          new 
XmlSchemaTypeInfo(
+                                                                               
 XmlSchemaBaseSimpleType.STRING));
+
+        QName xmlEnumQName = new QName(COMPLEX_SCHEMA_NS, "xmlEnum");
+
+        ExpectedStateMachineNode xmlEnumState = new ExpectedStateMachineNode(
+                                                                             
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                             
xmlEnumQName, xmlEnumElem);
+
+        ExpectedStateMachineNode backtrackChoiceSequence = new 
ExpectedStateMachineNode(
+                                                                               
         XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                               
         null, null);
+
+        // avro:unsignedLongList
+        ExpectedElement unsignedLongListElem = new ExpectedElement(
+                                                                   new 
XmlSchemaTypeInfo(
+                                                                               
          new XmlSchemaTypeInfo(
+                                                                               
                                XmlSchemaBaseSimpleType.DECIMAL)));
+
+        QName unsignedLongListQName = new QName(COMPLEX_SCHEMA_NS, 
"unsignedLongList");
+
+        ExpectedStateMachineNode unsignedLongListState = new 
ExpectedStateMachineNode(
+                                                                               
       XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                               
       unsignedLongListQName,
+                                                                               
       unsignedLongListElem);
+
+        ExpectedStateMachineNode backtrackSeqSequence = new 
ExpectedStateMachineNode(
+                                                                               
      XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                               
      null, null);
+
+        // listOfUnion
+        ArrayList<XmlSchemaTypeInfo> unionForListOfUnion = new 
ArrayList<XmlSchemaTypeInfo>();
+        unionForListOfUnion.add(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.BOOLEAN));
+        unionForListOfUnion.add(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.STRING));
+        unionForListOfUnion.add(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.DECIMAL));
+        unionForListOfUnion.add(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.DECIMAL));
+
+        ExpectedElement listOfUnionElem = new ExpectedElement(
+                                                              new 
XmlSchemaTypeInfo(
+                                                                               
     new XmlSchemaTypeInfo(
+                                                                               
                           unionForListOfUnion)));
+
+        QName listOfUnionQName = new QName(COMPLEX_SCHEMA_NS, "listOfUnion");
+
+        ExpectedStateMachineNode listOfUnionState = new 
ExpectedStateMachineNode(
+                                                                               
  XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                               
  listOfUnionQName,
+                                                                               
  listOfUnionElem);
+
+        // avro:allTheThings
+        ExpectedElement allTheThingsElem = new ExpectedElement(new 
XmlSchemaTypeInfo(false));
+
+        QName allTheThingsQName = new QName(COMPLEX_SCHEMA_NS, "allTheThings");
+
+        ExpectedStateMachineNode allTheThingsState = new 
ExpectedStateMachineNode(
+                                                                               
   XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                               
   allTheThingsQName,
+                                                                               
   allTheThingsElem);
+
+        ExpectedStateMachineNode allTheThingsAll = new 
ExpectedStateMachineNode(
+                                                                               
 XmlSchemaStateMachineNode.Type.ALL,
+                                                                               
 null, null);
+
+        // firstMap
+        ExpectedElement firstMapElem = new ExpectedElement(new 
XmlSchemaTypeInfo(false));
+
+        QName firstMapQName = new QName(COMPLEX_SCHEMA_NS, "firstMap");
+
+        ExpectedStateMachineNode firstMapState = new ExpectedStateMachineNode(
+                                                                              
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                              
firstMapQName, firstMapElem);
+
+        ExpectedStateMachineNode firstMapSeq = new ExpectedStateMachineNode(
+                                                                            
XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                            
null, null);
+
+        // value
+        ExpectedElement valueElem = new ExpectedElement(
+                                                        new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.DECIMAL));
+
+        QName valueQName = new QName(COMPLEX_SCHEMA_NS, "value");
+
+        ExpectedStateMachineNode valueState = new ExpectedStateMachineNode(
+                                                                           
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                           
valueQName, valueElem);
+
+        // secondMap
+        ExpectedElement secondMapElem = new ExpectedElement(new 
XmlSchemaTypeInfo(false));
+
+        QName secondMapQName = new QName(COMPLEX_SCHEMA_NS, "secondMap");
+
+        ExpectedStateMachineNode secondMapState = new ExpectedStateMachineNode(
+                                                                               
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                               
secondMapQName, secondMapElem);
+
+        // prohibit
+        ExpectedElement prohibitElem = new ExpectedElement(new 
XmlSchemaTypeInfo(false));
+
+        QName prohibitQName = new QName(COMPLEX_SCHEMA_NS, "prohibit");
+
+        ExpectedStateMachineNode prohibitState = new ExpectedStateMachineNode(
+                                                                              
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                              
prohibitQName, prohibitElem);
+
+        ExpectedStateMachineNode prohibitSeq = new ExpectedStateMachineNode(
+                                                                            
XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                            
null, null);
+
+        // fixed
+        ExpectedElement fixedElem = new ExpectedElement(
+                                                        new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.DECIMAL));
+
+        QName fixedQName = new QName(COMPLEX_SCHEMA_NS, "fixed");
+
+        ExpectedStateMachineNode fixedState = new ExpectedStateMachineNode(
+                                                                           
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                           
fixedQName, fixedElem);
+
+        // avro:anyAndFriends
+        ExpectedElement anyAndFriendsElem = new ExpectedElement(new 
XmlSchemaTypeInfo(true));
+
+        QName anyAndFriendsQName = new QName(COMPLEX_SCHEMA_NS, 
"anyAndFriends");
+
+        ExpectedStateMachineNode anyAndFriendsState = new 
ExpectedStateMachineNode(
+                                                                               
    XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                               
    anyAndFriendsQName,
+                                                                               
    anyAndFriendsElem);
+
+        ExpectedStateMachineNode anyAndFriendsSeq = new 
ExpectedStateMachineNode(
+                                                                               
  XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                               
  null, null);
+
+        ExpectedStateMachineNode anyState = new 
ExpectedStateMachineNode(XmlSchemaStateMachineNode.Type.ANY,
+                                                                         null, 
null);
+
+        // avro:simpleExtension
+        ArrayList<XmlSchemaTypeInfo> baseUnion = new 
ArrayList<XmlSchemaTypeInfo>();
+        baseUnion.add(new XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.BOOLEAN));
+        baseUnion.add(new XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.DECIMAL));
+
+        ExpectedElement simpleExtensionElem = new ExpectedElement(new 
XmlSchemaTypeInfo(baseUnion));
+
+        QName simpleExtensionQName = new QName(COMPLEX_SCHEMA_NS, 
"simpleExtension");
+
+        ExpectedStateMachineNode simpleExtensionState = new 
ExpectedStateMachineNode(
+                                                                               
      XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                               
      simpleExtensionQName,
+                                                                               
      simpleExtensionElem);
+
+        // simpleRestriction
+        QName simpleRestrictionQName = new QName(COMPLEX_SCHEMA_NS, 
"simpleRestriction");
+
+        ExpectedStateMachineNode simpleRestrictionState = new 
ExpectedStateMachineNode(
+                                                                               
        XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                               
        simpleRestrictionQName,
+                                                                               
        simpleExtensionElem);
+
+        // complexExtension
+        ExpectedElement complexExtensionElem = new ExpectedElement(new 
XmlSchemaTypeInfo(false));
+
+        QName complexExtensionQName = new QName(COMPLEX_SCHEMA_NS, 
"complexExtension");
+
+        ExpectedStateMachineNode complexExtensionState = new 
ExpectedStateMachineNode(
+                                                                               
       XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                               
       complexExtensionQName,
+                                                                               
       complexExtensionElem);
+
+        ExpectedStateMachineNode complexExtensionSeq = new 
ExpectedStateMachineNode(
+                                                                               
     XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                               
     null, null);
+
+        ExpectedStateMachineNode complexExtensionSeqChoice = new 
ExpectedStateMachineNode(
+                                                                               
           XmlSchemaStateMachineNode.Type.CHOICE,
+                                                                               
           null, null);
+
+        ExpectedStateMachineNode complexExtensionSeqSequence = new 
ExpectedStateMachineNode(
+                                                                               
             XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                               
             null, null);
+
+        // avro:mixedType
+        ExpectedElement mixedTypeElem = new ExpectedElement(new 
XmlSchemaTypeInfo(true));
+
+        QName mixedTypeQName = new QName(COMPLEX_SCHEMA_NS, "mixedType");
+
+        ExpectedStateMachineNode mixedTypeState = new ExpectedStateMachineNode(
+                                                                               
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                                               
mixedTypeQName, mixedTypeElem);
+
+        ExpectedStateMachineNode mixedTypeSeq = new ExpectedStateMachineNode(
+                                                                             
XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                             
null, null);
+
+        // Indentation follows schema
+        rootSubstGrp.addNextState(realRootState);
+        realRootState.addNextState(realRootSeq);
+        realRootSeq.addNextState(backtrackState);
+        backtrackState.addNextState(backtrackSeq);
+        backtrackSeq.addNextState(backtrackChoice);
+        backtrackChoice.addNextState(backtrackChoiceChoice);
+        backtrackChoiceChoice.addNextState(qNameState);
+        backtrackChoiceChoice.addNextState(avroEnumState);
+        backtrackChoiceChoice.addNextState(xmlEnumState);
+        backtrackChoice.addNextState(backtrackChoiceSequence);
+        backtrackChoiceSequence.addNextState(xmlEnumState);
+        backtrackChoiceSequence.addNextState(unsignedLongListState);
+        backtrackSeq.addNextState(backtrackSeqSequence);
+        backtrackSeqSequence.addNextState(qNameState);
+        backtrackSeqSequence.addNextState(avroEnumState);
+        backtrackSeqSequence.addNextState(xmlEnumState);
+        backtrackSeqSequence.addNextState(unsignedLongListState);
+        backtrackSeqSequence.addNextState(listOfUnionState);
+        realRootSeq.addNextState(allTheThingsState);
+        allTheThingsState.addNextState(allTheThingsAll);
+        allTheThingsAll.addNextState(firstMapState);
+        firstMapState.addNextState(firstMapSeq);
+        firstMapSeq.addNextState(valueState);
+        allTheThingsAll.addNextState(secondMapState);
+        realRootSeq.addNextState(prohibitState);
+        prohibitState.addNextState(prohibitSeq);
+        prohibitSeq.addNextState(fixedState);
+        realRootSeq.addNextState(anyAndFriendsState);
+        anyAndFriendsState.addNextState(anyAndFriendsSeq);
+        anyAndFriendsSeq.addNextState(anyState);
+        anyAndFriendsSeq.addNextState(anyState);
+        anyAndFriendsSeq.addNextState(anyState);
+        anyAndFriendsSeq.addNextState(anyState);
+        anyAndFriendsSeq.addNextState(anyState);
+        anyAndFriendsSeq.addNextState(anyState);
+        realRootSeq.addNextState(simpleExtensionState);
+        realRootSeq.addNextState(simpleRestrictionState);
+        realRootSeq.addNextState(complexExtensionState);
+        complexExtensionState.addNextState(complexExtensionSeq);
+        complexExtensionSeq.addNextState(complexExtensionSeqSequence);
+        complexExtensionSeqSequence.addNextState(fixedState);
+        complexExtensionSeq.addNextState(complexExtensionSeqChoice);
+        complexExtensionSeqChoice.addNextState(listOfUnionState);
+        complexExtensionSeqChoice.addNextState(unsignedLongListState);
+        realRootSeq.addNextState(mixedTypeState);
+        mixedTypeState.addNextState(mixedTypeSeq);
+        mixedTypeSeq.addNextState(listOfUnionState);
+        mixedTypeSeq.addNextState(unsignedLongListState);
+
+        validate(rootSubstGrp, stateMachine, seen);
+    }
+
+    private XmlSchemaStateMachineNode buildSchema(File schemaFile, QName root) 
throws IOException {
+
+        XmlSchemaCollection xmlSchemaCollection = new XmlSchemaCollection();
+
+        FileReader schemaFileReader = null;
+        try {
+            schemaFileReader = new FileReader(schemaFile);
+            xmlSchemaCollection.read(new StreamSource(schemaFileReader));
+        } finally {
+            if (schemaFileReader != null) {
+                schemaFileReader.close();
+            }
+        }
+
+        XmlSchemaStateMachineGenerator stateMachineGen = new 
XmlSchemaStateMachineGenerator();
+
+        XmlSchemaWalker walker = new XmlSchemaWalker(xmlSchemaCollection, 
stateMachineGen);
+
+        XmlSchemaElement rootElement = 
xmlSchemaCollection.getElementByQName(root);
+
+        walker.walk(rootElement);
+
+        return stateMachineGen.getStartNode();
+    }
+
+    private void validate(ExpectedStateMachineNode exp, 
XmlSchemaStateMachineNode act, HashSet<QName> seen) {
+
+        exp.validate(act);
+
+        if (exp.expNodeType.equals(XmlSchemaStateMachineNode.Type.ELEMENT)) {
+            /*
+             * The state machine may fold back onto itself if an element is a
+             * child of itself. Likewise, we need to keep track of what we've
+             * seen so we do not traverse state machine nodes again.
+             */
+            seen.add(exp.expElemQName);
+        }
+
+        for (int idx = 0; idx < exp.expNextStates.size(); ++idx) {
+            ExpectedStateMachineNode expNext = exp.expNextStates.get(idx);
+            XmlSchemaStateMachineNode actNext = 
act.getPossibleNextStates().get(idx);
+
+            if 
(expNext.expNodeType.equals(XmlSchemaStateMachineNode.Type.ELEMENT)
+                && seen.contains(expNext.expElemQName)) {
+
+                // We've seen this one; no need to follow it.
+                expNext.validate(actNext);
+                continue;
+            }
+
+            validate(expNext, actNext, seen);
+        }
+
+    }
+}

Propchange: 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaStateMachineGenerator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/testutils/UtilsForTests.java
URL: 
http://svn.apache.org/viewvc/webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/testutils/UtilsForTests.java?rev=1625632&view=auto
==============================================================================
--- 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/testutils/UtilsForTests.java
 (added)
+++ 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/testutils/UtilsForTests.java
 Wed Sep 17 15:32:44 2014
@@ -0,0 +1,53 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ws.commons.schema.testutils;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+import org.custommonkey.xmlunit.DetailedDiff;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.w3c.dom.Document;
+
+public final class UtilsForTests {
+
+    public static void assertEquivalent(Document expected, Document actual) {
+        XMLUnit.setIgnoreWhitespace(true);
+        XMLUnit.setIgnoreAttributeOrder(true);
+
+        DetailedDiff diff = new DetailedDiff(XMLUnit.compareXML(expected, 
actual));
+
+        assertTrue("Differences found: " + diff.toString(), diff.similar());
+    }
+
+    public static File buildFile(String... parts) {
+        File file = null;
+
+        for (String part : parts) {
+            if (file == null) {
+                file = new File(part);
+            } else {
+                file = new File(file, part);
+            }
+        }
+
+        return file;
+    }
+}

Propchange: 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/testutils/UtilsForTests.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/TestSchemaWalker.java
URL: 
http://svn.apache.org/viewvc/webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/TestSchemaWalker.java?rev=1625632&view=auto
==============================================================================
--- 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/TestSchemaWalker.java
 (added)
+++ 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/TestSchemaWalker.java
 Wed Sep 17 15:32:44 2014
@@ -0,0 +1,922 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ws.commons.schema.walker;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.transform.stream.StreamSource;
+
+import org.junit.Assert;
+
+import org.apache.ws.commons.schema.XmlSchema;
+import org.apache.ws.commons.schema.XmlSchemaAll;
+import org.apache.ws.commons.schema.XmlSchemaAny;
+import org.apache.ws.commons.schema.XmlSchemaAnyAttribute;
+import org.apache.ws.commons.schema.XmlSchemaAttribute;
+import org.apache.ws.commons.schema.XmlSchemaChoice;
+import org.apache.ws.commons.schema.XmlSchemaCollection;
+import org.apache.ws.commons.schema.XmlSchemaElement;
+import org.apache.ws.commons.schema.XmlSchemaFractionDigitsFacet;
+import org.apache.ws.commons.schema.XmlSchemaMaxInclusiveFacet;
+import org.apache.ws.commons.schema.XmlSchemaMinInclusiveFacet;
+import org.apache.ws.commons.schema.XmlSchemaParticle;
+import org.apache.ws.commons.schema.XmlSchemaPatternFacet;
+import org.apache.ws.commons.schema.XmlSchemaSequence;
+import org.apache.ws.commons.schema.XmlSchemaUse;
+import org.apache.ws.commons.schema.XmlSchemaWhiteSpaceFacet;
+import org.apache.ws.commons.schema.testutils.UtilsForTests;
+import org.apache.ws.commons.schema.walker.XmlSchemaAttrInfo;
+import org.apache.ws.commons.schema.walker.XmlSchemaBaseSimpleType;
+import org.apache.ws.commons.schema.walker.XmlSchemaRestriction;
+import org.apache.ws.commons.schema.walker.XmlSchemaTypeInfo;
+import org.apache.ws.commons.schema.walker.XmlSchemaVisitor;
+import org.apache.ws.commons.schema.walker.XmlSchemaWalker;
+import org.junit.Test;
+
+public class TestSchemaWalker {
+
+    private static enum Type {
+        ELEMENT, SEQUENCE, CHOICE, ALL, SUBSTITUTION_GROUP
+    }
+
+    private static class StackEntry {
+        StackEntry(Type type) {
+            this.type = type;
+            this.name = null;
+            this.typeName = null;
+            this.facets = null;
+            this.baseType = null;
+            this.minOccurs = 1;
+            this.maxOccurs = 1;
+        }
+
+        StackEntry(Type type, long minOccurs, long maxOccurs) {
+            this(type);
+            this.minOccurs = minOccurs;
+            this.maxOccurs = maxOccurs;
+        }
+
+        StackEntry(Type type, String name) {
+            this(type);
+            this.name = name;
+            this.typeName = null;
+        }
+
+        StackEntry(Type type, String name, String typeName) {
+            this(type, name);
+            this.typeName = typeName;
+        }
+
+        StackEntry(Type type, String name, String typeName, 
XmlSchemaBaseSimpleType baseType) {
+
+            this(type, name, typeName);
+            this.baseType = baseType;
+        }
+
+        StackEntry(Type type, String name, String typeName, long minOccurs, 
long maxOccurs) {
+
+            this(type, name, typeName);
+            this.minOccurs = minOccurs;
+            this.maxOccurs = maxOccurs;
+        }
+
+        StackEntry(Type type, String name, String typeName, 
XmlSchemaBaseSimpleType baseType, long minOccurs,
+                   long maxOccurs) {
+
+            this(type, name, typeName, baseType);
+            this.minOccurs = minOccurs;
+            this.maxOccurs = maxOccurs;
+        }
+
+        StackEntry(Type type, String name, String typeName, 
XmlSchemaBaseSimpleType baseType,
+                   Set<XmlSchemaRestriction> facets) {
+
+            this(type, name, typeName, baseType);
+            this.facets = facets;
+        }
+
+        StackEntry(Type type, String name, String typeName, 
XmlSchemaBaseSimpleType baseType, long minOccurs,
+                   long maxOccurs, Set<XmlSchemaRestriction> facets) {
+
+            this(type, name, typeName, baseType, minOccurs, maxOccurs);
+            this.facets = facets;
+
+        }
+
+        Type type;
+        String name;
+        String typeName;
+        Set<XmlSchemaRestriction> facets;
+        long minOccurs;
+        long maxOccurs;
+        XmlSchemaBaseSimpleType baseType;
+    }
+
+    private static class Attribute {
+        public Attribute(String name, String typeName, XmlSchemaTypeInfo.Type 
type,
+                         XmlSchemaBaseSimpleType baseType) {
+
+            this.name = name;
+            this.typeName = typeName;
+            this.isOptional = false;
+            this.type = type;
+            this.baseType = baseType;
+        }
+
+        public Attribute(String name, String typeName, XmlSchemaTypeInfo.Type 
type,
+                         XmlSchemaBaseSimpleType baseType, boolean isOptional) 
{
+
+            this(name, typeName, type, baseType);
+            this.isOptional = isOptional;
+        }
+
+        public Attribute(String name, String typeName, XmlSchemaTypeInfo.Type 
type,
+                         XmlSchemaBaseSimpleType baseType, 
Set<XmlSchemaRestriction> facets) {
+
+            this(name, typeName, type, baseType);
+            this.facets = facets;
+        }
+
+        public Attribute(String name, String typeName, XmlSchemaTypeInfo.Type 
type,
+                         XmlSchemaBaseSimpleType baseType, boolean isOptional,
+                         Set<XmlSchemaRestriction> facets) {
+
+            this(name, typeName, type, baseType, isOptional);
+            this.facets = facets;
+        }
+
+        String name;
+        String typeName;
+        boolean isOptional;
+        Set<XmlSchemaRestriction> facets;
+        XmlSchemaBaseSimpleType baseType;
+        XmlSchemaTypeInfo.Type type;
+    }
+
+    private static class Visitor implements XmlSchemaVisitor {
+
+        Visitor(List<StackEntry> stack, HashMap<String, List<Attribute>> 
attributes) {
+
+            this.stack = stack;
+            this.attributes = attributes;
+        }
+
+        @Override
+        public void onEnterElement(XmlSchemaElement element, XmlSchemaTypeInfo 
typeInfo,
+                                   boolean previouslyVisited) {
+
+            StackEntry next = pop();
+            if (next.type != Type.ELEMENT) {
+                throw new IllegalStateException("Expected a " + next.type + " 
named \"" + next.name
+                                                + "\" but received an element 
named \"" + element.getName()
+                                                + "\".");
+
+            } else if (!next.name.equals(element.getName())) {
+                throw new IllegalStateException("Expected an element named \"" 
+ next.name
+                                                + "\" but received an element 
named " + element.getName()
+                                                + "\"");
+
+            } else if ((next.typeName == null) && 
!element.getSchemaType().isAnonymous()) {
+
+                throw new IllegalStateException("Expected the element named 
\"" + next.name
+                                                + "\" to carry an anonymous 
type, but the type was "
+                                                + 
element.getSchemaType().getQName());
+
+            } else if ((next.typeName != null) && 
element.getSchemaType().isAnonymous()) {
+                throw new IllegalStateException("Expected the element named 
\"" + next.name
+                                                + "\" to carry a type named 
\"" + next.typeName
+                                                + "\"; but the type was 
anonymous instead.");
+            }
+
+            checkMinAndMaxOccurs(next, element);
+
+            if (typeInfo != null) {
+                checkFacets(next.name, typeInfo, next.facets);
+
+                if ((next.baseType == null) && (typeInfo.getBaseType() != null)
+                    && 
!typeInfo.getBaseType().equals(XmlSchemaBaseSimpleType.ANYTYPE)) {
+
+                    throw new IllegalStateException("Element \"" + next.name
+                                                    + "\" was not expected to 
have an Avro schema,"
+                                                    + " but has a schema of " 
+ typeInfo.getBaseType());
+
+                } else if ((next.baseType != null) && (typeInfo.getBaseType() 
== null)) {
+
+                    throw new IllegalStateException("Element \"" + next.name
+                                                    + "\" was expected to have 
a schema of " + next.baseType
+                                                    + " but instead has no 
schema.");
+
+                } else if ((next.baseType != null) && 
!next.baseType.equals(typeInfo.getBaseType())) {
+                    throw new IllegalStateException("Element \"" + next.name
+                                                    + "\" was expected to have 
a schema of " + next.baseType
+                                                    + " but instead has a 
schema of "
+                                                    + typeInfo.getBaseType());
+                }
+
+            } else if (next.baseType != null) {
+                throw new IllegalStateException("Expected a schema of " + 
next.baseType
+                                                + " but received none.");
+            }
+
+            if ((next.facets != null) && !next.facets.isEmpty()) {
+                StringBuilder errMsg = new StringBuilder("Element \"");
+                errMsg.append(next.name);
+                errMsg.append("\" was expected to have the following facets, 
");
+                errMsg.append("but did not:");
+
+                for (XmlSchemaRestriction facet : next.facets) {
+                    errMsg.append(" \"").append(facet).append('\"');
+                }
+
+                throw new IllegalStateException(errMsg.toString());
+            }
+        }
+
+        @Override
+        public void onExitElement(XmlSchemaElement element, XmlSchemaTypeInfo 
typeInfo,
+                                  boolean previouslyVisited) {
+
+            if (!previouslyVisited && 
attributes.containsKey(element.getName())) {
+                List<Attribute> remainingAttrs = 
attributes.get(element.getName());
+                if (!remainingAttrs.isEmpty()) {
+                    StringBuilder errMsg = new StringBuilder("Element \"");
+                    errMsg.append(element.getName());
+                    errMsg.append("\" did not have the expected attributes ");
+                    errMsg.append("of the following names:");
+                    for (Attribute attr : remainingAttrs) {
+                        errMsg.append(" \"").append(attr.name).append('\"');
+                    }
+                    throw new IllegalStateException(errMsg.toString());
+                }
+            }
+        }
+
+        @Override
+        public void onVisitAttribute(XmlSchemaElement element, 
XmlSchemaAttrInfo attrInfo) {
+
+            final XmlSchemaAttribute attribute = attrInfo.getAttribute();
+            final XmlSchemaTypeInfo attributeType = attrInfo.getType();
+
+            if (!attributes.containsKey(element.getName())) {
+                throw new IllegalStateException("No attributes were expected 
for \"" + element.getName()
+                                                + "\", but \"" + 
attribute.getQName() + "\" was found.");
+            }
+
+            List<Attribute> attrs = attributes.get(element.getName());
+            boolean found = false;
+            int index = 0;
+
+            for (; index < attrs.size(); ++index) {
+                Attribute attr = attrs.get(index);
+                if (attr.name.equals(attribute.getName())) {
+                    if ((attr.typeName == null) && 
!attribute.getSchemaType().isAnonymous()) {
+
+                        throw new IllegalStateException("Element \"" + 
element.getName()
+                                                        + "\" has an attribute 
named \"" + attr.name
+                                                        + "\" whose type was 
expected to be anonymous, "
+                                                        + "but actually is 
named \""
+                                                        + 
attribute.getSchemaType().getName() + "\"");
+
+                    } else if ((attr.typeName != null) && 
attribute.getSchemaType().isAnonymous()) {
+
+                        throw new IllegalStateException("Element \"" + 
element.getName()
+                                                        + "\" has an attribute 
named \"" + attr.name
+                                                        + "\" whose type was 
expected to be \""
+                                                        + attr.typeName + "\"; 
but is anonymous instead.");
+
+                    } else if ((attr.typeName != null)
+                               && 
!attr.typeName.equals(attribute.getSchemaType().getName())) {
+
+                        throw new IllegalStateException("Element \"" + 
element.getName()
+                                                        + "\" has an attribute 
named \"" + attr.name
+                                                        + "\"; its type was 
expected to be \""
+                                                        + attr.typeName + "\" 
but instead was \""
+                                                        + 
attribute.getSchemaType().getName() + "\"");
+
+                    } else if (attr.isOptional && 
!attribute.getUse().equals(XmlSchemaUse.OPTIONAL)) {
+
+                        throw new IllegalStateException(
+                                                        "Element \""
+                                                            + element.getName()
+                                                            + "\" has an 
attribute named \""
+                                                            + attr.name
+                                                            + "\" whose usage 
was expected to be optional, but instead is "
+                                                            + 
attribute.getUse());
+
+                    } else if (!attr.isOptional && 
attribute.getUse().equals(XmlSchemaUse.OPTIONAL)) {
+
+                        throw new IllegalStateException("Element \"" + 
element.getName()
+                                                        + "\" has an attribute 
named \"" + attr.name
+                                                        + "\" whose usage was 
expected to be required,"
+                                                        + " but is actually 
optional.");
+
+                    } else if (!attr.type.equals(attributeType.getType())) {
+                        throw new IllegalStateException("Element \"" + 
element.getName()
+                                                        + "\" has an attribute 
named \"" + attr.name
+                                                        + "\" whose type was 
expected to be " + attr.type
+                                                        + " but actually was " 
+ attributeType.getType());
+
+                    } else if (attr.type.equals(XmlSchemaTypeInfo.Type.ATOMIC)
+                               && 
!attr.baseType.equals(attributeType.getBaseType())) {
+
+                        throw new IllegalStateException("Element \"" + 
element.getName()
+                                                        + "\" has an attribute 
named \"" + attr.name
+                                                        + "\" whose type was 
expected to be "
+                                                        + attr.baseType.name() 
+ " but actually was "
+                                                        + 
attributeType.getBaseType());
+
+                    } else if (attr.type.equals(XmlSchemaTypeInfo.Type.LIST)
+                               && 
!attr.baseType.equals(attributeType.getChildTypes().get(0).getBaseType())) {
+
+                        throw new IllegalStateException("Element \"" + 
element.getName()
+                                                        + "\" has an attribute 
named \"" + attr.name
+                                                        + "\" with a type of " 
+ attr.type
+                                                        + " whose base type is 
expected to be "
+                                                        + attr.baseType + " 
but actually is "
+                                                        + 
attributeType.getChildTypes().get(0).getBaseType());
+
+                    } else {
+
+                        checkFacets(attr.name, attributeType, attr.facets);
+
+                        found = true;
+                        break;
+                    }
+                }
+            }
+
+            if (found) {
+                attrs.remove(index);
+            } else {
+                throw new IllegalStateException("Element \"" + 
element.getName()
+                                                + "\" has unexpected attribute 
\"" + attribute.getName()
+                                                + "\"");
+            }
+        }
+
+        @Override
+        public void onEndAttributes(XmlSchemaElement element, 
XmlSchemaTypeInfo elemTypeInfo) {
+
+        }
+
+        @Override
+        public void onEnterSubstitutionGroup(XmlSchemaElement base) {
+            StackEntry next = pop();
+
+            if (next.type != Type.SUBSTITUTION_GROUP) {
+                throw new IllegalStateException("Expected a " + next.type
+                                                + " but instead found a 
substition group of \""
+                                                + base.getName() + "\"");
+
+            } else if (!next.name.equals(base.getName())) {
+                throw new IllegalStateException("Expected a substitution group 
for element \"" + next.name
+                                                + "\", but instead received 
one for \"" + base.getName()
+                                                + "\"");
+
+            } else if (next.minOccurs != base.getMinOccurs()) {
+                throw new IllegalStateException("Expected a substitution group 
for element \"" + next.name
+                                                + "\" and min occurs of " + 
next.minOccurs
+                                                + ", but received a min occurs 
of " + base.getMinOccurs());
+
+            } else if (next.maxOccurs != base.getMaxOccurs()) {
+                throw new IllegalStateException("Expected a substitution group 
for element \"" + next.name
+                                                + "\" and max occurs of " + 
next.maxOccurs
+                                                + ", but received a max occurs 
of " + base.getMaxOccurs());
+            }
+        }
+
+        @Override
+        public void onExitSubstitutionGroup(XmlSchemaElement base) {
+        }
+
+        @Override
+        public void onEnterAllGroup(XmlSchemaAll all) {
+            StackEntry next = pop();
+            if (next.type != Type.ALL) {
+                throw new IllegalStateException("Expected a " + next.type + " 
but received an All group.");
+            }
+            checkMinAndMaxOccurs(next, all);
+        }
+
+        @Override
+        public void onExitAllGroup(XmlSchemaAll all) {
+        }
+
+        @Override
+        public void onEnterChoiceGroup(XmlSchemaChoice choice) {
+            StackEntry next = pop();
+            if (next.type != Type.CHOICE) {
+                throw new IllegalStateException("Expected a " + next.type + " 
but received a Choice group.");
+            }
+            checkMinAndMaxOccurs(next, choice);
+        }
+
+        @Override
+        public void onExitChoiceGroup(XmlSchemaChoice choice) {
+        }
+
+        @Override
+        public void onEnterSequenceGroup(XmlSchemaSequence seq) {
+            StackEntry next = pop();
+            if (next.type != Type.SEQUENCE) {
+                throw new IllegalStateException("Expected a " + next.type + " 
but received a Sequence group.");
+            }
+            checkMinAndMaxOccurs(next, seq);
+        }
+
+        @Override
+        public void onExitSequenceGroup(XmlSchemaSequence seq) {
+        }
+
+        @Override
+        public void onVisitAny(XmlSchemaAny any) {
+            throw new IllegalStateException("No Any types were expected in the 
schema.");
+        }
+
+        @Override
+        public void onVisitAnyAttribute(XmlSchemaElement element, 
XmlSchemaAnyAttribute anyAttr) {
+
+            throw new IllegalStateException("No anyAttribute types were 
expected in the schema.");
+        }
+
+        private static void checkMinAndMaxOccurs(StackEntry next, 
XmlSchemaParticle particle) {
+
+            if (next.minOccurs != particle.getMinOccurs()) {
+                throw new IllegalStateException("Expected a minOccurs of " + 
next.minOccurs + " for "
+                                                + next.type + " \"" + next.name
+                                                + "\", but found a minOccurs 
of " + particle.getMinOccurs());
+
+            } else if (next.maxOccurs != particle.getMaxOccurs()) {
+                throw new IllegalStateException("Expected a maxOccurs of " + 
next.maxOccurs + " for "
+                                                + next.type + " \"" + next.name
+                                                + "\", but found a maxOccurs 
of " + particle.getMaxOccurs());
+            }
+        }
+
+        private StackEntry pop() {
+            if (stack.isEmpty()) {
+                throw new IllegalStateException("Ran out of stack!");
+            }
+
+            StackEntry entry = stack.get(0);
+            stack.remove(entry);
+            return entry;
+        }
+
+        private List<StackEntry> stack;
+        private HashMap<String, List<Attribute>> attributes;
+    }
+
+    /**
+     * Test for src/main/resources/test_schema.xsd
+     */
+    @Test
+    public void test() throws Exception {
+        // Build the expectations.
+        ArrayList<Attribute> attrGroupAttrs = new ArrayList<Attribute>(43);
+
+        attrGroupAttrs.add(new Attribute("anySimpleType", "anySimpleType", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         
XmlSchemaBaseSimpleType.ANYSIMPLETYPE, true));
+
+        HashSet<XmlSchemaRestriction> whiteSpaceCollapseFixedRestrictions = 
new HashSet<XmlSchemaRestriction>();
+
+        whiteSpaceCollapseFixedRestrictions
+            .add(new XmlSchemaRestriction(new 
XmlSchemaWhiteSpaceFacet("collapse", true)));
+
+        attrGroupAttrs.add(new Attribute("duration", "duration", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DURATION, 
true,
+                                         
(Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("dateTime", "dateTime", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DATETIME, 
true,
+                                         
(Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("date", "date", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DATE, true,
+                                         
(Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("time", "time", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.TIME, true,
+                                         
(Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("gYearMonth", "gYearMonth", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.YEARMONTH, 
true,
+                                         
(Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("gYear", "gYear", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.YEAR, true,
+                                         
(Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("gDay", "gDay", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DAY, true,
+                                         
(Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("gMonth", "gMonth", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.MONTH, true,
+                                         
(Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("gMonthDay", "gMonthDay", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.MONTHDAY, 
true,
+                                         
(Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("boolean", "boolean", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.BOOLEAN, true,
+                                         
(Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("base64Binary", "base64Binary", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.BIN_BASE64, 
true,
+                                         
(Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("hexBinary", "hexBinary", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.BIN_HEX, true,
+                                         
(Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("float", "float", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.FLOAT, true,
+                                         
(Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("double", "double", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DOUBLE, true,
+                                         
(Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("anyURI", "anyURI", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.ANYURI, true,
+                                         
(Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+        attrGroupAttrs.add(new Attribute("qname", "QName", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.QNAME, true,
+                                         
(Set<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+                                             .clone()));
+
+        HashSet<XmlSchemaRestriction> decimalFacets = 
(HashSet<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+            .clone();
+        decimalFacets.add(new 
XmlSchemaRestriction(XmlSchemaRestriction.Type.DIGITS_FRACTION, new Integer(0),
+                                                   false));
+
+        attrGroupAttrs.add(new Attribute("decimal", null, 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, 
true, decimalFacets));
+
+        HashSet<XmlSchemaRestriction> integerFacets = 
(HashSet<XmlSchemaRestriction>)whiteSpaceCollapseFixedRestrictions
+            .clone();
+        integerFacets.add(new XmlSchemaRestriction(new 
XmlSchemaFractionDigitsFacet(new Integer(0), true)));
+        integerFacets.add(new XmlSchemaRestriction(new 
XmlSchemaPatternFacet("[\\-+]?[0-9]+", false)));
+        attrGroupAttrs.add(new Attribute("integer", "integer", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, 
true, integerFacets));
+
+        HashSet<XmlSchemaRestriction> nonPositiveIntegerFacets = 
(HashSet<XmlSchemaRestriction>)integerFacets
+            .clone();
+        nonPositiveIntegerFacets.add(new XmlSchemaRestriction(new 
XmlSchemaMaxInclusiveFacet(new Integer(0),
+                                                                               
              false)));
+        attrGroupAttrs.add(new Attribute("nonPositiveInteger", 
"nonPositiveInteger",
+                                         XmlSchemaTypeInfo.Type.ATOMIC, 
XmlSchemaBaseSimpleType.DECIMAL,
+                                         true, nonPositiveIntegerFacets));
+
+        HashSet<XmlSchemaRestriction> negativeIntegerFacets = 
(HashSet<XmlSchemaRestriction>)integerFacets
+            .clone();
+        negativeIntegerFacets.add(new XmlSchemaRestriction(new 
XmlSchemaMaxInclusiveFacet(new Integer(-1),
+                                                                               
           false)));
+        attrGroupAttrs.add(new Attribute("negativeInteger", "negativeInteger", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, 
true, negativeIntegerFacets));
+
+        HashSet<XmlSchemaRestriction> longFacets = 
(HashSet<XmlSchemaRestriction>)integerFacets.clone();
+        longFacets
+            .add(new XmlSchemaRestriction(new XmlSchemaMinInclusiveFacet(new 
Long(-9223372036854775808L),
+                                                                         
false)));
+        longFacets
+            .add(new XmlSchemaRestriction(new XmlSchemaMaxInclusiveFacet(new 
Long(9223372036854775807L),
+                                                                         
false)));
+        attrGroupAttrs.add(new Attribute("long", "long", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, 
true, longFacets));
+
+        HashSet<XmlSchemaRestriction> intFacets = 
(HashSet<XmlSchemaRestriction>)integerFacets.clone();
+        intFacets
+            .add(new XmlSchemaRestriction(new XmlSchemaMinInclusiveFacet(new 
Integer(-2147483648), false)));
+        intFacets.add(new XmlSchemaRestriction(new 
XmlSchemaMaxInclusiveFacet(2147483647, false)));
+        attrGroupAttrs.add(new Attribute("int", "int", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, 
true, intFacets));
+
+        HashSet<XmlSchemaRestriction> shortFacets = 
(HashSet<XmlSchemaRestriction>)integerFacets.clone();
+        shortFacets.add(new XmlSchemaRestriction(new 
XmlSchemaMinInclusiveFacet(new Short((short)-32768),
+                                                                               
 false)));
+        shortFacets.add(new XmlSchemaRestriction(new 
XmlSchemaMaxInclusiveFacet(new Short((short)32767),
+                                                                               
 false)));
+        attrGroupAttrs.add(new Attribute("short", "short", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, 
true, shortFacets));
+
+        HashSet<XmlSchemaRestriction> byteFacets = 
(HashSet<XmlSchemaRestriction>)integerFacets.clone();
+        byteFacets.add(new XmlSchemaRestriction(new 
XmlSchemaMinInclusiveFacet(new Byte((byte)-128), false)));
+        byteFacets.add(new XmlSchemaRestriction(new 
XmlSchemaMaxInclusiveFacet(new Byte((byte)127), false)));
+        attrGroupAttrs.add(new Attribute("byte", "byte", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, 
true, byteFacets));
+
+        HashSet<XmlSchemaRestriction> nonNegativeIntegerFacets = 
(HashSet<XmlSchemaRestriction>)integerFacets
+            .clone();
+        nonNegativeIntegerFacets.add(new XmlSchemaRestriction(new 
XmlSchemaMinInclusiveFacet(new Integer(0),
+                                                                               
              false)));
+        attrGroupAttrs.add(new Attribute("nonNegativeInteger", 
"nonNegativeInteger",
+                                         XmlSchemaTypeInfo.Type.ATOMIC, 
XmlSchemaBaseSimpleType.DECIMAL,
+                                         true, nonNegativeIntegerFacets));
+
+        HashSet<XmlSchemaRestriction> positiveIntegerFacets = 
(HashSet<XmlSchemaRestriction>)integerFacets
+            .clone();
+        positiveIntegerFacets.add(new XmlSchemaRestriction(new 
XmlSchemaMinInclusiveFacet(new Integer(1),
+                                                                               
           false)));
+        attrGroupAttrs.add(new Attribute("positiveInteger", "positiveInteger", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, 
true, positiveIntegerFacets));
+
+        HashSet<XmlSchemaRestriction> unsignedLongFacets = 
(HashSet<XmlSchemaRestriction>)nonNegativeIntegerFacets
+            .clone();
+        unsignedLongFacets
+            .add(new XmlSchemaRestriction(
+                                          new XmlSchemaMaxInclusiveFacet(
+                                                                         new 
BigInteger(
+                                                                               
         "18446744073709551615"),
+                                                                         
false)));
+        attrGroupAttrs.add(new Attribute("unsignedLong", "unsignedLong", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, 
true, unsignedLongFacets));
+
+        HashSet<XmlSchemaRestriction> unsignedIntFacets = 
(HashSet<XmlSchemaRestriction>)nonNegativeIntegerFacets
+            .clone();
+        unsignedIntFacets.add(new XmlSchemaRestriction(new 
XmlSchemaMaxInclusiveFacet(new Long(4294967295L),
+                                                                               
       false)));
+        attrGroupAttrs.add(new Attribute("unsignedInt", "unsignedInt", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, 
true, unsignedIntFacets));
+
+        HashSet<XmlSchemaRestriction> unsignedShortFacets = 
(HashSet<XmlSchemaRestriction>)nonNegativeIntegerFacets
+            .clone();
+        unsignedShortFacets.add(new XmlSchemaRestriction(new 
XmlSchemaMaxInclusiveFacet(new Integer(65535),
+                                                                               
         false)));
+        attrGroupAttrs.add(new Attribute("unsignedShort", "unsignedShort", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, 
true, unsignedShortFacets));
+
+        HashSet<XmlSchemaRestriction> unsignedByteFacets = 
(HashSet<XmlSchemaRestriction>)nonNegativeIntegerFacets
+            .clone();
+        unsignedByteFacets.add(new XmlSchemaRestriction(new 
XmlSchemaMaxInclusiveFacet(new Short((short)255),
+                                                                               
        false)));
+        attrGroupAttrs.add(new Attribute("unsignedByte", "unsignedByte", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, 
true, unsignedByteFacets));
+
+        HashSet<XmlSchemaRestriction> stringFacets = new 
HashSet<XmlSchemaRestriction>();
+        stringFacets.add(new XmlSchemaRestriction(new 
XmlSchemaWhiteSpaceFacet("preserve", false)));
+        attrGroupAttrs.add(new Attribute("string", "string", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.STRING, true, 
stringFacets));
+
+        HashSet<XmlSchemaRestriction> normalizedStringFacets = new 
HashSet<XmlSchemaRestriction>();
+        normalizedStringFacets.add(new XmlSchemaRestriction(new 
XmlSchemaWhiteSpaceFacet("replace", false)));
+        attrGroupAttrs.add(new Attribute("normalizedString", 
"normalizedString",
+                                         XmlSchemaTypeInfo.Type.ATOMIC, 
XmlSchemaBaseSimpleType.STRING, true,
+                                         normalizedStringFacets));
+
+        HashSet<XmlSchemaRestriction> tokenFacets = new 
HashSet<XmlSchemaRestriction>();
+        tokenFacets.add(new XmlSchemaRestriction(new 
XmlSchemaWhiteSpaceFacet("collapse", false)));
+        attrGroupAttrs.add(new Attribute("token", "token", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.STRING, true, 
tokenFacets));
+
+        HashSet<XmlSchemaRestriction> languageFacets = 
(HashSet<XmlSchemaRestriction>)tokenFacets.clone();
+        languageFacets
+            .add(new XmlSchemaRestriction(new 
XmlSchemaPatternFacet("[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*",
+                                                                    false)));
+        attrGroupAttrs.add(new Attribute("language", "language", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.STRING, true, 
languageFacets));
+
+        HashSet<XmlSchemaRestriction> nmTokenFacets = 
(HashSet<XmlSchemaRestriction>)tokenFacets.clone();
+        nmTokenFacets.add(new XmlSchemaRestriction(new 
XmlSchemaPatternFacet("\\c+", false)));
+        attrGroupAttrs.add(new Attribute("nmtoken", "NMTOKEN", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.STRING, true, 
nmTokenFacets));
+
+        HashSet<XmlSchemaRestriction> nameFacets = 
(HashSet<XmlSchemaRestriction>)tokenFacets.clone();
+        nameFacets.add(new XmlSchemaRestriction(new 
XmlSchemaPatternFacet("\\i\\c*", false)));
+        attrGroupAttrs.add(new Attribute("name", "Name", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.STRING, true, 
nameFacets));
+
+        HashSet<XmlSchemaRestriction> ncNameFacets = 
(HashSet<XmlSchemaRestriction>)tokenFacets.clone();
+        ncNameFacets.add(new XmlSchemaRestriction(new 
XmlSchemaPatternFacet("[\\i-[:]][\\c-[:]]*", false)));
+        attrGroupAttrs.add(new Attribute("ncName", "NCName", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.STRING, true, 
ncNameFacets));
+
+        attrGroupAttrs.add(new Attribute("id", "ID", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.STRING, true,
+                                         
(Set<XmlSchemaRestriction>)ncNameFacets.clone()));
+        attrGroupAttrs.add(new Attribute("idref", "IDREF", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.STRING, true,
+                                         
(Set<XmlSchemaRestriction>)ncNameFacets.clone()));
+        attrGroupAttrs.add(new Attribute("idrefs", "IDREFS", 
XmlSchemaTypeInfo.Type.LIST,
+                                         XmlSchemaBaseSimpleType.STRING, true, 
null));
+        attrGroupAttrs.add(new Attribute("entity", "ENTITY", 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.STRING, true,
+                                         
(Set<XmlSchemaRestriction>)ncNameFacets.clone()));
+        attrGroupAttrs.add(new Attribute("entities", "ENTITIES", 
XmlSchemaTypeInfo.Type.LIST,
+                                         XmlSchemaBaseSimpleType.STRING, true, 
null));
+        attrGroupAttrs.add(new Attribute("nmtokens", "NMTOKENS", 
XmlSchemaTypeInfo.Type.LIST,
+                                         XmlSchemaBaseSimpleType.STRING, true, 
null));
+
+        HashSet<XmlSchemaRestriction> nonNullPrimitiveTypeFacets = new 
HashSet<XmlSchemaRestriction>(14);
+        nonNullPrimitiveTypeFacets.add(new 
XmlSchemaRestriction(XmlSchemaRestriction.Type.ENUMERATION,
+                                                                "boolean", 
false));
+        nonNullPrimitiveTypeFacets.add(new 
XmlSchemaRestriction(XmlSchemaRestriction.Type.ENUMERATION, "int",
+                                                                false));
+        nonNullPrimitiveTypeFacets.add(new 
XmlSchemaRestriction(XmlSchemaRestriction.Type.ENUMERATION,
+                                                                "long", 
false));
+        nonNullPrimitiveTypeFacets.add(new 
XmlSchemaRestriction(XmlSchemaRestriction.Type.ENUMERATION,
+                                                                "float", 
false));
+        nonNullPrimitiveTypeFacets.add(new 
XmlSchemaRestriction(XmlSchemaRestriction.Type.ENUMERATION,
+                                                                "double", 
false));
+        nonNullPrimitiveTypeFacets.add(new 
XmlSchemaRestriction(XmlSchemaRestriction.Type.ENUMERATION,
+                                                                "decimal", 
false));
+        nonNullPrimitiveTypeFacets.add(new 
XmlSchemaRestriction(XmlSchemaRestriction.Type.ENUMERATION,
+                                                                "bytes", 
false));
+        nonNullPrimitiveTypeFacets.add(new 
XmlSchemaRestriction(XmlSchemaRestriction.Type.ENUMERATION,
+                                                                "string", 
false));
+        nonNullPrimitiveTypeFacets.add(new 
XmlSchemaRestriction(XmlSchemaRestriction.Type.PATTERN, "\\c+",
+                                                                false));
+        nonNullPrimitiveTypeFacets.add(new 
XmlSchemaRestriction(XmlSchemaRestriction.Type.WHITESPACE,
+                                                                "collapse", 
false));
+
+        XmlSchemaBaseSimpleType nonNullPrimitiveType = 
XmlSchemaBaseSimpleType.STRING;
+        XmlSchemaBaseSimpleType primitiveType = XmlSchemaBaseSimpleType.STRING;
+
+        HashSet<XmlSchemaRestriction> primitiveTypeFacets = new 
HashSet<XmlSchemaRestriction>(15);
+        primitiveTypeFacets
+            .add(new 
XmlSchemaRestriction(XmlSchemaRestriction.Type.ENUMERATION, "null", false));
+        primitiveTypeFacets.addAll(nonNullPrimitiveTypeFacets);
+
+        LinkedList<StackEntry> stack = new LinkedList<StackEntry>();
+
+        // Indentation follows tree.
+        stack.add(new StackEntry(Type.ELEMENT, "root"));
+        stack.add(new StackEntry(Type.SEQUENCE));
+        stack.add(new StackEntry(Type.CHOICE, 0, Long.MAX_VALUE));
+        stack.add(new StackEntry(Type.ELEMENT, "primitive", "primitiveType", 
primitiveType,
+                                 
(Set<XmlSchemaRestriction>)primitiveTypeFacets.clone()));
+        stack.add(new StackEntry(Type.ELEMENT, "nonNullPrimitive", 
"nonNullPrimitiveType",
+                                 nonNullPrimitiveType, 
(Set<XmlSchemaRestriction>)nonNullPrimitiveTypeFacets
+                                     .clone()));
+        stack.add(new StackEntry(Type.SUBSTITUTION_GROUP, "record"));
+        stack.add(new StackEntry(Type.ELEMENT, "record", "recordType"));
+        stack.add(new StackEntry(Type.SEQUENCE));
+        stack.add(new StackEntry(Type.CHOICE, 0, Long.MAX_VALUE));
+        /* 10 */stack.add(new StackEntry(Type.ELEMENT, "primitive", 
"primitiveType", primitiveType,
+                                         
(Set<XmlSchemaRestriction>)primitiveTypeFacets.clone()));
+        stack.add(new StackEntry(Type.ELEMENT, "nonNullPrimitive", 
"nonNullPrimitiveType",
+                                 nonNullPrimitiveType, 
(Set<XmlSchemaRestriction>)nonNullPrimitiveTypeFacets
+                                     .clone()));
+        stack.add(new StackEntry(Type.SUBSTITUTION_GROUP, "record"));
+        stack.add(new StackEntry(Type.ELEMENT, "record", "recordType"));
+        stack.add(new StackEntry(Type.ELEMENT, "map"));
+        stack.add(new StackEntry(Type.SEQUENCE));
+        stack.add(new StackEntry(Type.CHOICE, 0, Long.MAX_VALUE));
+        stack.add(new StackEntry(Type.ELEMENT, "primitive", "primitiveType", 
primitiveType,
+                                 
(Set<XmlSchemaRestriction>)primitiveTypeFacets.clone()));
+        stack.add(new StackEntry(Type.ELEMENT, "nonNullPrimitive", 
"nonNullPrimitiveType",
+                                 nonNullPrimitiveType, 
(Set<XmlSchemaRestriction>)nonNullPrimitiveTypeFacets
+                                     .clone()));
+        stack.add(new StackEntry(Type.SUBSTITUTION_GROUP, "record"));
+        /* 20 */stack.add(new StackEntry(Type.ELEMENT, "record", 
"recordType"));
+        stack.add(new StackEntry(Type.ELEMENT, "map"));
+        stack.add(new StackEntry(Type.ELEMENT, "list"));
+        stack.add(new StackEntry(Type.CHOICE));
+        stack.add(new StackEntry(Type.ELEMENT, "primitive", "primitiveType", 
primitiveType, 1, 100,
+                                 
(Set<XmlSchemaRestriction>)primitiveTypeFacets.clone()));
+        stack.add(new StackEntry(Type.SUBSTITUTION_GROUP, "record", 
"recordType", 1, 100));
+        stack.add(new StackEntry(Type.ELEMENT, "record", "recordType", 1, 1));
+        stack.add(new StackEntry(Type.ELEMENT, "map"));
+        stack.add(new StackEntry(Type.ELEMENT, "tuple"));
+        stack.add(new StackEntry(Type.ALL));
+        /* 30 */stack.add(new StackEntry(Type.ELEMENT, "primitive", 
"primitiveType", primitiveType,
+                                         
(Set<XmlSchemaRestriction>)primitiveTypeFacets.clone()));
+        stack.add(new StackEntry(Type.ELEMENT, "nonNullPrimitive", 
"nonNullPrimitiveType",
+                                 nonNullPrimitiveType, 
(Set<XmlSchemaRestriction>)nonNullPrimitiveTypeFacets
+                                     .clone()));
+        stack.add(new StackEntry(Type.SUBSTITUTION_GROUP, "record"));
+        stack.add(new StackEntry(Type.ELEMENT, "record", "recordType"));
+        stack.add(new StackEntry(Type.ELEMENT, "map"));
+        stack.add(new StackEntry(Type.ELEMENT, "list"));
+        stack.add(new StackEntry(Type.ELEMENT, "list"));
+        stack.add(new StackEntry(Type.ELEMENT, "tuple"));
+        stack.add(new StackEntry(Type.ELEMENT, "map"));
+        stack.add(new StackEntry(Type.ELEMENT, "list"));
+        stack.add(new StackEntry(Type.ELEMENT, "tuple"));
+
+        HashMap<String, List<Attribute>> attributes = new HashMap<String, 
List<Attribute>>();
+        attributes.put("root", attrGroupAttrs);
+
+        HashSet<XmlSchemaRestriction> listAttrFacets = 
(HashSet<XmlSchemaRestriction>)nonNegativeIntegerFacets
+            .clone();
+        listAttrFacets.add(new 
XmlSchemaRestriction(XmlSchemaRestriction.Type.EXCLUSIVE_MAX, 100, false));
+        ArrayList<Attribute> listAttributes = new ArrayList<Attribute>(1);
+        listAttributes.add(new Attribute("size", null, 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                         XmlSchemaBaseSimpleType.DECIMAL, 
true, listAttrFacets));
+        attributes.put("list", listAttributes);
+
+        HashSet<XmlSchemaRestriction> mapAttrFacets = 
(HashSet<XmlSchemaRestriction>)ncNameFacets.clone();
+        mapAttrFacets.add(new 
XmlSchemaRestriction(XmlSchemaRestriction.Type.LENGTH_MIN, 1, false));
+        ArrayList<Attribute> mapAttributes = new ArrayList<Attribute>(1);
+        mapAttributes.add(new Attribute("id", null, 
XmlSchemaTypeInfo.Type.ATOMIC,
+                                        XmlSchemaBaseSimpleType.STRING, 
mapAttrFacets));
+        attributes.put("map", mapAttributes);
+
+        // Compare against the actual.
+        final Visitor visitor = new Visitor(stack, attributes);
+        final int numEntries = stack.size();
+
+        XmlSchemaCollection collection = null;
+        FileReader fileReader = null;
+        try {
+            File file = UtilsForTests.buildFile("src", "test", "resources", 
"test_schema.xsd");
+            fileReader = new FileReader(file);
+
+            collection = new XmlSchemaCollection();
+            collection.read(new StreamSource(fileReader, 
file.getAbsolutePath()));
+
+        } finally {
+            if (fileReader != null) {
+                try {
+                    fileReader.close();
+                } catch (IOException ioe) {
+                    ioe.printStackTrace();
+                }
+            }
+        }
+
+        XmlSchemaElement elem = getElementOf(collection, "root");
+        XmlSchemaWalker walker = new XmlSchemaWalker(collection, visitor);
+        try {
+            walker.walk(elem);
+        } catch (Exception e) {
+            throw new IllegalStateException("Failed on stack entry " + 
(numEntries - stack.size()), e);
+        }
+
+        Assert.assertTrue(stack.isEmpty());
+    }
+
+    private static void checkFacets(String nextName, XmlSchemaTypeInfo 
typeInfo,
+                                    Set<XmlSchemaRestriction> nextFacets) {
+        final HashMap<XmlSchemaRestriction.Type, List<XmlSchemaRestriction>> 
facets = typeInfo.getFacets();
+
+        if ((facets == null) && (nextFacets != null)) {
+            throw new IllegalStateException("Expected " + nextFacets.size() + 
" facets for element \""
+                                            + nextName + "\" but received null 
facets.");
+
+        } else if ((facets != null) && facets.isEmpty() && (nextFacets != 
null) && !nextFacets.isEmpty()) {
+            throw new IllegalStateException("Expected " + nextFacets.size() + 
" facets for element \""
+                                            + nextName + "\" but found none.");
+
+        } else if ((facets != null) && !facets.isEmpty() && (nextFacets != 
null) && nextFacets.isEmpty()) {
+
+            throw new IllegalStateException("Element " + nextName + " has 
facets, but none were expected.");
+        }
+
+        if (facets != null) {
+            for (Map.Entry<XmlSchemaRestriction.Type, 
List<XmlSchemaRestriction>> facetsForType : facets
+                .entrySet()) {
+
+                for (XmlSchemaRestriction facet : facetsForType.getValue()) {
+                    if (!nextFacets.remove(facet)) {
+                        throw new IllegalStateException("Element \"" + nextName
+                                                        + "\" has unexpected 
facet \"" + facet + "\".");
+                    }
+                }
+            }
+        }
+
+    }
+
+    private static XmlSchemaElement getElementOf(XmlSchemaCollection 
collection, String name) {
+
+        XmlSchemaElement elem = null;
+        for (XmlSchema schema : collection.getXmlSchemas()) {
+            elem = schema.getElementByName(name);
+            if (elem != null) {
+                break;
+            }
+        }
+        return elem;
+    }
+}

Propchange: 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/TestSchemaWalker.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to