You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by an...@locus.apache.org on 2000/12/28 10:41:33 UTC

cvs commit: xml-xerces/java/src/org/apache/xerces/xni XMLString.java

andyc       00/12/28 01:41:30

  Modified:    java/src/org/apache/xerces/impl Tag: xerces_j_2
                        XMLDTDScanner.java XMLNamespaceBinder.java
                        XMLValidator.java
               java/src/org/apache/xerces/impl/validation Tag: xerces_j_2
                        Grammar.java XMLAttributeDecl.java
                        XMLElementDecl.java XMLSimpleType.java
               java/src/org/apache/xerces/impl/validation/grammars Tag:
                        xerces_j_2 DTDGrammar.java
               java/src/org/apache/xerces/parsers Tag: xerces_j_2
                        SAXParser.java
               java/src/org/apache/xerces/util Tag: xerces_j_2
                        NamespaceSupport.java
               java/src/org/apache/xerces/xni Tag: xerces_j_2
                        XMLString.java
  Log:
  1) Fixes done for namespace support. Seems to work correctly
     and pass the correct values now.
  2) Fixed validation problems with DTDs and namespaces.
  3) In process of performing massive code cleaning -- prepare
     for more.
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.76  +2 -3      xml-xerces/java/src/org/apache/xerces/impl/Attic/XMLDTDScanner.java
  
  Index: XMLDTDScanner.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/Attic/XMLDTDScanner.java,v
  retrieving revision 1.1.2.75
  retrieving revision 1.1.2.76
  diff -u -r1.1.2.75 -r1.1.2.76
  --- XMLDTDScanner.java	2000/11/30 01:27:56	1.1.2.75
  +++ XMLDTDScanner.java	2000/12/28 09:41:14	1.1.2.76
  @@ -90,7 +90,7 @@
    * @author Glenn Marcy, IBM
    * @author Eric Ye, IBM
    *
  - * @version $Id: XMLDTDScanner.java,v 1.1.2.75 2000/11/30 01:27:56 ericye Exp $
  + * @version $Id: XMLDTDScanner.java,v 1.1.2.76 2000/12/28 09:41:14 andyc Exp $
    */
   public class XMLDTDScanner
       extends XMLScanner
  @@ -1201,13 +1201,12 @@
   
           String defaultType = null;
           fString.clear();
  +        defaultVal.clear();
           if (fEntityScanner.skipString("#REQUIRED")) {
               defaultType = "#REQUIRED";
  -            defaultVal.clear();
           }
           else if (fEntityScanner.skipString("#IMPLIED")) {
               defaultType = "#IMPLIED";
  -            defaultVal.clear();
           }
           else {
               if (fEntityScanner.skipString("#FIXED")) {
  
  
  
  1.1.2.2   +12 -17    xml-xerces/java/src/org/apache/xerces/impl/Attic/XMLNamespaceBinder.java
  
  Index: XMLNamespaceBinder.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/Attic/XMLNamespaceBinder.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- XMLNamespaceBinder.java	2000/10/24 22:49:55	1.1.2.1
  +++ XMLNamespaceBinder.java	2000/12/28 09:41:15	1.1.2.2
  @@ -93,7 +93,7 @@
    *
    * @author Andy Clark, IBM
    *
  - * @version $Id: XMLNamespaceBinder.java,v 1.1.2.1 2000/10/24 22:49:55 andyc Exp $
  + * @version $Id: XMLNamespaceBinder.java,v 1.1.2.2 2000/12/28 09:41:15 andyc Exp $
    */
   public class XMLNamespaceBinder 
       implements XMLComponent, XMLDocumentFilter {
  @@ -102,11 +102,6 @@
       // Data
       //
   
  -    // features
  -
  -    /** Namespaces. */
  -    protected boolean fNamespaces;
  -
       // properties
   
       /** Symbol table. */
  @@ -563,25 +558,25 @@
        */
       public void endElement(QName element) throws SAXException {
   
  +        // bind element
  +        element.uri = fNamespaceSupport.getURI(element.prefix);
  +        
           // call handlers
           if (fDocumentHandler != null && !fOnlyPassPrefixMappingEvents) {
               fDocumentHandler.endElement(element);
           }
   
           // end prefix mappings
  -        if (fNamespaces) {
  -            // call handler
  -            if (fDocumentHandler != null) {
  -                int count = fNamespaceSupport.getDeclaredPrefixCount();
  -                for (int i = count; i > 0; i--) {
  -                    String prefix = fNamespaceSupport.getDeclaredPrefixAt(i);
  -                    fDocumentHandler.endPrefixMapping(prefix);
  -                }
  +        if (fDocumentHandler != null) {
  +            int count = fNamespaceSupport.getDeclaredPrefixCount();
  +            for (int i = count; i > 0; i--) {
  +                String prefix = fNamespaceSupport.getDeclaredPrefixAt(i);
  +                fDocumentHandler.endPrefixMapping(prefix);
               }
  -
  -            // pop context
  -            fNamespaceSupport.popContext();
           }
  +
  +        // pop context
  +        fNamespaceSupport.popContext();
   
       } // endElement(QName)
   
  
  
  
  1.1.2.60  +37 -29    xml-xerces/java/src/org/apache/xerces/impl/Attic/XMLValidator.java
  
  Index: XMLValidator.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/Attic/XMLValidator.java,v
  retrieving revision 1.1.2.59
  retrieving revision 1.1.2.60
  diff -u -r1.1.2.59 -r1.1.2.60
  --- XMLValidator.java	2000/12/09 01:42:18	1.1.2.59
  +++ XMLValidator.java	2000/12/28 09:41:16	1.1.2.60
  @@ -106,7 +106,7 @@
    * @author Andy Clark, IBM
    * @author Jeffrey Rodriguez IBM
    *
  - * @version $Id: XMLValidator.java,v 1.1.2.59 2000/12/09 01:42:18 lehors Exp $
  + * @version $Id: XMLValidator.java,v 1.1.2.60 2000/12/28 09:41:16 andyc Exp $
    */
   public class XMLValidator
   implements XMLComponent, 
  @@ -270,6 +270,11 @@
   
       /** Default constructor. */
       public XMLValidator() {
  +        
  +        // setup namespace binder
  +        fNamespaceBinder = new XMLNamespaceBinder();
  +        fNamespaceBinder.setOnlyPassPrefixMappingEvents(true);
  +
       } // <init>()
   
       //
  @@ -290,8 +295,8 @@
        *                      SAXNotRecognizedException or a
        *                      SAXNotSupportedException.
        */
  -    public void reset(XMLComponentManager configurationManager)
  -    throws SAXException {
  +    public void reset(XMLComponentManager componentManager)
  +        throws SAXException {
   
   
           // clear grammars
  @@ -315,26 +320,24 @@
           fNDataDeclNotations.clear();
   
           // sax features
  -        fValidation = configurationManager.getFeature(Constants.SAX_FEATURE_PREFIX+Constants.VALIDATION_FEATURE);
  +        fNamespaces = componentManager.getFeature(Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE);
  +        fValidation = componentManager.getFeature(Constants.SAX_FEATURE_PREFIX+Constants.VALIDATION_FEATURE);
   
           // get needed components
  -        fErrorReporter = (XMLErrorReporter) configurationManager.getProperty(Constants.XERCES_PROPERTY_PREFIX+Constants.ERROR_REPORTER_PROPERTY);
  -        fSymbolTable = (SymbolTable) configurationManager.getProperty(Constants.XERCES_PROPERTY_PREFIX+Constants.SYMBOL_TABLE_PROPERTY);
  -        fGrammarPool = (GrammarPool) configurationManager.getProperty(Constants.XERCES_PROPERTY_PREFIX+Constants.GRAMMAR_POOL_PROPERTY);
  -
  -        // plug in XMLNamespaceBinder
  -        fNamespaceBinder = new XMLNamespaceBinder();
  -        fNamespaceBinder.setOnlyPassPrefixMappingEvents(true);
  -        fNamespaceBinder.setDocumentHandler(fDocumentHandler);
  +        fErrorReporter = (XMLErrorReporter)componentManager.getProperty(Constants.XERCES_PROPERTY_PREFIX+Constants.ERROR_REPORTER_PROPERTY);
  +        fSymbolTable = (SymbolTable)componentManager.getProperty(Constants.XERCES_PROPERTY_PREFIX+Constants.SYMBOL_TABLE_PROPERTY);
  +        fGrammarPool = (GrammarPool)componentManager.getProperty(Constants.XERCES_PROPERTY_PREFIX+Constants.GRAMMAR_POOL_PROPERTY);
   
           for (int i = 0; i < fElementQNamePartsStack.length; i++) {
               fElementQNamePartsStack[i] = new QName();
           }
  -
   
  -        fElementDepth = -1;
  +        // reset namespace binder
  +        fNamespaceBinder.reset(componentManager);
   
  +        fElementDepth = -1;                      
           init();
  +
       } // reset(XMLComponentManager)
   
       /**
  @@ -386,6 +389,7 @@
        */
       public void setDocumentHandler(XMLDocumentHandler documentHandler) {
           fDocumentHandler = documentHandler;
  +        fNamespaceBinder.setDocumentHandler(fDocumentHandler);
       } // setDocumentHandler(XMLDocumentHandler)
   
       //
  @@ -595,21 +599,18 @@
   
           }
   
  -
  -        ensureStackCapacity(fElementDepth);
  +        //if fCurrentGrammar is DTD, do namespace binding here.
  +        if (fNamespaces && fCurrentGrammarIsDTD) {
  +            fNamespaceBinder.startElement(element, attributes);
  +        }
   
           fCurrentElement.setValues(element);
  -
  +        
  +        ensureStackCapacity(fElementDepth);
           fElementQNamePartsStack[fElementDepth].setValues(fCurrentElement); 
  -
           fElementIndexStack[fElementDepth] = fCurrentElementIndex;
           fContentSpecTypeStack[fElementDepth] = fCurrentContentSpecType;
   
  -        //if fCurrentGrammar is DTD, do namespace binding here.
  -        if (fNamespaces && fCurrentGrammarIsDTD) {
  -            fNamespaceBinder.startElement(element, attributes);
  -        }
  -
           // call handlers
           if (fDocumentHandler != null) {
               fDocumentHandler.startElement(element, attributes);
  @@ -738,10 +739,19 @@
   
           // call handlers
           if (fDocumentHandler != null) {
  -            // call fNamesapceBinder to fire up endPrefixMapping events
  -            fNamespaceBinder.endElement(fCurrentElement);
  +            // NOTE: The binding of the element doesn't actually happen
  +            //       yet because the namespace binder does that. However,
  +            //       if it does it before this point, then the endPrefix-
  +            //       Mapping calls get made too soon! As long as the
  +            //       rawnames match, we know it'll have a good binding,
  +            //       so we can just use the current element. -Ac
               fDocumentHandler.endElement(fCurrentElement);
           }
  +        
  +        // unbind prefixes
  +        if (fNamespaces) {
  +            fNamespaceBinder.endElement(element);
  +        }
   
           // now pop this element off the top of the element stack
           if (fElementDepth < -1) {
  @@ -1840,8 +1850,7 @@
                       int position = fCurrentGrammar.getFirstAttributeDeclIndex(elementIndex);
                       while (position != -1) {
                           fCurrentGrammar.getAttributeDecl(position, fTempAttDecl);
  -                        if (fTempAttDecl.name.rawname == attrRawName 
  -                            || fTempAttDecl.name.rawname.equals(attrRawName)) {
  +                        if (fTempAttDecl.name.rawname == attrRawName) {
                               // found the match att decl, 
                               attDefIndex = position;
                               declared = true;
  @@ -1852,8 +1861,7 @@
                       if (attDefIndex == -1) {
                           // REVISIT - cache the elem/attr tuple so that we only give
                           //  this error once for each unique occurrence
  -                        Object[] args = { element.localpart,
  -                            attrRawName};
  +                        Object[] args = { element.rawname, attrRawName };
   
                           fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
                                                      "MSG_ATTRIBUTE_NOT_DECLARED",
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.26  +1259 -1157xml-xerces/java/src/org/apache/xerces/impl/validation/Attic/Grammar.java
  
  Index: Grammar.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/validation/Attic/Grammar.java,v
  retrieving revision 1.1.2.25
  retrieving revision 1.1.2.26
  diff -u -r1.1.2.25 -r1.1.2.26
  --- Grammar.java	2000/11/09 22:14:01	1.1.2.25
  +++ Grammar.java	2000/12/28 09:41:18	1.1.2.26
  @@ -73,821 +73,791 @@
   import org.apache.xerces.impl.validation.models.MixedContentModel;
   import org.apache.xerces.impl.validation.models.SimpleContentModel;
   
  -
   /**
  - * @author Stubs generated by DesignDoc on Wed Jun 07 11:58:44 PDT 2000
  + * A generic grammar for use in validating XML documents. The Grammar
  + * object stores the validation information in a compiled form. Specific
  + * subclasses extend this class and "populate" the grammar by compiling 
  + * the specific syntax (DTD, Schema, etc) into the data structures used
  + * by this object.
  + * <p>
  + * <strong>Note:</strong> The Grammar object is not useful as a generic 
  + * grammar access or query object. In other words, you cannot round-trip 
  + * specific grammar syntaxes with the compiled grammar information in 
  + * the Grammar object. You <em>can</em> create equivalent validation
  + * rules in your choice of grammar syntax but there is no guarantee that
  + * the input and output will be the same.
  + *
    * @author Stubs generated by DesignDoc on Mon Sep 11 11:10:57 PDT 2000
  - * @author Jeffrey Rodriguez, ibm
  - * @author Eric Ye, ibm
  + * @author Jeffrey Rodriguez, IBM
  + * @author Eric Ye, IBM
  + * @author Andy Clark, IBM
    *
  - * @version $Id: Grammar.java,v 1.1.2.25 2000/11/09 22:14:01 ericye Exp $
  + * @version $Id: Grammar.java,v 1.1.2.26 2000/12/28 09:41:18 andyc Exp $
    */
   public class Grammar {
   
  -   //
  -   // Constants
  -   //
  -
  -   private static final int CHUNK_SHIFT = 8; // 2^8 = 256
  -   private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
  -   private static final int CHUNK_MASK = CHUNK_SIZE - 1;
  -   private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k
  -
  -   private static final short LIST_FLAG = 0x80;
  -   private static final short LIST_MASK = ~LIST_FLAG;
  -
  -   //
  -   // Data
  -   //
  -
  -   /** fTargetNamespace */
  -   protected String fTargetNamespace;
  -
  -   // element decl tables
  -
  -   private int fElementDeclCount = 0;
  -   private String fElementDeclName[][] = new String[INITIAL_CHUNK_COUNT][];
  -   private short fElementDeclType[][] = new short[INITIAL_CHUNK_COUNT][];
  -   private DatatypeValidator fElementDeclDatatypeValidator[][] = new DatatypeValidator[INITIAL_CHUNK_COUNT][];
  -   private ContentModelValidator fElementDeclContentModelValidator[][] = new ContentModelValidator[INITIAL_CHUNK_COUNT][];
  -   private int fElementDeclContentSpecIndex[][] = new int[INITIAL_CHUNK_COUNT][];
  -   private int fElementDeclFirstAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
  -   private int fElementDeclLastAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
  -   private String fElementDeclDefaultValue[][] = new String[INITIAL_CHUNK_COUNT][];
  -   private short   fElementDeclDefaultType[][] = new short[INITIAL_CHUNK_COUNT][];
  -
  -   // attribute decl tables
  -
  -   private int fAttributeDeclCount = 0 ;
  -   private QName fAttributeDeclName[][] = new QName[INITIAL_CHUNK_COUNT][];
  -   private short   fAttributeDeclType[][] = new short[INITIAL_CHUNK_COUNT][];
  -   private String[]   fAttributeDeclEnumeration[][] = new String[INITIAL_CHUNK_COUNT][][];
  -   private short   fAttributeDeclDefaultType[][] = new short[INITIAL_CHUNK_COUNT][];
  -   private DatatypeValidator fAttributeDeclDatatypeValidator[][] = new DatatypeValidator[INITIAL_CHUNK_COUNT][];
  -   private String fAttributeDeclDefaultValue[][] = new String[INITIAL_CHUNK_COUNT][];
  -   private int fAttributeDeclNextAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
  -
  -   // content spec tables, 
  -
  -   // here saves the content spec binary trees for element decls, 
  -   // each element with a content model will hold a pointer which is 
  -   // the index of the head node of the content spec tree. 
  -
  -   private int fContentSpecCount = 0 ;
  -   private short fContentSpecType[][] = new short[INITIAL_CHUNK_COUNT][];
  -   private Object fContentSpecValue[][] = new Object[INITIAL_CHUNK_COUNT][];
  -   private Object fContentSpecOtherValue[][] = new Object[INITIAL_CHUNK_COUNT][];
  -
  -   // Entities Tables1
  -   private int fEntityCount = 0;
  -   private String fEntityName[][] = new String[INITIAL_CHUNK_COUNT][];
  -   private String[][] fEntityValue = new String[INITIAL_CHUNK_COUNT][];
  -   private String[][] fEntityPublicId = new String[INITIAL_CHUNK_COUNT][];
  -   private String[][] fEntitySystemId = new String[INITIAL_CHUNK_COUNT][];
  -   private String[][] fEntityBaseSystemId = new String[INITIAL_CHUNK_COUNT][];
  -   private String[][] fEntityNotation = new String[INITIAL_CHUNK_COUNT][];
  -   private byte[][] fEntityIsPE = new byte[INITIAL_CHUNK_COUNT][];
  -   private byte[][] fEntityInExternal = new byte[INITIAL_CHUNK_COUNT][];
  -
  -   //Notation Tables
  -   private int fNotationCount = 0;
  -   private String fNotationName[][] = new String[INITIAL_CHUNK_COUNT][];
  -   private String[][] fNotationPublicId = new String[INITIAL_CHUNK_COUNT][];
  -   private String[][] fNotationSystemId = new String[INITIAL_CHUNK_COUNT][];
  -
  -
  -   // scope mapping tables
  -   private Hash1int2stringTable fScopeElementUriLocalpartHash = new Hash1int2stringTable();
  -
  -   private QName fQName1 = new QName();
  -   private QName fQName2 = new QName();
  -
  -   //
  -   // Constructors
  -   //
  -
  -   /**
  -    * 
  -    */
  -   public Grammar() {
  -   }
  +    //
  +    // Constants
  +    //
  +
  +    /** Chunk shift (8). */
  +    private static final int CHUNK_SHIFT = 8; // 2^8 = 256
  +
  +    /** Chunk size (1 << CHUNK_SHIFT). */
  +    private static final int CHUNK_SIZE = 1 << CHUNK_SHIFT;
  +
  +    /** Chunk mask (CHUNK_SIZE - 1). */
  +    private static final int CHUNK_MASK = CHUNK_SIZE - 1;
  +
  +    /** Initial chunk count (). */
  +    private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k
  +
  +    /** List flag (0x80). */
  +    private static final short LIST_FLAG = 0x80;
  +
  +    /** List mask (~LIST_FLAG). */
  +    private static final short LIST_MASK = ~LIST_FLAG;
  +
  +    //
  +    // Data
  +    //
  +
  +    /** Target namespace of grammar. */
  +    private String fTargetNamespace;
  +
  +    // element declarations
  +
  +    /** Number of element declarations. */
  +    private int fElementDeclCount = 0;
  +
  +    /** Element declaration name. */
  +    private QName fElementDeclName[][] = new QName[INITIAL_CHUNK_COUNT][];
  +
  +    /** 
  +     * Element declaration type. 
  +     * @see XMLElementDecl
  +     */
  +    private short fElementDeclType[][] = new short[INITIAL_CHUNK_COUNT][];
  +
  +    /** 
  +     * Element declaration default value. This value is used when
  +     * the element is of simple type.
  +     */
  +    private String fElementDeclDefaultValue[][] = new String[INITIAL_CHUNK_COUNT][];
  +
  +    /** 
  +     * Element declaration default type. This value is used when
  +     * the element is of simple type.
  +     */
  +    private short   fElementDeclDefaultType[][] = new short[INITIAL_CHUNK_COUNT][];
  +
  +    /** 
  +     * Element declaration datatype validator. This value is used when
  +     * the element is of simple type. 
  +     */
  +    private DatatypeValidator fElementDeclDatatypeValidator[][] = new DatatypeValidator[INITIAL_CHUNK_COUNT][];
  +
  +    /** 
  +     * Element declaration content spec index. This index value is used
  +     * to refer to the content spec information tables.
  +     */
  +    private int fElementDeclContentSpecIndex[][] = new int[INITIAL_CHUNK_COUNT][];
  +
  +    /** 
  +     * Element declaration content model validator. This validator is
  +     * constructed from the content spec nodes.
  +     */
  +    private ContentModelValidator fElementDeclContentModelValidator[][] = new ContentModelValidator[INITIAL_CHUNK_COUNT][];
  +
  +    /** First attribute declaration of an element declaration. */
  +    private int fElementDeclFirstAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
  +
  +    /** Last attribute declaration of an element declaration. */
  +    private int fElementDeclLastAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
  +
  +    // attribute declarations
  +
  +    /** Number of attribute declarations. */
  +    private int fAttributeDeclCount = 0 ;
  +
  +    /** Attribute declaration name. */
  +    private QName fAttributeDeclName[][] = new QName[INITIAL_CHUNK_COUNT][];
  +
  +    /** 
  +     * Attribute declaration type.
  +     * @see XMLAttributeDecl
  +     */
  +    private short fAttributeDeclType[][] = new short[INITIAL_CHUNK_COUNT][];
  +
  +    /** Attribute declaratoin enumeration values. */
  +    private String[] fAttributeDeclEnumeration[][] = new String[INITIAL_CHUNK_COUNT][][];
  +    private short fAttributeDeclDefaultType[][] = new short[INITIAL_CHUNK_COUNT][];
  +    private DatatypeValidator fAttributeDeclDatatypeValidator[][] = new DatatypeValidator[INITIAL_CHUNK_COUNT][];
  +    private String fAttributeDeclDefaultValue[][] = new String[INITIAL_CHUNK_COUNT][];
  +    private int fAttributeDeclNextAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
  +
  +    // content specs
  +
  +    // here saves the content spec binary trees for element decls, 
  +    // each element with a content model will hold a pointer which is 
  +    // the index of the head node of the content spec tree. 
  +
  +    private int fContentSpecCount = 0;
  +    private short fContentSpecType[][] = new short[INITIAL_CHUNK_COUNT][];
  +    private Object fContentSpecValue[][] = new Object[INITIAL_CHUNK_COUNT][];
  +    private Object fContentSpecOtherValue[][] = new Object[INITIAL_CHUNK_COUNT][];
  +
  +    // entities
  +
  +    private int fEntityCount = 0;
  +    private String fEntityName[][] = new String[INITIAL_CHUNK_COUNT][];
  +    private String[][] fEntityValue = new String[INITIAL_CHUNK_COUNT][];
  +    private String[][] fEntityPublicId = new String[INITIAL_CHUNK_COUNT][];
  +    private String[][] fEntitySystemId = new String[INITIAL_CHUNK_COUNT][];
  +    private String[][] fEntityBaseSystemId = new String[INITIAL_CHUNK_COUNT][];
  +    private String[][] fEntityNotation = new String[INITIAL_CHUNK_COUNT][];
  +    private byte[][] fEntityIsPE = new byte[INITIAL_CHUNK_COUNT][];
  +    private byte[][] fEntityInExternal = new byte[INITIAL_CHUNK_COUNT][];
  +
  +    // notations
  +
  +    private int fNotationCount = 0;
  +    private String fNotationName[][] = new String[INITIAL_CHUNK_COUNT][];
  +    private String[][] fNotationPublicId = new String[INITIAL_CHUNK_COUNT][];
  +    private String[][] fNotationSystemId = new String[INITIAL_CHUNK_COUNT][];
  +
  +    // other information
  +
  +    /** Scope mapping table. */
  +    private TupleHashtable fScopeMapping = new TupleHashtable();
  +
  +    // temporary variables
  +
  +    /** Temporary qualified name. */
  +    private QName fQName1 = new QName();
  +    
  +    /** Temporary qualified name. */
  +    private QName fQName2 = new QName();
  +
  +    // for buildSyntaxTree method
   
  -   //
  -   // Methods
  -   //
  -
  -   /**
  -    * getTargetNamespace
  -    * 
  -    * @return 
  -    */
  -   public String getTargetNamespace() {
  -      return fTargetNamespace;
  -   } // getTargetNamespace
  -
  -   /**
  -    * getFirstElementDeclIndex
  -    * 
  -    * @return 
  -    */
  -   public int getFirstElementDeclIndex() {
  -      return fElementDeclCount > 0 ? fElementDeclCount : -1;
  -   } // getFirstElementDeclIndex
  -
  -   /**
  -    * getNextElementDeclIndex
  -    * 
  -    * @param elementDeclIndex 
  -    * 
  -    * @return 
  -    */
  -   public int getNextElementDeclIndex(int elementDeclIndex) {
  -      return elementDeclIndex < fElementDeclCount - 1 
  -      ? elementDeclIndex + 1 : -1;
  -   } // getNextElementDeclIndex
  -
  -   /**
  -    * getElementDeclIndex
  -    * 
  -    * @param elementDeclName 
  -    * @param scope 
  -    * 
  -    * @return 
  -    */
  -   public int getElementDeclIndex(String elementDeclName, int scope) {
  -       return fScopeElementUriLocalpartHash.get(scope, elementDeclName, null);
  -   } // getElementDeclIndex
  +    private int fLeafCount = 0;
  +    private int fEpsilonIndex = -1;
  +    
  +    //
  +    // Constructors
  +    //
  +
  +    /** Default constructor. */
  +    public Grammar() {
  +    } // <init>()
  +
  +    //
  +    // Public methods
  +    //
  +
  +    /** Returns this grammar's target namespace. */
  +    public String getTargetNamespace() {
  +        return fTargetNamespace;
  +    } // getTargetNamespace():String
  +
  +    // REVISIT: Make this getElementDeclCount/getElementDeclAt. -Ac
  +
  +    /**
  +     * Returns the index of the first element declaration. This index
  +     * is then used to query more information about the element declaration.
  +     *
  +     * @see #getNextElementDeclIndex
  +     * @see #getElementDecl
  +     */
  +    public int getFirstElementDeclIndex() {
  +        return fElementDeclCount > 0 ? fElementDeclCount : -1;
  +    } // getFirstElementDeclIndex():int
  +
  +    /**
  +     * Returns the next index of the element declaration following the
  +     * specified element declaration.
  +     * 
  +     * @param elementDeclIndex The element declaration index.
  +     */
  +    public int getNextElementDeclIndex(int elementDeclIndex) {
  +        return elementDeclIndex < fElementDeclCount - 1 
  +             ? elementDeclIndex + 1 : -1;
  +    } // getNextElementDeclIndex(int):int
  +
  +    /**
  +     * getElementDeclIndex
  +     * 
  +     * @param elementDeclName 
  +     * @param scope 
  +     * 
  +     * @return 
  +     */
  +    public int getElementDeclIndex(String elementDeclName, int scope) {
  +        return fScopeMapping.get(scope, elementDeclName, null);
  +    } // getElementDeclIndex(String,int):int
      
  -   /**
  -    * getElementDeclIndex
  -    * 
  -    * @param elementDeclQName 
  -    * @param scope 
  -    * 
  -    * @return 
  -    */
  -   public int getElementDeclIndex(QName elementDeclQName, int scope) {
  -       return fScopeElementUriLocalpartHash.get(scope, elementDeclQName.localpart, elementDeclQName.uri);
  -   } // getElementDeclIndex
  -
  -   /**
  -    * getElementDecl
  -    * 
  -    * @param elementDeclIndex 
  -    * @param elementDecl The values of this structure are set by this call.
  -    * 
  -    * @return True if find the element, False otherwise. 
  -    */
  -   public boolean getElementDecl(int elementDeclIndex, XMLElementDecl elementDecl) {
  -      if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
  -         return false;
  -      }
  +    /**
  +     * getElementDeclIndex
  +     * 
  +     * @param elementDeclQName 
  +     * @param scope 
  +     * 
  +     * @return 
  +     */
  +    public int getElementDeclIndex(QName elementDeclQName, int scope) {
  +        return fScopeMapping.get(scope, elementDeclQName.localpart, elementDeclQName.uri);
  +    } // getElementDeclIndex(QName,int):int
   
  -      int chunk = elementDeclIndex >> CHUNK_SHIFT;
  -      int index = elementDeclIndex &  CHUNK_MASK;
  +    /**
  +     * getElementDecl
  +     * 
  +     * @param elementDeclIndex 
  +     * @param elementDecl The values of this structure are set by this call.
  +     * 
  +     * @return True if find the element, False otherwise. 
  +     */
  +    public boolean getElementDecl(int elementDeclIndex, 
  +                                  XMLElementDecl elementDecl) {
   
  -      elementDecl.name.clear();
  -      elementDecl.name.prefix = null;
  -      elementDecl.name.rawname = null;
  -
  -      elementDecl.name.localpart          = fElementDeclName[chunk][index];               
  -      elementDecl.name.uri                = fTargetNamespace; 
  -
  -      if (fElementDeclType[chunk][index] == -1) {
  -         elementDecl.type                    = -1;
  -         elementDecl.simpleType.list = false;
  -      } else {
  -         elementDecl.type            = (short) (fElementDeclType[chunk][index] & LIST_MASK);
  -         elementDecl.simpleType.list = (fElementDeclType[chunk][index] & LIST_FLAG) != 0;
  -      }
  +        if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
  +            return false;
  +        }
   
  -      /* Validators are null until we add that code */
  -      //elementDecl.contentModelValidator = fElementDeclContentModelValidator[chunk][index];
  -      if (elementDecl.type == XMLElementDecl.TYPE_CHILDREN || elementDecl.type == XMLElementDecl.TYPE_MIXED) {
  -          elementDecl.contentModelValidator = getElementContentModelValidator(elementDeclIndex);
  -      }
  -      
  +        int chunk = elementDeclIndex >> CHUNK_SHIFT;
  +        int index = elementDeclIndex &  CHUNK_MASK;
   
  -      //elementDecl.contentModelValidator = null;
  +        elementDecl.name.setValues(fElementDeclName[chunk][index]);
   
  +        if (fElementDeclType[chunk][index] == -1) {
  +            elementDecl.type                    = -1;
  +            elementDecl.simpleType.list = false;
  +        } else {
  +            elementDecl.type            = (short) (fElementDeclType[chunk][index] & LIST_MASK);
  +            elementDecl.simpleType.list = (fElementDeclType[chunk][index] & LIST_FLAG) != 0;
  +        }
   
  -      elementDecl.simpleType.datatypeValidator = fElementDeclDatatypeValidator[chunk][index];      
  -      elementDecl.simpleType.defaultType       = fElementDeclDefaultType[chunk][index];
  -      elementDecl.simpleType.defaultValue      = fElementDeclDefaultValue[chunk][index];
  +        /* Validators are null until we add that code */
  +        if (elementDecl.type == XMLElementDecl.TYPE_CHILDREN || elementDecl.type == XMLElementDecl.TYPE_MIXED) {
  +            elementDecl.contentModelValidator = getElementContentModelValidator(elementDeclIndex);
  +        }
  +              
  +        elementDecl.simpleType.datatypeValidator = fElementDeclDatatypeValidator[chunk][index];      
  +        elementDecl.simpleType.defaultType       = fElementDeclDefaultType[chunk][index];
  +        elementDecl.simpleType.defaultValue      = fElementDeclDefaultValue[chunk][index];
   
  -      return true;
  -   } // getElementDecl
  +        return true;
   
  +    } // getElementDecl(int,XMLElementDecl):boolean
   
  -   /**
  -    * getElementContentModelValidator
  -    * 
  -    * @param elementDeclIndex 
  -    * 
  -    * @return its ContentModelValidator if any.
  -    */
  -   protected ContentModelValidator getElementContentModelValidator(int elementDeclIndex) {
  -      int chunk = elementDeclIndex >> CHUNK_SHIFT;
  -      int index = elementDeclIndex & CHUNK_MASK;
  +    // REVISIT: Make this getAttributeDeclCount/getAttributeDeclAt. -Ac
   
  -      ContentModelValidator contentModel    =  fElementDeclContentModelValidator[chunk][index];
  +    /**
  +     * getFirstAttributeDeclIndex
  +     * 
  +     * @param elementDeclIndex 
  +     * 
  +     * @return int
  +     */
  +    public int getFirstAttributeDeclIndex(int elementDeclIndex) {
  +        int chunk = elementDeclIndex >> CHUNK_SHIFT;
  +        int index = elementDeclIndex &  CHUNK_MASK;
   
  -      // If we have one, just return that. Otherwise, gotta create one
  -      if (contentModel != null)
  -         return contentModel;
  +        return  fElementDeclFirstAttributeDeclIndex[chunk][index];
  +    } // getFirstAttributeDeclIndex
   
  -      int contentType = fElementDeclType[chunk][index];
  -      if (contentType == XMLElementDecl.TYPE_SIMPLE) {
  -         return null;
  -      }
  +    /**
  +     * getNextAttributeDeclIndex
  +     * 
  +     * @param attributeDeclIndex 
  +     * 
  +     * @return 
  +     */
  +    public int getNextAttributeDeclIndex(int attributeDeclIndex) {
  +        int chunk = attributeDeclIndex >> CHUNK_SHIFT;
  +        int index = attributeDeclIndex &  CHUNK_MASK;
   
  -      // Get the type of content this element has
  +        return fAttributeDeclNextAttributeDeclIndex[chunk][index];
  +    } // getNextAttributeDeclIndex
   
  +    /**
  +     * getAttributeDeclIndex
  +     * 
  +     * @param elementDeclIndex 
  +     * @param attributeDeclName 
  +     * 
  +     * @return 
  +     */
  +    public int getAttributeDeclIndex(int elementDeclIndex, String attributeDeclName) {
  +        // REVISIT: [Q] How is this supposed to be overridden efficiently by 
  +        //          a subclass if all of the data structures are private? -Ac
  +        return -1; // should be overide by sub classes
  +    }
   
  -      int contentSpecIndex = fElementDeclContentSpecIndex[chunk][index]; 
  +    /**
  +     * getAttributeDecl
  +     * 
  +     * @param attributeDeclIndex 
  +     * @param attributeDecl The values of this structure are set by this call.
  +     * 
  +     * @return 
  +     */
  +    public boolean getAttributeDecl(int attributeDeclIndex, XMLAttributeDecl attributeDecl) {
  +        if (attributeDeclIndex < 0 || attributeDeclIndex >= fAttributeDeclCount) {
  +            return false;
  +        }
  +        int chunk = attributeDeclIndex >> CHUNK_SHIFT;
  +        int index = attributeDeclIndex & CHUNK_MASK;
   
  -      /***
  -      if ( contentSpecIndex == -1 )
  -          return null;
  -      /***/
  -
  -      XMLContentSpec  contentSpec = new XMLContentSpec();
  -      getContentSpec( contentSpecIndex, contentSpec );
  -
  -      // And create the content model according to the spec type
  -
  -      if ( contentType == XMLElementDecl.TYPE_MIXED ) {
  -         //
  -         //  Just create a mixel content model object. This type of
  -         //  content model is optimized for mixed content validation.
  -         //
  -
  -         ChildrenList children = new ChildrenList();
  -         contentSpecTree(contentSpecIndex, contentSpec, children);
  -         contentModel = new MixedContentModel(children.qname,
  -                                              children.type,
  -                                              0, children.length, false, isDTD());
  -
  -      } else if (contentType == XMLElementDecl.TYPE_CHILDREN) {
  -         //  This method will create an optimal model for the complexity
  -         //  of the element's defined model. If its simple, it will create
  -         //  a SimpleContentModel object. If its a simple list, it will
  -         //  create a SimpleListContentModel object. If its complex, it
  -         //  will create a DFAContentModel object.
  -         //
  -         contentModel = createChildModel(contentSpecIndex);
  -      } else {
  -         throw new RuntimeException("Unknown content type for a element decl "
  -                                    + "in getElementContentModelValidator() in Grammar class");
  -      }
  +        attributeDecl.name.setValues(fAttributeDeclName[chunk][index]);
   
  -      // Add the new model to the content model for this element
  -      fElementDeclContentModelValidator[chunk][index] = contentModel;
  +        short attributeType;
  +        boolean isList;
   
  -      return contentModel;
  +        if (fAttributeDeclType[chunk][index] == -1) {
   
  -   }
  +            attributeType = -1;
  +            isList = false;
  +        } else {
  +            attributeType = (short) (fAttributeDeclType[chunk][index] & LIST_MASK);
  +            isList = (fAttributeDeclType[chunk][index] & LIST_FLAG) != 0;
  +        }
  +        attributeDecl.simpleType.setValues(attributeType,fAttributeDeclName[chunk][index].localpart,
  +                                           fAttributeDeclEnumeration[chunk][index],
  +                                           isList, fAttributeDeclDefaultType[chunk][index],
  +                                           fAttributeDeclDefaultValue[chunk][index], 
  +                                           fAttributeDeclDatatypeValidator[chunk][index]);
  +        return true;
   
  -   /**
  -    * getContentSpecAsString
  -    *
  -    * @param elementDeclIndex
  -    *
  -    * @ return String
  -    */
  -
  -   public String getContentSpecAsString(int elementDeclIndex ){
  -       if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
  -          return null;
  -       }
  -
  -       int chunk = elementDeclIndex >> CHUNK_SHIFT;
  -       int index = elementDeclIndex &  CHUNK_MASK;
  -
  -       int contentSpecIndex = fElementDeclContentSpecIndex[chunk][index];
  -
  -       // lookup content spec node
  -       XMLContentSpec contentSpec = new XMLContentSpec();
  -
  -       if (getContentSpec(contentSpecIndex, contentSpec)) {
  -
  -           // build string
  -           StringBuffer str = new StringBuffer();
  -           int    parentContentSpecType = contentSpec.type & 0x0f;
  -           int    nextContentSpec;
  -           switch (parentContentSpecType) {
  -               case XMLContentSpec.CONTENTSPECNODE_LEAF: {
  -                   str.append('(');
  -                   if (contentSpec.value == null && contentSpec.otherValue == null) {
  -                       str.append("#PCDATA");
  -                   }
  -                   else {
  -                       str.append(contentSpec.value);
  -                   }
  -                   str.append(')');
  -                   break;
  -               }
  -               case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: {
  -                   getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  -                   nextContentSpec = contentSpec.type;
  -
  -                   if (nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) {
  -                       str.append('(');
  -                       str.append(contentSpec.value);
  -                       str.append(')');
  -                   } else if( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE  ||
  -                           nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE  ||
  -                           nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
  -                       str.append('(' );
  -                       appendContentSpec( contentSpec, str, 
  -                                                                true, parentContentSpecType );
  -                       str.append(')');
  -
  -                   } else {
  -                       appendContentSpec( contentSpec, str, 
  -                                                                true, parentContentSpecType );
  -                   }
  -                   str.append('?');
  -                   break;
  -               }
  -               case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: {
  -                   getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  -                   nextContentSpec = contentSpec.type;
  -
  -                   if ( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) {
  -                       str.append('(');
  -                       if (contentSpec.value == null && contentSpec.otherValue == null) {
  -                           str.append("#PCDATA");
  -                       }
  -                       else if (contentSpec.otherValue != null) {
  -                           str.append("##any:uri="+contentSpec.otherValue);
  -                       }
  -                       else if (contentSpec.value == null) {
  -                           str.append("##any");
  -                       }
  -                       else {
  -                            appendContentSpec( contentSpec, str, 
  -                                                   true, parentContentSpecType );
  -                       }
  -                       str.append(')');
  -
  -                   } else if( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE  ||
  -                       nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE  ||
  -                       nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
  -                       str.append('(' );
  -                       appendContentSpec( contentSpec, str, 
  -                                                           true, parentContentSpecType );
  -                       str.append(')');
  -                   } else {
  -                       appendContentSpec( contentSpec, str, 
  -                                                               true, parentContentSpecType );
  -
  -                       //str.append(stringPool.toString(contentSpec.value));
  -                   }
  -                   str.append('*');
  -                   break;
  -               }
  -               case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: {
  -                   getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  -                   nextContentSpec = contentSpec.type;
  -
  -                   if ( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) {
  -                       str.append('(');
  -                       if (contentSpec.value == null && contentSpec.otherValue == null) {
  -                           str.append("#PCDATA");
  -                       }
  -                       else if (contentSpec.otherValue != null) {
  -                           str.append("##any:uri="+contentSpec.otherValue);
  -                       }
  -                       else if (contentSpec.value == null) {
  -                           str.append("##any");
  -                       }
  -                       else {
  -                           str.append(contentSpec.value);
  -                       }
  -                       str.append(')');
  -                   } else if( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE  ||
  -                       nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE  ||
  -                       nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
  -                       str.append('(' );
  -                       appendContentSpec( contentSpec, str, 
  -                                                     true, parentContentSpecType );
  -                       str.append(')');
  -                   } else {
  -                       appendContentSpec( contentSpec, str,
  -                                                           true, parentContentSpecType);
  -                   }
  -                   str.append('+');
  -                   break;
  -               }
  -               case XMLContentSpec.CONTENTSPECNODE_CHOICE:
  -               case XMLContentSpec.CONTENTSPECNODE_SEQ: {
  -                   appendContentSpec(
  -                                     contentSpec, str, true, parentContentSpecType );
  -                   break;
  -               }
  -               case XMLContentSpec.CONTENTSPECNODE_ANY: {
  -                   str.append("##any");
  -                   if (contentSpec.otherValue != null) {
  -                       str.append(":uri=");
  -                       str.append(contentSpec.otherValue);
  -                   }
  -                   break;
  -               }
  -               case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER: {
  -                   str.append("##other:uri=");
  -                   str.append(contentSpec.otherValue);
  -                   break;
  -               }
  -               case XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL: {
  -                   str.append("##local");
  -                   break;
  -               }
  -               default: {
  -                   str.append("???");
  -               }
  -
  -           } // switch type
  -
  -           // return string
  -           return str.toString();
  -       }
  +    } // getAttributeDecl
   
  -       // not found
  -       return null;
  +    /**
  +     * getFirstEntityDeclIndex
  +     * 
  +     * @return 
  +     */
  +    public int getFirstEntityDeclIndex() {
  +        throw new RuntimeException("implement Grammar#getFirstEntityDeclIndex():int");
  +    } // getFirstEntityDeclIndex
   
  -   }
  +    /**
  +     * getNextEntityDeclIndex
  +     * 
  +     * @param elementDeclIndex 
  +     * 
  +     * @return 
  +     */
  +    public int getNextEntityDeclIndex(int elementDeclIndex) {
  +        throw new RuntimeException("implement Grammar#getNextEntityDeclIndex(int):int");
  +    } // getNextEntityDeclIndex
   
  -   private void appendContentSpec(XMLContentSpec contentSpec, 
  -                                         StringBuffer str, 
  -                                         boolean parens,
  -                                         int     parentContentSpecType ) {
  -
  -       int thisContentSpec = contentSpec.type & 0x0f;
  -       switch (thisContentSpec) {
  -           case XMLContentSpec.CONTENTSPECNODE_LEAF: {
  -               if (contentSpec.value == null && contentSpec.otherValue == null) {
  -                   str.append("#PCDATA");
  -               }
  -               else if (contentSpec.value == null && contentSpec.otherValue != null) {
  -                   str.append("##any:uri="+contentSpec.otherValue);
  -               }
  -               else if (contentSpec.value == null) {
  -                   str.append("##any");
  -               }
  -               else {
  -                   str.append(contentSpec.value);
  -               }
  -               break;
  -           }
  -           case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: {
  -               if( parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE  ||
  -                   parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
  -                   parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
  -                   getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  -                   str.append('(');
  -                   appendContentSpec(contentSpec, str, true, thisContentSpec );
  -                   str.append(')');
  -
  -               } 
  -               else {
  -                   getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  -                   appendContentSpec( contentSpec, str, true, thisContentSpec );
  -               }
  -               str.append('?');
  -               break;
  -           }
  -           case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: {
  -               if( parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE ||
  -                  parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
  -                  parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
  -                  getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  -                  str.append('(');
  -                  appendContentSpec(contentSpec, str, true, thisContentSpec);
  -                  str.append(')' );
  -               } else{
  -                   getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  -                   appendContentSpec(contentSpec, str, true, thisContentSpec);
  -               }
  -               str.append('*');
  -               break;
  -           }
  -           case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: {
  -               if( parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE   ||
  -                   parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE  ||
  -                   parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
  -
  -                 str.append('(');
  -                 getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  -                 appendContentSpec(contentSpec, str, true, thisContentSpec);
  -                 str.append(')' );
  -               } else {
  -                   getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  -                   appendContentSpec(contentSpec, str, true, thisContentSpec);
  -               }
  -               str.append('+');
  -               break;
  -           }
  -           case XMLContentSpec.CONTENTSPECNODE_CHOICE:
  -           case XMLContentSpec.CONTENTSPECNODE_SEQ: {
  -               if (parens) {
  -                   str.append('(');
  -               }
  -               int type = contentSpec.type;
  -               int otherValue = ((int[])contentSpec.otherValue)[0];
  -               getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  -               appendContentSpec(contentSpec, str, contentSpec.type != type, thisContentSpec);
  -               if (type == XMLContentSpec.CONTENTSPECNODE_CHOICE) {
  -                   str.append('|');
  -               }
  -               else {
  -                   str.append(',');
  -               }
  -               // REVISIT: Do we need this? -Ac
  -               //if (++index == CHUNK_SIZE) {
  -                 //  chunk++;
  -                 //  index = 0;
  -               // }
  -               getContentSpec(otherValue, contentSpec);
  -               appendContentSpec(contentSpec, str, true, thisContentSpec);
  -               if (parens) {
  -                   str.append(')');
  -               }
  -               break;
  -           }
  -           case XMLContentSpec.CONTENTSPECNODE_ANY: {
  -               str.append("##any");
  -               if (contentSpec.otherValue != null) {
  -                   str.append(":uri=");
  -                   str.append(contentSpec.otherValue);
  -               }
  -               break;
  -           }
  -           case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER: {
  -               str.append("##other:uri=");
  -               str.append(contentSpec.otherValue);
  -               break;
  -           }
  -           case XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL: {
  -               str.append("##local");
  -               break;
  -           }
  -           default: {
  -               str.append("???");
  -               break;
  -           }
  -
  -       } // switch type
  -
  -   } // appendContentSpec(XMLContentSpec.Provider,StringPool,XMLContentSpec,StringBuffer,boolean)
  -
  -   /**
  -    * getFirstAttributeDeclIndex
  -    * 
  -    * @param elementDeclIndex 
  -    * 
  -    * @return int
  -    */
  -   public int getFirstAttributeDeclIndex(int elementDeclIndex) {
  -      int chunk = elementDeclIndex >> CHUNK_SHIFT;
  -      int index = elementDeclIndex &  CHUNK_MASK;
  +    /**
  +     * getEntityDeclIndex
  +     * 
  +     * @param entityDeclName 
  +     * 
  +     * @return 
  +     */
  +    public int getEntityDeclIndex(String entityDeclName) {
  +        if (entityDeclName == null) {
  +            return -1;
  +        }
  +        for (int i=0; i<fEntityCount; i++) {
  +            int chunk = i >> CHUNK_SHIFT;
  +            int index = i & CHUNK_MASK;
  +            if ( fEntityName[chunk][index] == entityDeclName || entityDeclName.equals(fEntityName[chunk][index]) ) {
  +                return i;
  +            }
  +        }
  +    
  +        return -1;
  +    } // getEntityDeclIndex
   
  -      return  fElementDeclFirstAttributeDeclIndex[chunk][index];
  -   } // getFirstAttributeDeclIndex
  +    /**
  +     * getEntityDecl
  +     * 
  +     * @param entityDeclIndex 
  +     * @param entityDecl 
  +     * 
  +     * @return 
  +     */
  +    public boolean getEntityDecl(int entityDeclIndex, XMLEntityDecl entityDecl) {
  +        if (entityDeclIndex < 0 || entityDeclIndex >= fEntityCount) {
  +            return false;
  +        }
  +        int chunk = entityDeclIndex >> CHUNK_SHIFT;
  +        int index = entityDeclIndex & CHUNK_MASK;
   
  -   /**
  -    * getNextAttributeDeclIndex
  -    * 
  -    * @param attributeDeclIndex 
  -    * 
  -    * @return 
  -    */
  -   public int getNextAttributeDeclIndex(int attributeDeclIndex) {
  -      int chunk = attributeDeclIndex >> CHUNK_SHIFT;
  -      int index = attributeDeclIndex &  CHUNK_MASK;
  -
  -      return fAttributeDeclNextAttributeDeclIndex[chunk][index];
  -   } // getNextAttributeDeclIndex
  -
  -   /**
  -    * getAttributeDeclIndex
  -    * 
  -    * @param elementDeclIndex 
  -    * @param attributeDeclName 
  -    * 
  -    * @return 
  -    */
  -   public int getAttributeDeclIndex(int elementDeclIndex, String attributeDeclName) {
  -       return -1; // should be overide by sub classes
  -   }
  +        entityDecl.setValues(fEntityName[chunk][index],
  +                             fEntityPublicId[chunk][index],
  +                             fEntitySystemId[chunk][index],
  +                             fEntityBaseSystemId[chunk][index],
  +                             fEntityNotation[chunk][index],
  +                             fEntityIsPE[chunk][index] == 0 ? false : true ,
  +                             fEntityInExternal[chunk][index] == 0 ? false : true );
   
  -   /**
  -    * getAttributeDecl
  -    * 
  -    * @param attributeDeclIndex 
  -    * @param attributeDecl The values of this structure are set by this call.
  -    * 
  -    * @return 
  -    */
  -   public boolean getAttributeDecl(int attributeDeclIndex, XMLAttributeDecl attributeDecl) {
  -      if (attributeDeclIndex < 0 || attributeDeclIndex >= fAttributeDeclCount) {
  -         return false;
  -      }
  -      int chunk = attributeDeclIndex >> CHUNK_SHIFT;
  -      int index = attributeDeclIndex & CHUNK_MASK;
  +        return true;
  +    } // getEntityDecl
   
  -      QName temp = fAttributeDeclName[chunk][index];
  +    /**
  +     * getFirstNotationDeclIndex
  +     * 
  +     * @return 
  +     */
  +    public int getFirstNotationDeclIndex() {
  +        throw new RuntimeException("implement Grammar#getFirstNotationDeclIndex():int");
  +    } // getFirstNotationDeclIndex
   
  -      attributeDecl.name.prefix = temp.prefix;
  -      attributeDecl.name.localpart =  temp.localpart;
  -      attributeDecl.name.rawname = temp.rawname;
  -      attributeDecl.name.uri = temp.uri;
  +    /**
  +     * getNextNotationDeclIndex
  +     * 
  +     * @param elementDeclIndex 
  +     * 
  +     * @return 
  +     */
  +    public int getNextNotationDeclIndex(int elementDeclIndex) {
  +        throw new RuntimeException("implement Grammar#getNextNotationDeclIndex(int):int");
  +    } // getNextNotationDeclIndex
   
  +    /**
  +     * getNotationDeclIndex
  +     * 
  +     * @param notationDeclName 
  +     * 
  +     * @return the index if found a notation with the name, otherwise -1.
  +     */
  +    public int getNotationDeclIndex(String notationDeclName) {
  +        if (notationDeclName == null) {
  +            return -1;
  +        }
  +        for (int i=0; i<fNotationCount; i++) {
  +            int chunk = i >> CHUNK_SHIFT;
  +            int index = i & CHUNK_MASK;
  +            if ( fNotationName[chunk][index] == notationDeclName || notationDeclName.equals(fNotationName[chunk][index]) ) {
  +                return i;
  +            }
  +        }
   
  -      short attributeType;
  -      boolean isList;
  +        return -1;
  +    } // getNotationDeclIndex
   
  -      if (fAttributeDeclType[chunk][index] == -1) {
  +    /**
  +     * getNotationDecl
  +     * 
  +     * @param notationDeclIndex 
  +     * @param notationDecl 
  +     * 
  +     * @return 
  +     */
  +    public boolean getNotationDecl(int notationDeclIndex, XMLNotationDecl notationDecl) {
  +        if (notationDeclIndex < 0 || notationDeclIndex >= fNotationCount) {
  +            return false;
  +        }
  +        int chunk = notationDeclIndex >> CHUNK_SHIFT;
  +        int index = notationDeclIndex & CHUNK_MASK;
   
  -         attributeType = -1;
  -         isList = false;
  -      } else {
  -         attributeType = (short) (fAttributeDeclType[chunk][index] & LIST_MASK);
  -         isList = (fAttributeDeclType[chunk][index] & LIST_FLAG) != 0;
  -      }
  -      attributeDecl.simpleType.setValues(attributeType,fAttributeDeclName[chunk][index].localpart,
  -                                         fAttributeDeclEnumeration[chunk][index],
  -                                         isList, fAttributeDeclDefaultType[chunk][index],
  -                                         fAttributeDeclDefaultValue[chunk][index], 
  -                                         fAttributeDeclDatatypeValidator[chunk][index]);
  -      return true;
  -   } // getAttributeDecl
  +        notationDecl.setValues(fNotationName[chunk][index], 
  +                               fNotationPublicId[chunk][index],
  +                               fNotationSystemId[chunk][index]);
   
  -   /**
  -    * getFirstEntityDeclIndex
  -    * 
  -    * @return 
  -    */
  -   public int getFirstEntityDeclIndex() {
  -      throw new RuntimeException("implement Grammar#getFirstEntityDeclIndex():int");
  -   } // getFirstEntityDeclIndex
  -
  -   /**
  -    * getNextEntityDeclIndex
  -    * 
  -    * @param elementDeclIndex 
  -    * 
  -    * @return 
  -    */
  -   public int getNextEntityDeclIndex(int elementDeclIndex) {
  -      throw new RuntimeException("implement Grammar#getNextEntityDeclIndex(int):int");
  -   } // getNextEntityDeclIndex
  -
  -   /**
  -    * getEntityDeclIndex
  -    * 
  -    * @param entityDeclName 
  -    * 
  -    * @return 
  -    */
  -   public int getEntityDeclIndex(String entityDeclName) {
  -       if (entityDeclName == null) {
  -           return -1;
  -       }
  -       for (int i=0; i<fEntityCount; i++) {
  -           int chunk = i >> CHUNK_SHIFT;
  -           int index = i & CHUNK_MASK;
  -           if ( fEntityName[chunk][index] == entityDeclName || entityDeclName.equals(fEntityName[chunk][index]) ) {
  -               return i;
  -           }
  -       }
  -
  -       return -1;
  -   } // getEntityDeclIndex
  -
  -   /**
  -    * getEntityDecl
  -    * 
  -    * @param entityDeclIndex 
  -    * @param entityDecl 
  -    * 
  -    * @return 
  -    */
  -   public boolean getEntityDecl(int entityDeclIndex, XMLEntityDecl entityDecl) {
  -       if (entityDeclIndex < 0 || entityDeclIndex >= fEntityCount) {
  -           return false;
  -       }
  -       int chunk = entityDeclIndex >> CHUNK_SHIFT;
  -       int index = entityDeclIndex & CHUNK_MASK;
  +        return true;
   
  -       entityDecl.setValues(fEntityName[chunk][index],
  -                            fEntityPublicId[chunk][index],
  -                            fEntitySystemId[chunk][index],
  -                            fEntityBaseSystemId[chunk][index],
  -                            fEntityNotation[chunk][index],
  -                            fEntityIsPE[chunk][index] == 0 ? false : true ,
  -                            fEntityInExternal[chunk][index] == 0 ? false : true );
  -
  -       return true;
  -   } // getEntityDecl
  -
  -   /**
  -    * getFirstNotationDeclIndex
  -    * 
  -    * @return 
  -    */
  -   public int getFirstNotationDeclIndex() {
  -      throw new RuntimeException("implement Grammar#getFirstNotationDeclIndex():int");
  -   } // getFirstNotationDeclIndex
  -
  -   /**
  -    * getNextNotationDeclIndex
  -    * 
  -    * @param elementDeclIndex 
  -    * 
  -    * @return 
  -    */
  -   public int getNextNotationDeclIndex(int elementDeclIndex) {
  -      throw new RuntimeException("implement Grammar#getNextNotationDeclIndex(int):int");
  -   } // getNextNotationDeclIndex
  -
  -   /**
  -    * getNotationDeclIndex
  -    * 
  -    * @param notationDeclName 
  -    * 
  -    * @return the index if found a notation with the name, otherwise -1.
  -    */
  -   public int getNotationDeclIndex(String notationDeclName) {
  -       if (notationDeclName == null) {
  -           return -1;
  -       }
  -       for (int i=0; i<fNotationCount; i++) {
  -           int chunk = i >> CHUNK_SHIFT;
  -           int index = i & CHUNK_MASK;
  -           if ( fNotationName[chunk][index] == notationDeclName || notationDeclName.equals(fNotationName[chunk][index]) ) {
  -               return i;
  -           }
  -       }
  -
  -       return -1;
  -   } // getNotationDeclIndex
  -
  -   /**
  -    * getNotationDecl
  -    * 
  -    * @param notationDeclIndex 
  -    * @param notationDecl 
  -    * 
  -    * @return 
  -    */
  -   public boolean getNotationDecl(int notationDeclIndex, XMLNotationDecl notationDecl) {
  -       if (notationDeclIndex < 0 || notationDeclIndex >= fNotationCount) {
  -           return false;
  -       }
  -       int chunk = notationDeclIndex >> CHUNK_SHIFT;
  -       int index = notationDeclIndex & CHUNK_MASK;
  +    } // getNotationDecl
   
  -       notationDecl.setValues(fNotationName[chunk][index], 
  -                              fNotationPublicId[chunk][index],
  -                              fNotationSystemId[chunk][index]);
  -
  -       return true;
  -
  -   } // getNotationDecl
  -
  -
  -   /**
  -    * getContentSpec
  -    * 
  -    * @param contentSpecIndex 
  -    * @param contentSpec
  -    * 
  -    * @return true if find the requested contentSpec node, false otherwise
  -    */
  -   public boolean getContentSpec(int contentSpecIndex, XMLContentSpec contentSpec) {
  -      if (contentSpecIndex < 0 || contentSpecIndex >= fContentSpecCount )
  -         return false;
  -
  -      int chunk = contentSpecIndex >> CHUNK_SHIFT;
  -      int index = contentSpecIndex & CHUNK_MASK;
  -
  -      contentSpec.type       = fContentSpecType[chunk][index];
  -      contentSpec.value      = fContentSpecValue[chunk][index];
  -      contentSpec.otherValue = fContentSpecOtherValue[chunk][index];
  -      return true;
  -   }
  +    /**
  +     * getContentSpec
  +     * 
  +     * @param contentSpecIndex 
  +     * @param contentSpec
  +     * 
  +     * @return true if find the requested contentSpec node, false otherwise
  +     */
  +    public boolean getContentSpec(int contentSpecIndex, XMLContentSpec contentSpec) {
  +        if (contentSpecIndex < 0 || contentSpecIndex >= fContentSpecCount )
  +            return false;
  +
  +        int chunk = contentSpecIndex >> CHUNK_SHIFT;
  +        int index = contentSpecIndex & CHUNK_MASK;
  +
  +        contentSpec.type       = fContentSpecType[chunk][index];
  +        contentSpec.value      = fContentSpecValue[chunk][index];
  +        contentSpec.otherValue = fContentSpecOtherValue[chunk][index];
  +        return true;
  +    }
  +
  +    /**
  +     * getContentSpecAsString
  +     *
  +     * @param elementDeclIndex
  +     *
  +     * @ return String
  +     */
  +    public String getContentSpecAsString(int elementDeclIndex){
  +
  +        if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
  +            return null;
  +        }
  +
  +        int chunk = elementDeclIndex >> CHUNK_SHIFT;
  +        int index = elementDeclIndex &  CHUNK_MASK;
  +
  +        int contentSpecIndex = fElementDeclContentSpecIndex[chunk][index];
  +
  +        // lookup content spec node
  +        XMLContentSpec contentSpec = new XMLContentSpec();
  +
  +        if (getContentSpec(contentSpecIndex, contentSpec)) {
  +
  +            // build string
  +            StringBuffer str = new StringBuffer();
  +            int    parentContentSpecType = contentSpec.type & 0x0f;
  +            int    nextContentSpec;
  +            switch (parentContentSpecType) {
  +                case XMLContentSpec.CONTENTSPECNODE_LEAF: {
  +                    str.append('(');
  +                    if (contentSpec.value == null && contentSpec.otherValue == null) {
  +                        str.append("#PCDATA");
  +                    }
  +                    else {
  +                        str.append(contentSpec.value);
  +                    }
  +                    str.append(')');
  +                    break;
  +                }
  +                case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: {
  +                    getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  +                    nextContentSpec = contentSpec.type;
  +
  +                    if (nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) {
  +                        str.append('(');
  +                        str.append(contentSpec.value);
  +                        str.append(')');
  +                    } else if( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE  ||
  +                        nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE  ||
  +                        nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
  +                        str.append('(' );
  +                        appendContentSpec(contentSpec, str, 
  +                                          true, parentContentSpecType );
  +                        str.append(')');
  +                    } else {
  +                        appendContentSpec(contentSpec, str, 
  +                                          true, parentContentSpecType );
  +                    }
  +                    str.append('?');
  +                    break;
  +                }
  +                case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: {
  +                    getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  +                    nextContentSpec = contentSpec.type;
  +
  +                    if ( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) {
  +                        str.append('(');
  +                        if (contentSpec.value == null && contentSpec.otherValue == null) {
  +                            str.append("#PCDATA");
  +                        }
  +                        else if (contentSpec.otherValue != null) {
  +                            str.append("##any:uri="+contentSpec.otherValue);
  +                        }
  +                        else if (contentSpec.value == null) {
  +                            str.append("##any");
  +                        }
  +                        else {
  +                            appendContentSpec(contentSpec, str, 
  +                                              true, parentContentSpecType );
  +                        }
  +                        str.append(')');
  +                    } else if( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE  ||
  +                        nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE  ||
  +                        nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
  +                        str.append('(' );
  +                        appendContentSpec(contentSpec, str, 
  +                                          true, parentContentSpecType );
  +                        str.append(')');
  +                    } else {
  +                        appendContentSpec(contentSpec, str, 
  +                                          true, parentContentSpecType );
  +                    }
  +                    str.append('*');
  +                    break;
  +                }
  +                case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: {
  +                    getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  +                    nextContentSpec = contentSpec.type;
  +
  +                    if ( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_LEAF) {
  +                        str.append('(');
  +                        if (contentSpec.value == null && contentSpec.otherValue == null) {
  +                            str.append("#PCDATA");
  +                        }
  +                        else if (contentSpec.otherValue != null) {
  +                            str.append("##any:uri="+contentSpec.otherValue);
  +                        }
  +                        else if (contentSpec.value == null) {
  +                            str.append("##any");
  +                        }
  +                        else {
  +                            str.append(contentSpec.value);
  +                        }
  +                        str.append(')');
  +                    } else if( nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE  ||
  +                        nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE  ||
  +                        nextContentSpec == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
  +                        str.append('(' );
  +                        appendContentSpec(contentSpec, str, 
  +                                          true, parentContentSpecType );
  +                        str.append(')');
  +                    } else {
  +                        appendContentSpec(contentSpec, str,
  +                                          true, parentContentSpecType);
  +                    }
  +                    str.append('+');
  +                    break;
  +                }
  +                case XMLContentSpec.CONTENTSPECNODE_CHOICE:
  +                case XMLContentSpec.CONTENTSPECNODE_SEQ: {
  +                    appendContentSpec(contentSpec, str, 
  +                                      true, parentContentSpecType );
  +                    break;
  +                }
  +                case XMLContentSpec.CONTENTSPECNODE_ANY: {
  +                    str.append("##any");
  +                    if (contentSpec.otherValue != null) {
  +                        str.append(":uri=");
  +                        str.append(contentSpec.otherValue);
  +                    }
  +                    break;
  +                }
  +                case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER: {
  +                    str.append("##other:uri=");
  +                    str.append(contentSpec.otherValue);
  +                    break;
  +                }
  +                case XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL: {
  +                    str.append("##local");
  +                    break;
  +                }
  +                default: {
  +                    str.append("???");
  +                }
  +
  +            } // switch type
  +
  +            // return string
  +            return str.toString();
  +        }
  +
  +        // not found
  +        return null;
  +
  +    } // getContentSpecAsString(int):String
  +
  +    // debugging
  +
  +    public void printElements(  ) {
  +        int elementDeclIndex = 0;
  +        XMLElementDecl elementDecl = new XMLElementDecl();
  +        elementDecl.simpleType     = new XMLSimpleType();
  +        while (getElementDecl(elementDeclIndex++, elementDecl)) {
  +
  +            System.out.println("element decl: "+elementDecl.name+
  +                               ", "+ elementDecl.name.rawname  );
  +
  +            //                   ", "+ elementDecl.contentModelValidator.toString());
  +        }
  +    }
  +
  +    public void printAttributes(int elementDeclIndex) {
  +        int attributeDeclIndex = getFirstAttributeDeclIndex(elementDeclIndex);
  +        System.out.print(elementDeclIndex);
  +        System.out.print(" [");
  +        while (attributeDeclIndex != -1) {
  +            System.out.print(' ');
  +            System.out.print(attributeDeclIndex);
  +            printAttribute(attributeDeclIndex);
  +            attributeDeclIndex = getNextAttributeDeclIndex(attributeDeclIndex);
  +            if (attributeDeclIndex != -1) {
  +                System.out.print(",");
  +            }
  +        }
  +        System.out.println(" ]");
  +    }
  +
  +    //
  +    // Protected methods
  +    //
  +
  +    /**
  +     * getElementContentModelValidator
  +     * 
  +     * @param elementDeclIndex 
  +     * 
  +     * @return its ContentModelValidator if any.
  +     */
  +    protected ContentModelValidator getElementContentModelValidator(int elementDeclIndex) {
  +
  +        int chunk = elementDeclIndex >> CHUNK_SHIFT;
  +        int index = elementDeclIndex & CHUNK_MASK;
  +
  +        ContentModelValidator contentModel    =  fElementDeclContentModelValidator[chunk][index];
  +
  +        // If we have one, just return that. Otherwise, gotta create one
  +        if (contentModel != null) {
  +            return contentModel;
  +        }
  +
  +        int contentType = fElementDeclType[chunk][index];
  +        if (contentType == XMLElementDecl.TYPE_SIMPLE) {
  +            return null;
  +        }
  +
  +        // Get the type of content this element has
  +        int contentSpecIndex = fElementDeclContentSpecIndex[chunk][index]; 
  +
  +        /***
  +        if ( contentSpecIndex == -1 )
  +            return null;
  +        /***/
  +
  +        XMLContentSpec  contentSpec = new XMLContentSpec();
  +        getContentSpec( contentSpecIndex, contentSpec );
  +
  +        // And create the content model according to the spec type
  +        if ( contentType == XMLElementDecl.TYPE_MIXED ) {
  +            //
  +            //  Just create a mixel content model object. This type of
  +            //  content model is optimized for mixed content validation.
  +            //
  +            ChildrenList children = new ChildrenList();
  +            contentSpecTree(contentSpecIndex, contentSpec, children);
  +            contentModel = new MixedContentModel(children.qname,
  +                                                 children.type,
  +                                                 0, children.length, 
  +                                                 false, isDTD());
  +        } else if (contentType == XMLElementDecl.TYPE_CHILDREN) {
  +            //  This method will create an optimal model for the complexity
  +            //  of the element's defined model. If its simple, it will create
  +            //  a SimpleContentModel object. If its a simple list, it will
  +            //  create a SimpleListContentModel object. If its complex, it
  +            //  will create a DFAContentModel object.
  +            //
  +            contentModel = createChildModel(contentSpecIndex);
  +        } else {
  +            throw new RuntimeException("Unknown content type for a element decl "
  +                                     + "in getElementContentModelValidator() in Grammar class");
  +        }
  +
  +        // Add the new model to the content model for this element
  +        fElementDeclContentModelValidator[chunk][index] = contentModel;
   
  -   //
  -   // Protected methods
  -   //
  +        return contentModel;
   
  +    } // getElementContentModelValidator(int):ContentModelValidator
   
      protected int createElementDecl() {
         int chunk = fElementDeclCount >> CHUNK_SHIFT;
         int index = fElementDeclCount & CHUNK_MASK;
         ensureElementDeclCapacity(chunk);
  -      fElementDeclName[chunk][index]                    = null; 
  +      fElementDeclName[chunk][index]                    = new QName(); 
         fElementDeclType[chunk][index]                    = -1;  
         fElementDeclDatatypeValidator[chunk][index]       = null;
         fElementDeclContentModelValidator[chunk][index]   = null;
  @@ -905,11 +875,10 @@
         int     chunk       = elementDeclIndex >> CHUNK_SHIFT;
         int     index       = elementDeclIndex &  CHUNK_MASK;
   
  -      String  elementName = elementDecl.name.localpart;
         int     scope       = elementDecl.scope;
   
   
  -      fElementDeclName[chunk][index]                  = elementName;
  +      fElementDeclName[chunk][index].setValues(elementDecl.name);
         fElementDeclType[chunk][index]                  = elementDecl.type; 
         fElementDeclDatatypeValidator[chunk][index]     =
                           elementDecl.simpleType.datatypeValidator;
  @@ -924,10 +893,10 @@
         }
   
         if (isDTD()) {
  -          fScopeElementUriLocalpartHash.put(scope, elementDecl.name.rawname, null, elementDeclIndex);
  +          fScopeMapping.put(scope, elementDecl.name.rawname, null, elementDeclIndex);
         }
         else {
  -          fScopeElementUriLocalpartHash.put( scope, elementDecl.name.localpart, 
  +          fScopeMapping.put( scope, elementDecl.name.localpart, 
                                                elementDecl.name.uri, elementDeclIndex);
         }
      }
  @@ -1086,7 +1055,7 @@
          fNotationSystemId[chunk][index] = notationDecl.systemId;
      }
   
  -   protected void setTargetNameSpace( String targetNamespace ){
  +   protected void setTargetNamespace( String targetNamespace ){
         fTargetNamespace = targetNamespace;
      }
   
  @@ -1095,170 +1064,254 @@
         return true;
      }
   
  -   // debugging
  -
  -   public void printElements(  ) {
  -      int elementDeclIndex = 0;
  -      XMLElementDecl elementDecl = new XMLElementDecl();
  -      elementDecl.simpleType     = new XMLSimpleType();
  -      while (getElementDecl(elementDeclIndex++, elementDecl)) {
  +    //
  +    // Private methods
  +    //
  +
  +    private void appendContentSpec(XMLContentSpec contentSpec, 
  +                                   StringBuffer str, boolean parens,
  +                                   int parentContentSpecType ) {
  +
  +        int thisContentSpec = contentSpec.type & 0x0f;
  +        switch (thisContentSpec) {
  +            case XMLContentSpec.CONTENTSPECNODE_LEAF: {
  +                if (contentSpec.value == null && contentSpec.otherValue == null) {
  +                    str.append("#PCDATA");
  +                }
  +                else if (contentSpec.value == null && contentSpec.otherValue != null) {
  +                    str.append("##any:uri="+contentSpec.otherValue);
  +                }
  +                else if (contentSpec.value == null) {
  +                    str.append("##any");
  +                }
  +                else {
  +                    str.append(contentSpec.value);
  +                }
  +                break;
  +            }
  +            case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: {
  +                if (parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE  ||
  +                    parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
  +                    parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
  +                    getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  +                    str.append('(');
  +                    appendContentSpec(contentSpec, str, true, thisContentSpec );
  +                    str.append(')');
  +                } 
  +                else {
  +                    getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  +                    appendContentSpec( contentSpec, str, true, thisContentSpec );
  +                }
  +                str.append('?');
  +                break;
  +            }
  +            case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: {
  +                if (parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE ||
  +                    parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
  +                    parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
  +                    getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  +                    str.append('(');
  +                    appendContentSpec(contentSpec, str, true, thisContentSpec);
  +                    str.append(')' );
  +                } 
  +                else {
  +                    getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  +                    appendContentSpec(contentSpec, str, true, thisContentSpec);
  +                }
  +                str.append('*');
  +                break;
  +            }
  +            case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: {
  +                if (parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE   ||
  +                    parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE  ||
  +                    parentContentSpecType == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ) {
  +
  +                    str.append('(');
  +                    getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  +                    appendContentSpec(contentSpec, str, true, thisContentSpec);
  +                    str.append(')' );
  +                }
  +                else {
  +                    getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  +                    appendContentSpec(contentSpec, str, true, thisContentSpec);
  +                }
  +                str.append('+');
  +                break;
  +            }
  +            case XMLContentSpec.CONTENTSPECNODE_CHOICE:
  +            case XMLContentSpec.CONTENTSPECNODE_SEQ: {
  +                if (parens) {
  +                    str.append('(');
  +                }
  +                int type = contentSpec.type;
  +                int otherValue = ((int[])contentSpec.otherValue)[0];
  +                getContentSpec(((int[])contentSpec.value)[0], contentSpec);
  +                appendContentSpec(contentSpec, str, contentSpec.type != type, thisContentSpec);
  +                if (type == XMLContentSpec.CONTENTSPECNODE_CHOICE) {
  +                    str.append('|');
  +                }
  +                else {
  +                    str.append(',');
  +                }
  +                getContentSpec(otherValue, contentSpec);
  +                appendContentSpec(contentSpec, str, true, thisContentSpec);
  +                if (parens) {
  +                    str.append(')');
  +                }
  +                break;
  +            }
  +            case XMLContentSpec.CONTENTSPECNODE_ANY: {
  +                str.append("##any");
  +                if (contentSpec.otherValue != null) {
  +                    str.append(":uri=");
  +                    str.append(contentSpec.otherValue);
  +                }
  +                break;
  +            }
  +            case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER: {
  +                str.append("##other:uri=");
  +                str.append(contentSpec.otherValue);
  +                break;
  +            }
  +            case XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL: {
  +                str.append("##local");
  +                break;
  +            }
  +            default: {
  +                str.append("???");
  +                break;
  +            }
   
  -         System.out.println("element decl: "+elementDecl.name+
  -                            ", "+ elementDecl.name.rawname  );
  +        } // switch type
   
  -         //                   ", "+ elementDecl.contentModelValidator.toString());
  -      }
  -   }
  +    } // appendContentSpec(XMLContentSpec.Provider,StringPool,XMLContentSpec,StringBuffer,boolean)
   
  -   public void printAttributes(int elementDeclIndex) {
  -      int attributeDeclIndex = getFirstAttributeDeclIndex(elementDeclIndex);
  -      System.out.print(elementDeclIndex);
  -      System.out.print(" [");
  -      while (attributeDeclIndex != -1) {
  -         System.out.print(' ');
  -         System.out.print(attributeDeclIndex);
  -         printAttribute(attributeDeclIndex);
  -         attributeDeclIndex = getNextAttributeDeclIndex(attributeDeclIndex);
  -         if (attributeDeclIndex != -1) {
  -            System.out.print(",");
  -         }
  -      }
  -      System.out.println(" ]");
  -   }
  +    //
  +    // Private methods
  +    //
   
  +    // debugging
   
  -   //
  -   // Private methods
  -   //
  -
  -   // debugging
  -
  -   private void printAttribute(int attributeDeclIndex) {
  -      XMLAttributeDecl attributeDecl = new XMLAttributeDecl();
  -      attributeDecl.simpleType       = new XMLSimpleType();
  -      if (getAttributeDecl(attributeDeclIndex, attributeDecl)) {
  -         System.out.print(" { ");
  -         System.out.print(attributeDecl.name.localpart);
  -         System.out.print(" }");
  -      }
  -   }
  +    private void printAttribute(int attributeDeclIndex) {
   
  -   // content models
  -   //
  +        XMLAttributeDecl attributeDecl = new XMLAttributeDecl();
  +        if (getAttributeDecl(attributeDeclIndex, attributeDecl)) {
  +            System.out.print(" { ");
  +            System.out.print(attributeDecl.name.localpart);
  +            System.out.print(" }");
  +        }
   
  -   //private void printSyntaxTree(CMNode cmn){
  -   //}
  +    } // printAttribute(int)
   
  +    // content models
   
  +    /**
  +     * When the element has a 'CHILDREN' model, this method is called to
  +     * create the content model object. It looks for some special case simple
  +     * models and creates SimpleContentModel objects for those. For the rest
  +     * it creates the standard DFA style model.
  +     */
  +    private ContentModelValidator createChildModel(int contentSpecIndex) {
  +        
  +        //
  +        //  Get the content spec node for the element we are working on.
  +        //  This will tell us what kind of node it is, which tells us what
  +        //  kind of model we will try to create.
  +        //
  +        XMLContentSpec contentSpec = new XMLContentSpec();
  +        getContentSpec(contentSpecIndex, contentSpec);
   
  -   //
  -   //  When the element has a 'CHILDREN' model, this method is called to
  -   //  create the content model object. It looks for some special case simple
  -   //  models and creates SimpleContentModel objects for those. For the rest
  -   //  it creates the standard DFA style model.
  -   //
  -   private ContentModelValidator createChildModel ( int contentSpecIndex) {
  -      //
  -      //  Get the content spec node for the element we are working on.
  -      //  This will tell us what kind of node it is, which tells us what
  -      //  kind of model we will try to create.
  -      //
  -      XMLContentSpec contentSpec = new XMLContentSpec();
  -
  -
  -      getContentSpec(contentSpecIndex, contentSpec);
  -
  -      if ((contentSpec.type & 0x0f ) == XMLContentSpec.CONTENTSPECNODE_ANY ||
  -          (contentSpec.type & 0x0f ) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER ||
  -          (contentSpec.type & 0x0f ) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
  -         // let fall through to build a DFAContentModel
  -      }
  +        if ((contentSpec.type & 0x0f ) == XMLContentSpec.CONTENTSPECNODE_ANY ||
  +            (contentSpec.type & 0x0f ) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER ||
  +            (contentSpec.type & 0x0f ) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
  +            // let fall through to build a DFAContentModel
  +        }
   
  -      else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
  -         //
  -         //  Check that the left value is not -1, since any content model
  -         //  with PCDATA should be MIXED, so we should not have gotten here.
  -         //
  -         if (contentSpec.value == null && contentSpec.otherValue == null)
  -            throw new RuntimeException("ImplementationMessages.VAL_NPCD");
  -
  -         //
  -         //  Its a single leaf, so its an 'a' type of content model, i.e.
  -         //  just one instance of one element. That one is definitely a
  -         //  simple content model.
  -         //
  -
  -         fQName1.setValues(null, (String)contentSpec.value, 
  -                           (String)contentSpec.value, (String)contentSpec.otherValue);
  -         return new SimpleContentModel(contentSpec.type, fQName1, null, isDTD());
  -      } else if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE)
  -                 ||  (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ)) {
  -         //
  -         //  Lets see if both of the children are leafs. If so, then it
  -         //  it has to be a simple content model
  -         //
  -         XMLContentSpec contentSpecLeft  = new XMLContentSpec();
  -         XMLContentSpec contentSpecRight = new XMLContentSpec();
  +        else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
  +            //
  +            //  Check that the left value is not -1, since any content model
  +            //  with PCDATA should be MIXED, so we should not have gotten here.
  +            //
  +            if (contentSpec.value == null && contentSpec.otherValue == null)
  +                throw new RuntimeException("ImplementationMessages.VAL_NPCD");
   
  -         getContentSpec( ((int[])contentSpec.value)[0], contentSpecLeft);
  -         getContentSpec( ((int[])contentSpec.otherValue)[0], contentSpecRight);
  +            //
  +            //  Its a single leaf, so its an 'a' type of content model, i.e.
  +            //  just one instance of one element. That one is definitely a
  +            //  simple content model.
  +            //
   
  -         if ((contentSpecLeft.type == XMLContentSpec.CONTENTSPECNODE_LEAF)
  -             &&  (contentSpecRight.type == XMLContentSpec.CONTENTSPECNODE_LEAF)) {
  +            fQName1.setValues(null, (String)contentSpec.value, 
  +                              (String)contentSpec.value, (String)contentSpec.otherValue);
  +            return new SimpleContentModel(contentSpec.type, fQName1, null, isDTD());
  +        } else if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE)
  +                    ||  (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ)) {
               //
  -            //  Its a simple choice or sequence, so we can do a simple
  -            //  content model for it.
  +            //  Lets see if both of the children are leafs. If so, then it
  +            //  it has to be a simple content model
               //
  -            fQName1.setValues(null, (String)contentSpecLeft.value, 
  -                              (String)contentSpecLeft.value, (String)contentSpecLeft.otherValue);
  -            fQName2.setValues(null, (String)contentSpecRight.value, 
  -                              (String)contentSpecRight.value, (String)contentSpecRight.otherValue);
  -            return new SimpleContentModel(contentSpec.type, fQName1, fQName2, isDTD());
  -         }
  -      } else if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE)
  -                 ||  (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE)
  -                 ||  (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE)) {
  -         //
  -         //  Its a repetition, so see if its one child is a leaf. If so
  -         //  its a repetition of a single element, so we can do a simple
  -         //  content model for that.
  -         //
  -         XMLContentSpec contentSpecLeft = new XMLContentSpec();
  -         getContentSpec(((int[])contentSpec.value)[0], contentSpecLeft);
  +            XMLContentSpec contentSpecLeft  = new XMLContentSpec();
  +            XMLContentSpec contentSpecRight = new XMLContentSpec();
   
  -         if (contentSpecLeft.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
  +            getContentSpec( ((int[])contentSpec.value)[0], contentSpecLeft);
  +            getContentSpec( ((int[])contentSpec.otherValue)[0], contentSpecRight);
  +
  +            if ((contentSpecLeft.type == XMLContentSpec.CONTENTSPECNODE_LEAF)
  +                 &&  (contentSpecRight.type == XMLContentSpec.CONTENTSPECNODE_LEAF)) {
  +                //
  +                //  Its a simple choice or sequence, so we can do a simple
  +                //  content model for it.
  +                //
  +                fQName1.setValues(null, (String)contentSpecLeft.value, 
  +                                  (String)contentSpecLeft.value, (String)contentSpecLeft.otherValue);
  +                fQName2.setValues(null, (String)contentSpecRight.value, 
  +                                  (String)contentSpecRight.value, (String)contentSpecRight.otherValue);
  +                return new SimpleContentModel(contentSpec.type, fQName1, fQName2, isDTD());
  +            }
  +        } else if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE)
  +                    ||  (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE)
  +                    ||  (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE)) {
               //
  -            //  It is, so we can create a simple content model here that
  -            //  will check for this repetition. We pass -1 for the unused
  -            //  right node.
  +            //  Its a repetition, so see if its one child is a leaf. If so
  +            //  its a repetition of a single element, so we can do a simple
  +            //  content model for that.
               //
  -            fQName1.setValues(null, (String)contentSpecLeft.value, 
  -                              (String)contentSpecLeft.value, (String)contentSpecLeft.otherValue);
  -            return new SimpleContentModel(contentSpec.type, fQName1, null, isDTD());
  -         }
  -      } else {
  -         throw new RuntimeException("ImplementationMessages.VAL_CST");
  -      }
  +            XMLContentSpec contentSpecLeft = new XMLContentSpec();
  +            getContentSpec(((int[])contentSpec.value)[0], contentSpecLeft);
  +    
  +            if (contentSpecLeft.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
  +                //
  +                //  It is, so we can create a simple content model here that
  +                //  will check for this repetition. We pass -1 for the unused
  +                //  right node.
  +                //
  +                fQName1.setValues(null, (String)contentSpecLeft.value, 
  +                                  (String)contentSpecLeft.value, (String)contentSpecLeft.otherValue);
  +                return new SimpleContentModel(contentSpec.type, fQName1, null, isDTD());
  +            }
  +        } else {
  +            throw new RuntimeException("ImplementationMessages.VAL_CST");
  +        }
   
  -      //
  -      //  Its not a simple content model, so here we have to create a DFA
  -      //  for this element. So we create a DFAContentModel object. He
  -      //  encapsulates all of the work to create the DFA.
  -      //
  -
  -      fLeafCount = 0;
  -      //int leafCount = countLeaves(contentSpecIndex);
  -      fLeafCount = 0;
  -      CMNode cmn    = buildSyntaxTree(contentSpecIndex, contentSpec);
  +        //
  +        //  Its not a simple content model, so here we have to create a DFA
  +        //  for this element. So we create a DFAContentModel object. He
  +        //  encapsulates all of the work to create the DFA.
  +        //
   
  -      // REVISIT: has to be fLeafCount because we convert x+ to x,x*, one more leaf
  -      return new DFAContentModel(  cmn, fLeafCount, isDTD(), false);
  -   }
  +        fLeafCount = 0;
  +        //int leafCount = countLeaves(contentSpecIndex);
  +        fLeafCount = 0;
  +        CMNode cmn    = buildSyntaxTree(contentSpecIndex, contentSpec);
   
  -    private int fLeafCount = 0;
  -    private int fEpsilonIndex = -1;
  -    private final CMNode buildSyntaxTree(int startNode, XMLContentSpec contentSpec)
  -    {
  +        // REVISIT: has to be fLeafCount because we convert x+ to x,x*, one more leaf
  +        return new DFAContentModel(  cmn, fLeafCount, isDTD(), false);
  +
  +    } // createChildModel(int):ContentModelValidator
  +
  +    private final CMNode buildSyntaxTree(int startNode, 
  +                                         XMLContentSpec contentSpec) {
  +
           // We will build a node at this level for the new tree
           CMNode nodeRet = null;
           getContentSpec(startNode, contentSpec);
  @@ -1330,278 +1383,316 @@
       }
      
       /**
  -    * Build a vector of valid QNames from Content Spec
  -    * table.
  -    * 
  -    * @param contentSpecIndex
  -    *               Content Spec index
  -    * @param vectorQName
  -    *               Array of QName
  -    * @exception RuntimeException
  -    */
  -   private void contentSpecTree(int contentSpecIndex, 
  -                                XMLContentSpec contentSpec,
  -                                ChildrenList children) {
  -
  -      // Handle any and leaf nodes
  -      getContentSpec( contentSpecIndex, contentSpec);
  -      if ( contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF ||
  -           (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY ||
  -           (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL ||
  -           (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
  -
  -         // resize arrays, if needed
  -         if (children.length == children.qname.length) {
  -            QName[] newQName = new QName[children.length * 2];
  -            System.arraycopy(children.qname, 0, newQName, 0, children.length);
  -            children.qname = newQName;
  -            int[] newType = new int[children.length * 2];
  -            System.arraycopy(children.type, 0, newType, 0, children.length);
  -            children.type = newType;
  -         }
  +     * Build a vector of valid QNames from Content Spec
  +     * table.
  +     * 
  +     * @param contentSpecIndex
  +     *               Content Spec index
  +     * @param vectorQName
  +     *               Array of QName
  +     * @exception RuntimeException
  +     */
  +    private void contentSpecTree(int contentSpecIndex, 
  +                                 XMLContentSpec contentSpec,
  +                                 ChildrenList children) {
  +
  +        // Handle any and leaf nodes
  +        getContentSpec( contentSpecIndex, contentSpec);
  +        if ( contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF ||
  +            (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY ||
  +            (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL ||
  +            (contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
  +
  +            // resize arrays, if needed
  +            if (children.length == children.qname.length) {
  +                QName[] newQName = new QName[children.length * 2];
  +                System.arraycopy(children.qname, 0, newQName, 0, children.length);
  +                children.qname = newQName;
  +                int[] newType = new int[children.length * 2];
  +                System.arraycopy(children.type, 0, newType, 0, children.length);
  +                children.type = newType;
  +            }
   
  -         // save values and return length
  -         children.qname[children.length] = new QName(null, (String)contentSpec.value, 
  +            // save values and return length
  +            children.qname[children.length] = new QName(null, (String)contentSpec.value, 
                                                        (String) contentSpec.value, 
                                                        (String) contentSpec.otherValue);
  -         children.type[children.length] = contentSpec.type;
  -         children.length++;
  -         return;
  -      }
  -
  -      //
  -      //  Its not a leaf, so we have to recurse its left and maybe right
  -      //  nodes. Save both values before we recurse and trash the node.
  -      //
  -      final int     leftNode = ((int[])(contentSpec.value))[0];
  -      int rightNode = -1 ;
  -      if (contentSpec.otherValue != null ) 
  -           rightNode = ((int[])(contentSpec.otherValue))[0];
  -      else 
  -          return;
  -
  -      if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE ||
  -          contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ) {
  -         contentSpecTree(leftNode, contentSpec, children);
  -         contentSpecTree(rightNode, contentSpec, children);
  -         return;
  -      }
  -
  -      if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ||
  -          contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
  -          contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) {
  -         contentSpecTree(leftNode, contentSpec, children);
  -         return;
  -      }
  +            children.type[children.length] = contentSpec.type;
  +            children.length++;
  +            return;
  +        }
   
  -      // error
  -      throw new RuntimeException("Invalid content spec type seen in contentSpecTree() method of Grammar class : "+contentSpec.type);
  -   }
  +        //
  +        //  Its not a leaf, so we have to recurse its left and maybe right
  +        //  nodes. Save both values before we recurse and trash the node.
  +        //
  +        final int     leftNode = ((int[])(contentSpec.value))[0];
  +        int rightNode = -1 ;
  +        if (contentSpec.otherValue != null ) 
  +            rightNode = ((int[])(contentSpec.otherValue))[0];
  +        else 
  +            return;
  +
  +        if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE ||
  +            contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ) {
  +            contentSpecTree(leftNode, contentSpec, children);
  +            contentSpecTree(rightNode, contentSpec, children);
  +            return;
  +        }
   
  +        if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE ||
  +            contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE ||
  +            contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) {
  +            contentSpecTree(leftNode, contentSpec, children);
  +            return;
  +        }
   
  +        // error
  +        throw new RuntimeException("Invalid content spec type seen in contentSpecTree() method of Grammar class : "+contentSpec.type);
   
  -   // ensure capacity
  +    } // contentSpecTree(int,XMLContentSpec,ChildrenList)
   
  +    // ensure capacity
   
  -   private boolean ensureElementDeclCapacity(int chunk) {
  -      try {
  -         return fElementDeclName[chunk][0] == null;
  -      } catch (ArrayIndexOutOfBoundsException ex) {
  -         fElementDeclName = resize(fElementDeclName, fElementDeclName.length * 2);
  -         fElementDeclType = resize(fElementDeclType, fElementDeclType.length * 2);
  -         fElementDeclDatatypeValidator = resize(fElementDeclDatatypeValidator, fElementDeclDatatypeValidator.length * 2);
  -         fElementDeclContentModelValidator = resize(fElementDeclContentModelValidator, fElementDeclContentModelValidator.length * 2);
  -         fElementDeclContentSpecIndex = resize(fElementDeclContentSpecIndex,fElementDeclContentSpecIndex.length * 2);
  -         fElementDeclFirstAttributeDeclIndex = resize(fElementDeclFirstAttributeDeclIndex, fElementDeclFirstAttributeDeclIndex.length * 2);
  -         fElementDeclLastAttributeDeclIndex = resize(fElementDeclLastAttributeDeclIndex, fElementDeclLastAttributeDeclIndex.length * 2);
  -         fElementDeclDefaultValue = resize( fElementDeclDefaultValue, fElementDeclDefaultValue.length * 2 ); 
  -         fElementDeclDefaultType  = resize( fElementDeclDefaultType, fElementDeclDefaultType.length *2 );
  -      } catch (NullPointerException ex) {
  -         // ignore
  -      }
  -      fElementDeclName[chunk] = new String[CHUNK_SIZE];
  -      fElementDeclType[chunk] = new short[CHUNK_SIZE];
  -      fElementDeclDatatypeValidator[chunk] = new DatatypeValidator[CHUNK_SIZE];
  -      fElementDeclContentModelValidator[chunk] = new ContentModelValidator[CHUNK_SIZE];
  -      fElementDeclContentSpecIndex[chunk] = new int[CHUNK_SIZE];
  -      fElementDeclFirstAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
  -      fElementDeclLastAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
  -      fElementDeclDefaultValue[chunk] = new String[CHUNK_SIZE]; 
  -      fElementDeclDefaultType[chunk]  = new short[CHUNK_SIZE]; 
  -      return true;
  -   }
  +    private boolean ensureElementDeclCapacity(int chunk) {
  +        try {
  +            return fElementDeclName[chunk][0] == null;
  +        } catch (ArrayIndexOutOfBoundsException ex) {
  +            fElementDeclName = resize(fElementDeclName, fElementDeclName.length * 2);
  +            fElementDeclType = resize(fElementDeclType, fElementDeclType.length * 2);
  +            fElementDeclDatatypeValidator = resize(fElementDeclDatatypeValidator, fElementDeclDatatypeValidator.length * 2);
  +            fElementDeclContentModelValidator = resize(fElementDeclContentModelValidator, fElementDeclContentModelValidator.length * 2);
  +            fElementDeclContentSpecIndex = resize(fElementDeclContentSpecIndex,fElementDeclContentSpecIndex.length * 2);
  +            fElementDeclFirstAttributeDeclIndex = resize(fElementDeclFirstAttributeDeclIndex, fElementDeclFirstAttributeDeclIndex.length * 2);
  +            fElementDeclLastAttributeDeclIndex = resize(fElementDeclLastAttributeDeclIndex, fElementDeclLastAttributeDeclIndex.length * 2);
  +            fElementDeclDefaultValue = resize( fElementDeclDefaultValue, fElementDeclDefaultValue.length * 2 ); 
  +            fElementDeclDefaultType  = resize( fElementDeclDefaultType, fElementDeclDefaultType.length *2 );
  +        } catch (NullPointerException ex) {
  +            // ignore
  +        }
  +        fElementDeclName[chunk] = new QName[CHUNK_SIZE];
  +        fElementDeclType[chunk] = new short[CHUNK_SIZE];
  +        fElementDeclDatatypeValidator[chunk] = new DatatypeValidator[CHUNK_SIZE];
  +        fElementDeclContentModelValidator[chunk] = new ContentModelValidator[CHUNK_SIZE];
  +        fElementDeclContentSpecIndex[chunk] = new int[CHUNK_SIZE];
  +        fElementDeclFirstAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
  +        fElementDeclLastAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
  +        fElementDeclDefaultValue[chunk] = new String[CHUNK_SIZE]; 
  +        fElementDeclDefaultType[chunk]  = new short[CHUNK_SIZE]; 
  +        return true;
  +    }
   
  +    private boolean ensureAttributeDeclCapacity(int chunk) {
  +        try {
  +            return fAttributeDeclName[chunk][0] == null;
  +        } catch (ArrayIndexOutOfBoundsException ex) {
  +            fAttributeDeclName = resize(fAttributeDeclName, fAttributeDeclName.length * 2);
  +            fAttributeDeclType = resize(fAttributeDeclType, fAttributeDeclType.length * 2);
  +            fAttributeDeclEnumeration = resize(fAttributeDeclEnumeration, fAttributeDeclEnumeration.length * 2);
  +            fAttributeDeclDefaultType = resize(fAttributeDeclDefaultType, fAttributeDeclDefaultType.length * 2);
  +            fAttributeDeclDatatypeValidator = resize(fAttributeDeclDatatypeValidator, fAttributeDeclDatatypeValidator.length * 2);
  +            fAttributeDeclDefaultValue = resize(fAttributeDeclDefaultValue, fAttributeDeclDefaultValue.length * 2);
  +            fAttributeDeclNextAttributeDeclIndex = resize(fAttributeDeclNextAttributeDeclIndex, fAttributeDeclNextAttributeDeclIndex.length * 2);
  +        } catch (NullPointerException ex) {
  +            // ignore
  +        }
  +        fAttributeDeclName[chunk] = new QName[CHUNK_SIZE];
  +        fAttributeDeclType[chunk] = new short[CHUNK_SIZE];
  +        fAttributeDeclEnumeration[chunk] = new String[CHUNK_SIZE][];
  +        fAttributeDeclDefaultType[chunk] = new short[CHUNK_SIZE];
  +        fAttributeDeclDatatypeValidator[chunk] = new DatatypeValidator[CHUNK_SIZE];
  +        fAttributeDeclDefaultValue[chunk] = new String[CHUNK_SIZE];
  +        fAttributeDeclNextAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
  +        return true;
  +    }
  +   
  +    private boolean ensureEntityDeclCapacity(int chunk) {
  +        try {
  +            return fEntityName[chunk][0] == null;
  +        } catch (ArrayIndexOutOfBoundsException ex) {
  +            fEntityName = resize(fEntityName, fEntityName.length * 2);
  +            fEntityValue = resize(fEntityValue, fEntityValue.length * 2);
  +            fEntityPublicId = resize(fEntityPublicId, fEntityPublicId.length * 2);
  +            fEntitySystemId = resize(fEntitySystemId, fEntitySystemId.length * 2);
  +            fEntityBaseSystemId = resize(fEntityBaseSystemId, fEntityBaseSystemId.length * 2);
  +            fEntityNotation = resize(fEntityNotation, fEntityNotation.length * 2);
  +            fEntityIsPE = resize(fEntityIsPE, fEntityIsPE.length * 2);
  +            fEntityInExternal = resize(fEntityInExternal, fEntityInExternal.length * 2);
  +        } catch (NullPointerException ex) {
  +            // ignore
  +        }
  +        fEntityName[chunk] = new String[CHUNK_SIZE];
  +        fEntityValue[chunk] = new String[CHUNK_SIZE];
  +        fEntityPublicId[chunk] = new String[CHUNK_SIZE];
  +        fEntitySystemId[chunk] = new String[CHUNK_SIZE];
  +        fEntityBaseSystemId[chunk] = new String[CHUNK_SIZE];
  +        fEntityNotation[chunk] = new String[CHUNK_SIZE];
  +        fEntityIsPE[chunk] = new byte[CHUNK_SIZE];
  +        fEntityInExternal[chunk] = new byte[CHUNK_SIZE];
  +        return true;
  +    }
  +      
  +    private boolean ensureNotationDeclCapacity(int chunk) {
  +        try {
  +            return fNotationName[chunk][0] == null;
  +        } catch (ArrayIndexOutOfBoundsException ex) {
  +            fNotationName = resize(fNotationName, fNotationName.length * 2);
  +            fNotationPublicId = resize(fNotationPublicId, fNotationPublicId.length * 2);
  +            fNotationSystemId = resize(fNotationSystemId, fNotationSystemId.length * 2);
  +        } catch (NullPointerException ex) {
  +            // ignore
  +        }
  +        fNotationName[chunk] = new String[CHUNK_SIZE];
  +        fNotationPublicId[chunk] = new String[CHUNK_SIZE];
  +        fNotationSystemId[chunk] = new String[CHUNK_SIZE];
  +        return true;
  +    }
   
  +    private boolean ensureContentSpecCapacity(int chunk) {
  +        try {
  +            return fContentSpecType[chunk][0] == 0;
  +        } catch (ArrayIndexOutOfBoundsException ex) {
  +            fContentSpecType = resize(fContentSpecType, fContentSpecType.length * 2);
  +            fContentSpecValue = resize(fContentSpecValue, fContentSpecValue.length * 2);
  +            fContentSpecOtherValue = resize(fContentSpecOtherValue, fContentSpecOtherValue.length * 2);
  +        } catch (NullPointerException ex) {
  +            // ignore
  +        }
  +        fContentSpecType[chunk] = new short[CHUNK_SIZE];
  +        fContentSpecValue[chunk] = new Object[CHUNK_SIZE];
  +        fContentSpecOtherValue[chunk] = new Object[CHUNK_SIZE];
  +        return true;
  +    }
   
  -   private boolean ensureAttributeDeclCapacity(int chunk) {
  -      try {
  -         return fAttributeDeclName[chunk][0] == null;
  -      } catch (ArrayIndexOutOfBoundsException ex) {
  -         fAttributeDeclName = resize(fAttributeDeclName, fAttributeDeclName.length * 2);
  -         fAttributeDeclType = resize(fAttributeDeclType, fAttributeDeclType.length * 2);
  -         fAttributeDeclEnumeration = resize(fAttributeDeclEnumeration, fAttributeDeclEnumeration.length * 2);
  -         fAttributeDeclDefaultType = resize(fAttributeDeclDefaultType, fAttributeDeclDefaultType.length * 2);
  -         fAttributeDeclDatatypeValidator = resize(fAttributeDeclDatatypeValidator, fAttributeDeclDatatypeValidator.length * 2);
  -         fAttributeDeclDefaultValue = resize(fAttributeDeclDefaultValue, fAttributeDeclDefaultValue.length * 2);
  -         fAttributeDeclNextAttributeDeclIndex = resize(fAttributeDeclNextAttributeDeclIndex, fAttributeDeclNextAttributeDeclIndex.length * 2);
  -      } catch (NullPointerException ex) {
  -         // ignore
  -      }
  -      fAttributeDeclName[chunk] = new QName[CHUNK_SIZE];
  -      fAttributeDeclType[chunk] = new short[CHUNK_SIZE];
  -      fAttributeDeclEnumeration[chunk] = new String[CHUNK_SIZE][];
  -      fAttributeDeclDefaultType[chunk] = new short[CHUNK_SIZE];
  -      fAttributeDeclDatatypeValidator[chunk] = new DatatypeValidator[CHUNK_SIZE];
  -      fAttributeDeclDefaultValue[chunk] = new String[CHUNK_SIZE];
  -      fAttributeDeclNextAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
  -      return true;
  -   }
  -   
  -   private boolean ensureEntityDeclCapacity(int chunk) {
  -      try {
  -         return fEntityName[chunk][0] == null;
  -      } catch (ArrayIndexOutOfBoundsException ex) {
  -          fEntityName = resize(fEntityName, fEntityName.length * 2);
  -          fEntityValue = resize(fEntityValue, fEntityValue.length * 2);
  -          fEntityPublicId = resize(fEntityPublicId, fEntityPublicId.length * 2);
  -          fEntitySystemId = resize(fEntitySystemId, fEntitySystemId.length * 2);
  -          fEntityBaseSystemId = resize(fEntityBaseSystemId, fEntityBaseSystemId.length * 2);
  -          fEntityNotation = resize(fEntityNotation, fEntityNotation.length * 2);
  -          fEntityIsPE = resize(fEntityIsPE, fEntityIsPE.length * 2);
  -          fEntityInExternal = resize(fEntityInExternal, fEntityInExternal.length * 2);
  -      } catch (NullPointerException ex) {
  -         // ignore
  -      }
  -      fEntityName[chunk] = new String[CHUNK_SIZE];
  -      fEntityValue[chunk] = new String[CHUNK_SIZE];
  -      fEntityPublicId[chunk] = new String[CHUNK_SIZE];
  -      fEntitySystemId[chunk] = new String[CHUNK_SIZE];
  -      fEntityBaseSystemId[chunk] = new String[CHUNK_SIZE];
  -      fEntityNotation[chunk] = new String[CHUNK_SIZE];
  -      fEntityIsPE[chunk] = new byte[CHUNK_SIZE];
  -      fEntityInExternal[chunk] = new byte[CHUNK_SIZE];
  -      return true;
  -   }
  +    //
  +    // Private static methods
  +    //
  +
  +    // resize chunks
  +
  +    private static byte[][] resize(byte array[][], int newsize) {
  +        byte newarray[][] = new byte[newsize][];
  +        System.arraycopy(array, 0, newarray, 0, array.length);
  +        return newarray;
  +    }
      
  +    private static short[][] resize(short array[][], int newsize) {
  +        short newarray[][] = new short[newsize][];
  +        System.arraycopy(array, 0, newarray, 0, array.length);
  +        return newarray;
  +    }
   
  -   private boolean ensureNotationDeclCapacity(int chunk) {
  -      try {
  -         return fNotationName[chunk][0] == null;
  -      } catch (ArrayIndexOutOfBoundsException ex) {
  -          fNotationName = resize(fNotationName, fNotationName.length * 2);
  -          fNotationPublicId = resize(fNotationPublicId, fNotationPublicId.length * 2);
  -          fNotationSystemId = resize(fNotationSystemId, fNotationSystemId.length * 2);
  -      } catch (NullPointerException ex) {
  -         // ignore
  -      }
  -      fNotationName[chunk] = new String[CHUNK_SIZE];
  -      fNotationPublicId[chunk] = new String[CHUNK_SIZE];
  -      fNotationSystemId[chunk] = new String[CHUNK_SIZE];
  -      return true;
  -   }
  +    private static int[][] resize(int array[][], int newsize) {
  +        int newarray[][] = new int[newsize][];
  +        System.arraycopy(array, 0, newarray, 0, array.length);
  +        return newarray;
  +    }
   
  -   private boolean ensureContentSpecCapacity(int chunk) {
  -      try {
  -         return fContentSpecType[chunk][0] == 0;
  -      } catch (ArrayIndexOutOfBoundsException ex) {
  -         fContentSpecType = resize(fContentSpecType, fContentSpecType.length * 2);
  -         fContentSpecValue = resize(fContentSpecValue, fContentSpecValue.length * 2);
  -         fContentSpecOtherValue = resize(fContentSpecOtherValue, fContentSpecOtherValue.length * 2);
  -      } catch (NullPointerException ex) {
  -         // ignore
  -      }
  -      fContentSpecType[chunk] = new short[CHUNK_SIZE];
  -      fContentSpecValue[chunk] = new Object[CHUNK_SIZE];
  -      fContentSpecOtherValue[chunk] = new Object[CHUNK_SIZE];
  -      return true;
  -   }
  +    private static DatatypeValidator[][] resize(DatatypeValidator array[][], int newsize) {
  +        DatatypeValidator newarray[][] = new DatatypeValidator[newsize][];
  +        System.arraycopy(array, 0, newarray, 0, array.length);
  +        return newarray;
  +    }
   
  +    private static ContentModelValidator[][] resize(ContentModelValidator array[][], int newsize) {
  +        ContentModelValidator newarray[][] = new ContentModelValidator[newsize][];
  +        System.arraycopy(array, 0, newarray, 0, array.length);
  +        return newarray;
  +    }
   
  -   // resize initial chunk
  +    private static Object[][] resize(Object array[][], int newsize) {
  +        Object newarray[][] = new Object[newsize][];
  +        System.arraycopy(array, 0, newarray, 0, array.length);
  +        return newarray;
  +    }
   
  -   private byte[][] resize(byte array[][], int newsize) {
  -      byte newarray[][] = new byte[newsize][];
  -      System.arraycopy(array, 0, newarray, 0, array.length);
  -      return newarray;
  -   }
  -   
  -   private short[][] resize(short array[][], int newsize) {
  -      short newarray[][] = new short[newsize][];
  -      System.arraycopy(array, 0, newarray, 0, array.length);
  -      return newarray;
  -   }
  +    private static QName[][] resize(QName array[][], int newsize) {
  +        QName newarray[][] = new QName[newsize][];
  +        System.arraycopy(array, 0, newarray, 0, array.length);
  +        return newarray;
  +    }
   
  +    private static String[][] resize(String array[][], int newsize) {
  +        String newarray[][] = new String[newsize][];
  +        System.arraycopy(array, 0, newarray, 0, array.length);
  +        return newarray;
  +    }
   
  -   private int[][] resize(int array[][], int newsize) {
  -      int newarray[][] = new int[newsize][];
  -      System.arraycopy(array, 0, newarray, 0, array.length);
  -      return newarray;
  -   }
  +    private static String[][][] resize(String array[][][], int newsize) {
  +        String newarray[][][] = new String[newsize] [][];
  +        System.arraycopy(array, 0, newarray, 0, array.length);
  +        return newarray;
  +    }
   
  -   private DatatypeValidator[][] resize(DatatypeValidator array[][], int newsize) {
  -      DatatypeValidator newarray[][] = new DatatypeValidator[newsize][];
  -      System.arraycopy(array, 0, newarray, 0, array.length);
  -      return newarray;
  -   }
  +    //
  +    // Classes
  +    //
  +    
  +    /**
  +     * Children list for <code>contentSpecTree</code> method.
  +     *
  +     * @author Eric Ye, IBM
  +     */
  +    private static class ChildrenList {
  +        
  +        //
  +        // Data
  +        //
   
  -   private ContentModelValidator[][] resize(ContentModelValidator array[][], int newsize) {
  -      ContentModelValidator newarray[][] = new ContentModelValidator[newsize][];
  -      System.arraycopy(array, 0, newarray, 0, array.length);
  -      return newarray;
  -   }
  +        /** Length. */
  +        public int length = 0;
   
  -   private Object[][] resize(Object array[][], int newsize) {
  -      Object newarray[][] = new Object[newsize][];
  -      System.arraycopy(array, 0, newarray, 0, array.length);
  -      return newarray;
  -   }
  +        // NOTE: The following set of data is mutually exclusive. It is
  +        //       written this way because Java doesn't have a native
  +        //       union data structure. -Ac
   
  -   private QName[][] resize(QName array[][], int newsize) {
  -      QName newarray[][] = new QName[newsize][];
  -      System.arraycopy(array, 0, newarray, 0, array.length);
  -      return newarray;
  -   }
  +        /** Left and right children names. */
  +        public QName[] qname = new QName[2];
   
  -   private String[][] resize(String array[][], int newsize) {
  -      String newarray[][] = new String[newsize][];
  -      System.arraycopy(array, 0, newarray, 0, array.length);
  -      return newarray;
  -   }
  +        /** Left and right children types. */
  +        public int[] type = new int[2];
   
  -   private String[][][] resize(String array[][][], int newsize) {
  -      String newarray[][][] = new String[newsize] [][];
  -      System.arraycopy(array, 0, newarray, 0, array.length);
  -      return newarray;
  -   }
  +    } // class ChildrenList
   
  -   //
  -   // Classes
  -   //
  -
  -   /**
  -    * Children list for <code>contentSpecTree</code> method.
  -    */
  -   static class ChildrenList {
  -      public int length = 0;
  -      public QName[] qname = new QName[2];
  -      public int[] type = new int[2];
  -   }
  +    //
  +    // Classes
  +    //
   
  -   /**
  -    *
  -    * A simple Hashtable implementation that takes a tuple (int, String, String)
  -    * as the key and a int as value
  -    *
  -    */
  -   static final class Hash1int2stringTable {
  +    /**
  +     * A simple Hashtable implementation that takes a tuple (int, String, 
  +     * String) as the key and a int as value.
  +     *
  +     * @author Eric Ye, IBM
  +     * @author Andy Clark, IBM
  +     */
  +    protected static final class TupleHashtable {
       
  +        //
  +        // Constants
  +        //
       
  -       private static final int INITIAL_BUCKET_SIZE = 4;
  -       private static final int HASHTABLE_SIZE = 512;
  -       private Object[][] fHashTable = new Object[HASHTABLE_SIZE][];
  +        /** Initial bucket size (4). */
  +        private static final int INITIAL_BUCKET_SIZE = 4;
   
  +        // NOTE: Changed previous hashtable size from 512 to 101 so
  +        //       that we get a better distribution for hashing. -Ac
  +        /** Hashtable size (101). */
  +        private static final int HASHTABLE_SIZE = 101;
   
  +        //
  +        // Data
  +        //
  +
  +        private Object[][] fHashTable = new Object[HASHTABLE_SIZE][];
  +
  +        //
  +        // Public methods
  +        //
  +
  +        /** Associates the given value with the specified key tuple. */
           public void put(int key1, String key2, String key3, int value) {
  +
  +            // REVISIT: Why +2? -Ac
               int hash = (key1+hash(key2)+hash(key3)+2) % HASHTABLE_SIZE;
               Object[] bucket = fHashTable[hash];
   
  @@ -1643,9 +1734,12 @@
                   }
   
               }
  -        }
   
  +        } // put(int,String,String,int)
  +
  +        /** Returns the value associated with the specified key tuple. */
           public int get(int key1, String key2, String key3) {
  +
               int hash = (key1+hash(key2)+hash(key3)+2) % HASHTABLE_SIZE;
               Object[] bucket = fHashTable[hash];
   
  @@ -1663,9 +1757,16 @@
                   j += 4;
               }
               return -1;
  -        }
  +
  +        } // get(int,String,String)
   
  -        public int hash(String symbol) {
  +        //
  +        // Protected methods
  +        //
  +
  +        /** Returns a hash value for the specified symbol. */
  +        protected int hash(String symbol) {
  +
               if (symbol == null) {
                   return 0;
               }
  @@ -1675,8 +1776,9 @@
                   code = code * 37 + symbol.charAt(i);
               }
               return code & 0x7FFFFFF;
  -        }
  -   }  // class Hash1int2stringTable
   
  +        } // hash(String):int
  +
  +    }  // class TupleHashtable
   
   } // class Grammar
  
  
  
  1.1.2.6   +7 -7      xml-xerces/java/src/org/apache/xerces/impl/validation/Attic/XMLAttributeDecl.java
  
  Index: XMLAttributeDecl.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/validation/Attic/XMLAttributeDecl.java,v
  retrieving revision 1.1.2.5
  retrieving revision 1.1.2.6
  diff -u -r1.1.2.5 -r1.1.2.6
  --- XMLAttributeDecl.java	2000/10/28 01:14:22	1.1.2.5
  +++ XMLAttributeDecl.java	2000/12/28 09:41:19	1.1.2.6
  @@ -61,7 +61,7 @@
   
   /**
    * @author Stubs generated by DesignDoc on Wed Jun 07 11:58:44 PDT 2000
  - * @version $Id: XMLAttributeDecl.java,v 1.1.2.5 2000/10/28 01:14:22 ericye Exp $
  + * @version $Id: XMLAttributeDecl.java,v 1.1.2.6 2000/12/28 09:41:19 andyc Exp $
    */
   public class XMLAttributeDecl {
   
  @@ -70,10 +70,10 @@
       //
   
       /** name */
  -    public QName name = new QName();
  +    public final QName name = new QName();
   
       /** simpleType */
  -    public XMLSimpleType simpleType = new XMLSimpleType();
  +    public final XMLSimpleType simpleType = new XMLSimpleType();
   
       /** optional */
       public boolean optional;
  @@ -90,8 +90,8 @@
        * @param optional 
        */
       public void setValues(QName name, XMLSimpleType simpleType, boolean optional) {
  -        this.name       = name;
  -        this.simpleType = simpleType;
  +        this.name.setValues(name);
  +        this.simpleType.setValues(simpleType);
           this.optional   = optional;
       } // setValues
   
  @@ -99,8 +99,8 @@
        * clear
        */
       public void clear() {
  -        this.name       = null;
  -        this.simpleType = null;
  +        this.name.clear();
  +        this.simpleType.clear();
           this.optional   = false;
       } // clear
   
  
  
  
  1.1.2.7   +4 -4      xml-xerces/java/src/org/apache/xerces/impl/validation/Attic/XMLElementDecl.java
  
  Index: XMLElementDecl.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/validation/Attic/XMLElementDecl.java,v
  retrieving revision 1.1.2.6
  retrieving revision 1.1.2.7
  diff -u -r1.1.2.6 -r1.1.2.7
  --- XMLElementDecl.java	2000/10/31 00:13:56	1.1.2.6
  +++ XMLElementDecl.java	2000/12/28 09:41:19	1.1.2.7
  @@ -61,7 +61,7 @@
   
   /**
    * @author Stubs generated by DesignDoc on Mon Sep 11 11:54:05 PDT 2000
  - * @version $Id: XMLElementDecl.java,v 1.1.2.6 2000/10/31 00:13:56 ericye Exp $
  + * @version $Id: XMLElementDecl.java,v 1.1.2.7 2000/12/28 09:41:19 andyc Exp $
    */
   public class XMLElementDecl {
   
  @@ -89,7 +89,7 @@
       //
   
       /** name */
  -    public QName name = new QName();
  +    public final QName name = new QName();
   
       /** scope */
       public int scope = -1;
  @@ -101,7 +101,7 @@
       public ContentModelValidator contentModelValidator;
   
       /** simpleType */
  -    public XMLSimpleType simpleType = new XMLSimpleType();
  +    public final XMLSimpleType simpleType = new XMLSimpleType();
   
       //
       // Methods
  @@ -121,7 +121,7 @@
           this.scope                 = scope;
           this.type                  = type;
           this.contentModelValidator = contentModelValidator;
  -        this.simpleType            = simpleType;
  +        this.simpleType.setValues(simpleType);
       } // setValues
   
       /**
  
  
  
  1.1.2.7   +36 -4     xml-xerces/java/src/org/apache/xerces/impl/validation/Attic/XMLSimpleType.java
  
  Index: XMLSimpleType.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/validation/Attic/XMLSimpleType.java,v
  retrieving revision 1.1.2.6
  retrieving revision 1.1.2.7
  diff -u -r1.1.2.6 -r1.1.2.7
  --- XMLSimpleType.java	2000/10/13 10:21:50	1.1.2.6
  +++ XMLSimpleType.java	2000/12/28 09:41:20	1.1.2.7
  @@ -59,7 +59,7 @@
   
   /**
    * @author Stubs generated by DesignDoc on Wed Jun 07 11:58:44 PDT 2000
  - * @version $Id: XMLSimpleType.java,v 1.1.2.6 2000/10/13 10:21:50 jeffreyr Exp $
  + * @version $Id: XMLSimpleType.java,v 1.1.2.7 2000/12/28 09:41:20 andyc Exp $
    */
   public class XMLSimpleType {
   
  @@ -143,15 +143,47 @@
        * @param defaultValue 
        * @param datatypeValidator 
        */
  -    public void setValues(short type, String name, String[] enumeration, boolean list, short defaultType, String defaultValue, DatatypeValidator datatypeValidator) {
  +    public void setValues(short type, String name, String[] enumeration, 
  +                          boolean list, short defaultType, 
  +                          String defaultValue, 
  +                          DatatypeValidator datatypeValidator) {
  +
           this.type              = type;
           this.name              = name;
  -        this.enumeration       = enumeration;
  +        // REVISIT: Should this be a copy? -Ac
  +        if (enumeration != null && enumeration.length > 0) {
  +            this.enumeration = new String[enumeration.length];
  +            System.arraycopy(enumeration, 0, this.enumeration, 0, this.enumeration.length);
  +        }
  +        else {
  +            this.enumeration = null;
  +        }
           this.list              = list;
           this.defaultType       = defaultType;
           this.defaultValue      = defaultValue;
           this.datatypeValidator = datatypeValidator;
  -    } // setValues
  +
  +    } // setValues(short,String,String[],boolean,short,String,DatatypeValidator)
  +
  +    /** Set values. */
  +    public void setValues(XMLSimpleType simpleType) {
  +
  +        type = simpleType.type;
  +        name = simpleType.name;
  +        // REVISIT: Should this be a copy? -Ac
  +        if (simpleType.enumeration != null && simpleType.enumeration.length > 0) {
  +            enumeration = new String[simpleType.enumeration.length];
  +            System.arraycopy(simpleType.enumeration, 0, enumeration, 0, enumeration.length);
  +        }
  +        else {
  +            enumeration = null;
  +        }
  +        list = simpleType.list;
  +        defaultType = simpleType.defaultType;
  +        defaultValue = simpleType.defaultValue;
  +        datatypeValidator = simpleType.datatypeValidator;
  +
  +    } // setValues(XMLSimpleType)
   
       /**
        * clear
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.34  +867 -892  xml-xerces/java/src/org/apache/xerces/impl/validation/grammars/Attic/DTDGrammar.java
  
  Index: DTDGrammar.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/validation/grammars/Attic/DTDGrammar.java,v
  retrieving revision 1.1.2.33
  retrieving revision 1.1.2.34
  diff -u -r1.1.2.33 -r1.1.2.34
  --- DTDGrammar.java	2000/12/05 18:18:58	1.1.2.33
  +++ DTDGrammar.java	2000/12/28 09:41:23	1.1.2.34
  @@ -57,9 +57,9 @@
   
   package org.apache.xerces.impl.validation.grammars;
   
  -import org.apache.xerces.xni.XMLString;
  -import org.apache.xerces.xni.XMLDTDContentModelHandler;
  -import org.apache.xerces.xni.XMLDTDHandler;
  +import java.util.Hashtable;
  +import java.util.Enumeration;
  +
   import org.apache.xerces.impl.XMLErrorReporter;
   import org.apache.xerces.impl.msg.XMLMessageFormatter;
   import org.apache.xerces.impl.validation.Grammar;
  @@ -73,96 +73,108 @@
   import org.apache.xerces.impl.validation.DatatypeValidator;
   import org.apache.xerces.impl.validation.datatypes.DatatypeValidatorFactoryImpl;
   import org.apache.xerces.xni.QName;
  +import org.apache.xerces.xni.XMLString;
  +import org.apache.xerces.xni.XMLDTDContentModelHandler;
  +import org.apache.xerces.xni.XMLDTDHandler;
  +
   import org.xml.sax.SAXException;
  -import java.util.Hashtable;
  -import java.util.Enumeration;
   
   /**
  - * @author Eric Ye, IBM
  + * A DTD grammar. This class implements the XNI handler interfaces
  + * for DTD information so that it can build the approprate validation
  + * structures automatically from the callbacks.
  + *
    * @author Stubs generated by DesignDoc on Mon Sep 11 11:10:57 PDT 2000
  + * @author Eric Ye, IBM
    * @author Jeffrey Rodriguez, IBM
  + * @author Andy Clark, IBM
    *
  - * @version $Id: DTDGrammar.java,v 1.1.2.33 2000/12/05 18:18:58 ericye Exp $
  + * @version $Id: DTDGrammar.java,v 1.1.2.34 2000/12/28 09:41:23 andyc Exp $
    */
   public class DTDGrammar
  -extends Grammar
  -implements XMLDTDHandler, XMLDTDContentModelHandler{
  +    extends Grammar
  +    implements XMLDTDHandler, XMLDTDContentModelHandler {
   
  -   //
  -   // Data
  -   //
  +    //
  +    // Constants
  +    //
   
  +    /** Chunk shift (8). */
  +    private static final int CHUNK_SHIFT = 8; // 2^8 = 256
   
  -   /** Chunk shift. */
  -   private static final int CHUNK_SHIFT = 8; // 2^8 = 256
  +    /** Chunk size (1 << CHUNK_SHIFT). */
  +    private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
   
  -   /** Chunk size. */
  -   private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
  +    /** Chunk mask (CHUNK_SIZE - 1). */
  +    private static final int CHUNK_MASK = CHUNK_SIZE - 1;
   
  -   /** Chunk mask. */
  -   private static final int CHUNK_MASK = CHUNK_SIZE - 1;
  +    /** Initial chunk count (1 << (10 - CHUNK_SHIFT)). */
  +    private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k
   
  -   /** Initial chunk count. */
  -   private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k
  +    // debugging
   
  -   /** Current ElementIndex */
  -   private int              fCurrentElementIndex;
  +    /** Debug DTDGrammar. */
  +    private static final boolean DEBUG = false;
   
  -   /** Element declaration. */
  -   private XMLElementDecl    fElementDecl        = new XMLElementDecl();
  +    //
  +    // Data
  +    //
   
  -   /** Current AttributeIndex */
  -   private int               fCurrentAttributeIndex;
  +    /** Current element index. */
  +    protected int fCurrentElementIndex;
   
  -   /** Attribute declaration. */
  -   private XMLAttributeDecl  fAttributeDecl      = new XMLAttributeDecl();
  +    /** Current attribute index. */
  +    protected int fCurrentAttributeIndex;
   
  -   /** QName holder           */
  -   private QName             fQName              = new QName();
  +    /** fReadingExternalDTD */
  +    protected boolean fReadingExternalDTD = false;
   
  -   /** XMLEntityDecl. */
  -   private XMLEntityDecl     fEntityDecl         = new XMLEntityDecl();
  +    // temp variables
   
  -   /** internal XMLEntityDecl. */
  -   private XMLEntityDecl     fInternalEntityDecl = new XMLEntityDecl();
  +    /** Element declaration. */
  +    private XMLElementDecl fElementDecl = new XMLElementDecl();
   
  -   /** external XMLEntityDecl */
  -   private XMLEntityDecl     fExternalEntityDecl = new XMLEntityDecl();
  +    /** Attribute declaration. */
  +    private XMLAttributeDecl fAttributeDecl = new XMLAttributeDecl();
   
  -   /** Simple Type. */
  -   private XMLSimpleType     fSimpleType         = new XMLSimpleType();
  +    /** A qualified name. */
  +    private QName fQName = new QName();
   
  -   /** Content spec node. */
  -   private XMLContentSpec    fContentSpec        = new XMLContentSpec();
  +    /** Entity declaration. */
  +    private XMLEntityDecl fEntityDecl = new XMLEntityDecl();
   
  -   /** fReadingExternalDTD */
  -   boolean fReadingExternalDTD = false;
  +    /** Simple type. */
  +    private XMLSimpleType fSimpleType = new XMLSimpleType();
   
  +    /** Content spec node. */
  +    private XMLContentSpec fContentSpec = new XMLContentSpec();
   
  -   /** table of XMLAttributeDecl */
  -   Hashtable  fAttributeDeclTab   = new Hashtable();
  +    /** table of XMLAttributeDecl */
  +    Hashtable  fAttributeDeclTab   = new Hashtable();
   
  -   /** table of XMLElementDecl   */
  -   Hashtable   fElementDeclTab     = new Hashtable();
  +    /** table of XMLElementDecl   */
  +    Hashtable   fElementDeclTab     = new Hashtable();
   
  -   /** table of XMLNotationDecl  */
  -   Hashtable  fNotationDeclTab    = new Hashtable();
  +    /** table of XMLNotationDecl  */
  +    Hashtable  fNotationDeclTab    = new Hashtable();
   
  -   /** table of XMLSimplType     */
  -   Hashtable   fSimpleTypeTab     = new Hashtable();
  +    /** table of XMLSimplType     */
  +    Hashtable   fSimpleTypeTab     = new Hashtable();
   
  -   /** table of XMLEntityDecl    */
  -   Hashtable   fEntityDeclTab     = new Hashtable();
  +    /** table of XMLEntityDecl    */
  +    Hashtable   fEntityDeclTab     = new Hashtable();
   
  -   /** Children Content Model  Stack */
  -
  -   private short[] fOpStack     = null;
  -   private int[] fNodeIndexStack     = null;
  -   private int[] fPrevNodeIndexStack = null;
  -
  -   /** Stack depth   */
  +    /** Children content model operation stack. */
  +    private short[] fOpStack = null;
  +    
  +    /** Children content model index stack. */
  +    private int[] fNodeIndexStack = null;
  +    
  +    /** Children content model previous node index stack. */
  +    private int[] fPrevNodeIndexStack = null;
   
  -    private int fDepth               = 0;
  +    /** Stack depth   */
  +    private int fDepth = 0;
   
       /** Entity stack. */
       private boolean[] fPEntityStack = new boolean[4];
  @@ -178,732 +190,54 @@
   
       /** flag if the AttributeDecl is External. */
       private int fAttributeDeclIsExternal[][] = new int[INITIAL_CHUNK_COUNT][];
  -
  -
  -    /** Mapping for attribute declarations. */
  -   // debugging
  -
  -   /** Debug DTDGrammar. */
  -   private static final boolean DEBUG = false;
  -
  -   //
  -   // Constructors
  -   //
  -
  -   /** Default constructor. */
  -   public DTDGrammar() {
  -      this( "" );
  -   }
  -
  -   /**
  -    * 
  -    * 
  -    * @param targetNamespace 
  -    */
  -   public DTDGrammar(String targetNamespace) {
  -      setTargetNameSpace( targetNamespace );
  -   }
  -
  -   //
  -   // XMLDTDHandler methods
  -   //
  -
  -   /**
  -    * This method notifies of the start of an entity. The DTD has the 
  -    * pseudo-name of "[dtd]; and parameter entity names start with '%'.
  -    * <p>
  -    * <strong>Note:</strong> Since the DTD is an entity, the handler
  -    * will be notified of the start of the DTD entity by calling the
  -    * startEntity method with the entity name "[dtd]" <em>before</em> calling
  -    * the startDTD method.
  -    * 
  -    * @param name     The name of the entity.
  -    * @param publicId The public identifier of the entity if the entity
  -    *                 is external, null otherwise.
  -    * @param systemId The system identifier of the entity if the entity
  -    *                 is external, null otherwise.
  -    * @param encoding The auto-detected IANA encoding name of the entity
  -    *                 stream. This value will be null in those situations
  -    *                 where the entity encoding is not auto-detected (e.g.
  -    *                 internal parameter entities).
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    */
  -   public void startEntity(String name, String publicId, String systemId, 
  -                           String encoding) throws SAXException {
  -
  -       if (name.startsWith("%")) {
  -           // keep track of this entity before fEntityDepth is increased
  -           if (fPEDepth == fPEntityStack.length) {
  -               boolean[] entityarray = new boolean[fPEntityStack.length * 2];
  -               System.arraycopy(fPEntityStack, 0, entityarray, 0, fPEntityStack.length);
  -               fPEntityStack = entityarray;
  -           }
  -           fPEntityStack[fPEDepth] = fReadingExternalDTD;
  -           fPEDepth++;
  -       }
  -
  -      if ( name.equals("[dtd]") || 
  -           (name.startsWith("%") && systemId != null )) {
  -          fReadingExternalDTD = true;
  -      }
  -
  -
  -   }
  -
  -   /**
  -    * Notifies of the presence of a TextDecl line in an entity. If present,
  -    * this method will be called immediately following the startEntity call.
  -    * <p>
  -    * <strong>Note:</strong> This method is only called for external
  -    * parameter entities referenced in the DTD.
  -    * 
  -    * @param version  The XML version, or null if not specified.
  -    * @param encoding The IANA encoding name of the entity.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    */
  -   public void textDecl(String version, String encoding) throws SAXException {
  -   }
  -
  -   /**
  -    * The start of the DTD.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    */
  -   public void startDTD() throws SAXException {
  -       //Initialize stack
  -       fOpStack = null;
  -       fNodeIndexStack = null;
  -       fPrevNodeIndexStack = null;
  -   } // startDTD
  -
  -   /**
  -    * A comment.
  -    * 
  -    * @param text The text in the comment.
  -    *
  -    * @throws SAXException Thrown by application to signal an error.
  -    */
  -   public void comment(XMLString text) throws SAXException {
  -   } // comment
  -
  -   /**
  -    * A processing instruction. Processing instructions consist of a
  -    * target name and, optionally, text data. The data is only meaningful
  -    * to the application.
  -    * <p>
  -    * Typically, a processing instruction's data will contain a series
  -    * of pseudo-attributes. These pseudo-attributes follow the form of
  -    * element attributes but are <strong>not</strong> parsed or presented
  -    * to the application as anything other than text. The application is
  -    * responsible for parsing the data.
  -    * 
  -    * @param target The target.
  -    * @param data   The data or null if none specified.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    */
  -   public void processingInstruction(String target, XMLString data)
  -   throws SAXException {
  -   } // processingInstruction
  -
  -   /**
  -    * The start of the external subset.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    */
  -   public void startExternalSubset() throws SAXException {
  -   } // startExternalSubset
  -
  -   /**
  -    * The end of the external subset.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    */
  -   public void endExternalSubset() throws SAXException {
  -   } // endExternalSubset
  -
  -   /**
  -    * An element declaration.
  -    * 
  -    * @param name         The name of the element.
  -    * @param contentModel The element content model.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    */
  -   public void elementDecl(String name, String contentModel)
  -   throws SAXException {
  -      XMLElementDecl tmpElementDecl = (XMLElementDecl) fElementDeclTab.get(name) ;
  -
  -      // check if it is already defined
  -      if ( tmpElementDecl != null ) {
  -          if (tmpElementDecl.type == -1) {
  -              fCurrentElementIndex = getElementDeclIndex(name, -1);
  -          }
  -          else {
  -              // duplicate element, ignored.
  -              return;
  -          }
  -      }
  -      else {
  -          fCurrentElementIndex = createElementDecl();//create element decl
  -      }
  -
  -      XMLElementDecl elementDecl       = new XMLElementDecl();
  -      QName          elementName       = new QName(null, name, name, null);
  -      //XMLSimpleType  elementSimpleType = new XMLSimpleType();
  -
  -      elementDecl.name                  = elementName;
  -
  -      elementDecl.contentModelValidator = null;
  -      elementDecl.scope= -1;
  -      if (contentModel.equals("EMPTY")) {
  -          elementDecl.type = XMLElementDecl.TYPE_EMPTY;
  -      }
  -      else if (contentModel.equals("ANY")) {
  -          elementDecl.type = XMLElementDecl.TYPE_ANY;
  -      }
  -      else if (contentModel.startsWith("(") ) {
  -          if (contentModel.indexOf("#PCDATA") > 0 ) {
  -              elementDecl.type = XMLElementDecl.TYPE_MIXED;
  -          }
  -          else {
  -              elementDecl.type = XMLElementDecl.TYPE_CHILDREN;
  -          }
  -      }
  -
  -
  -      //add(or set) this elementDecl to the local cache
  -      this.fElementDeclTab.put(name, elementDecl );
  -
  -      fElementDecl         = elementDecl; 
  -
  -      if (fDepth == 0 && fNodeIndexStack != null) {
  -          if (elementDecl.type == XMLElementDecl.TYPE_MIXED) {
  -              int pcdata = addUniqueLeafNode(null);
  -              if (fNodeIndexStack[0] == -1) {
  -                  fNodeIndexStack[0] = pcdata;
  -              }
  -              else {
  -                  fNodeIndexStack[0] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_CHOICE, 
  -                                                          pcdata, fNodeIndexStack[0]);
  -              }
  -          }
  -          setContentSpecIndex(fCurrentElementIndex, fNodeIndexStack[fDepth]);
  -      }
  -
  -      if ( DEBUG ) {
  -          System.out.println(  "name = " + fElementDecl.name.localpart );
  -          System.out.println(  "Type = " + fElementDecl.type );
  -      }
  -
  -      setElementDecl(fCurrentElementIndex, fElementDecl );//set internal structure
  -
  -      int chunk = fCurrentElementIndex >> CHUNK_SHIFT;
  -      int index = fCurrentElementIndex & CHUNK_MASK;
  -      ensureElementDeclCapacity(chunk);
  -      fElementDeclIsExternal[chunk][index] = fReadingExternalDTD? 1 : 0;
  -
  -   } // elementDecl
  -
  -   /**
  -    * The start of an attribute list.
  -    * 
  -    * @param elementName The name of the element that this attribute
  -    *                    list is associated with.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    */
  -   public void startAttlist(String elementName) throws SAXException {
  -   } // startAttlist
  -
  -   /**
  -    * An attribute declaration.
  -    * 
  -    * @param elementName   The name of the element that this attribute
  -    *                      is associated with.
  -    * @param attributeName The name of the attribute.
  -    * @param type          The attribute type. This value will be one of
  -    *                      the following: "CDATA", "ENTITY", "ENTITIES",
  -    *                      "ENUMERATION", "ID", "IDREF", "IDREFS", 
  -    *                      "NMTOKEN", "NMTOKENS", or "NOTATION".
  -    * @param enumeration   If the type has the value "ENUMERATION", this
  -    *                      array holds the allowed attribute values;
  -    *                      otherwise, this array is null.
  -    * @param defaultType   The attribute default type. This value will be
  -    *                      one of the following: "#FIXED", "#IMPLIED",
  -    *                      "#REQUIRED", or null.
  -    * @param defaultValue  The attribute default value, or null if no
  -    *                      default value is specified.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    */
  -   public void attributeDecl(String elementName, String attributeName, String type, String[] enumeration, String defaultType, XMLString defaultValue) throws SAXException {
  -
  -      if ( this.fElementDeclTab.containsKey( (String) elementName) ) {
  -         //if ElementDecl has already being created in the Grammar then remove from table, 
  -         //this.fElementDeclTab.remove( (String) elementName );
  -      }
  -      // then it is forward reference to a element decl, create the elementDecl first.
  -      else {
  -          fCurrentElementIndex = createElementDecl();//create element decl
  -
  -          XMLElementDecl elementDecl       = new XMLElementDecl();
  -          elementDecl.name = new QName(null, elementName, elementName, null);
  -          
  -          elementDecl.scope= -1;
  -          
  -          //add(or set) this elementDecl to the local cache
  -          this.fElementDeclTab.put(elementName, elementDecl );
  -
  -          //set internal structure
  -          setElementDecl(fCurrentElementIndex, elementDecl );
  -      }
  -
  -      //Get Grammar index to grammar array
  -      int elementIndex       = getElementDeclIndex( elementName, -1 );
  -
  -      fCurrentAttributeIndex = createAttributeDecl();// Create current Attribute Decl
  -
  -      fSimpleType.clear();
  -      if ( defaultType != null ) {
  -          if ( defaultType.equals( "#FIXED") ) {
  -              fSimpleType.defaultType = fSimpleType.DEFAULT_TYPE_FIXED;
  -          } else if ( defaultType.equals( "#IMPLIED") ) {
  -              fSimpleType.defaultType = fSimpleType.DEFAULT_TYPE_IMPLIED;
  -          } else if ( defaultType.equals( "#REQUIRED") ) {
  -              fSimpleType.defaultType = fSimpleType.DEFAULT_TYPE_REQUIRED;
  -          }
  -         }
  -      if ( DEBUG ) {
  -          System.out.println("defaultvalue = " + defaultValue.toString() );
  -      }
  -      fSimpleType.defaultValue      = defaultValue.length > 0 ?  defaultValue.toString() : null;
  -      fSimpleType.enumeration       = enumeration;
  -      fSimpleType.datatypeValidator = DatatypeValidatorFactoryImpl.getDatatypeRegistry().getDatatypeValidator(type);
  -
  -      if (type.equals("CDATA")) {
  -          fSimpleType.type = XMLSimpleType.TYPE_CDATA;
  -      }
  -      else if ( type.equals("ID") ) {
  -          fSimpleType.type = XMLSimpleType.TYPE_ID;
  -      }
  -      else if ( type.startsWith("IDREF") ) {
  -          fSimpleType.type = XMLSimpleType.TYPE_IDREF;
  -          if (type.indexOf("S") > 0) {
  -              fSimpleType.list = true;
  -          }
  -      }
  -      else if (type.equals("ENTITIES")) {
  -          fSimpleType.type = XMLSimpleType.TYPE_ENTITY;
  -          fSimpleType.list = true;
  -      }
  -      else if (type.equals("ENTITY")) {
  -          fSimpleType.type = XMLSimpleType.TYPE_ENTITY;
  -      }
  -      else if (type.equals("NMTOKENS")) {
  -          fSimpleType.type = XMLSimpleType.TYPE_NMTOKEN;
  -          fSimpleType.list = true;
  -      }
  -      else if (type.equals("NMTOKEN")) {
  -          fSimpleType.type = XMLSimpleType.TYPE_NMTOKEN;
  -      }
  -      else if (type.startsWith("NOTATION") ) {
  -          fSimpleType.type = XMLSimpleType.TYPE_NOTATION;
  -          Hashtable facets = new Hashtable();
  -          facets.put(SchemaSymbols.ELT_ENUMERATION, fSimpleType.enumeration);
  -      }
  -      else if (type.startsWith("ENUMERATION") ) {
  -          fSimpleType.type = XMLSimpleType.TYPE_ENUMERATION;
  -          Hashtable facets = new Hashtable();
  -          facets.put(SchemaSymbols.ELT_ENUMERATION, fSimpleType.enumeration);
  -      }
  -
  -      fQName.clear();
  -      fQName.setValues(null, attributeName, attributeName, null);
  -
  -
  -      fAttributeDecl.clear();
  -      fAttributeDecl.setValues( fQName, fSimpleType, false );
  -
  -      setAttributeDecl( elementIndex, fCurrentAttributeIndex,
  -                           fAttributeDecl );
  -
  -      int chunk = fCurrentAttributeIndex >> CHUNK_SHIFT;
  -      int index = fCurrentAttributeIndex & CHUNK_MASK;
  -      ensureAttributeDeclCapacity(chunk);
  -      fAttributeDeclIsExternal[chunk][index] = fReadingExternalDTD ?  1 : 0;
  -   } // attributeDecl
  -
  -/**
  -    * The end of an attribute list.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    */
  -   public void endAttlist() throws SAXException {
  -   } // endAttlist
  -
  -   /**
  -    * An internal entity declaration.
  -    * 
  -    * @param name The name of the entity. Parameter entity names start with
  -    *             '%', whereas the name of a general entity is just the 
  -    *             entity name.
  -    * @param text The value of the entity.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    */
  -   public void internalEntityDecl(String name, XMLString text)
  -   throws SAXException {
  -       XMLEntityDecl  entityDecl = new XMLEntityDecl();
  -       boolean isPE = name.startsWith("%");
  -       boolean inExternal = fReadingExternalDTD;
  -
  -       entityDecl.setValues(name,null,null, null, null, isPE, inExternal);
  -       int entityIndex = getEntityDeclIndex(name);
  -       if (entityIndex == -1) {
  -         entityIndex = createEntityDecl();
  -         setEntityDecl(entityIndex, entityDecl);
  -       }
  -   } // internalEntityDecl
  -
  -   /**
  -    * An external entity declaration.
  -    * 
  -    * @param name     The name of the entity. Parameter entity names start
  -    *                 with '%', whereas the name of a general entity is just
  -    *                 the entity name.
  -    * @param publicId The public identifier of the entity or null if the
  -    *                 the entity was specified with SYSTEM.
  -    * @param systemId The system identifier of the entity.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    */
  -   public void externalEntityDecl(String name, String publicId, String systemId)
  -   throws SAXException {
  -       XMLEntityDecl  entityDecl = new XMLEntityDecl();
  -       boolean isPE = name.startsWith("%");
  -       boolean inExternal = fReadingExternalDTD;
  -       
  -       entityDecl.setValues(name,publicId,systemId, null, null, isPE, inExternal);
  -
  -       int entityIndex = getEntityDeclIndex(name);
  -       if (entityIndex == -1) {
  -         entityIndex = createEntityDecl();
  -         setEntityDecl(entityIndex, entityDecl);
  -       }
  -   } // externalEntityDecl
  -
  -   /**
  -    * An unparsed entity declaration.
  -    * 
  -    * @param name     The name of the entity.
  -    * @param publicId The public identifier of the entity, or null if not
  -    *                 specified.
  -    * @param systemId The system identifier of the entity, or null if not
  -    *                 specified.
  -    * @param notation The name of the notation.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    */
  -   public void unparsedEntityDecl(String name, String publicId, String systemId, String notation)
  -   throws SAXException {
  -       XMLEntityDecl  entityDecl = new XMLEntityDecl();
  -       boolean isPE = name.startsWith("%");
  -       boolean inExternal = fReadingExternalDTD;
  -
  -       entityDecl.setValues(name,publicId,systemId, null, notation, isPE, inExternal);
  -       int entityIndex = getEntityDeclIndex(name);
  -       if (entityIndex == -1) {
  -         entityIndex = createEntityDecl();
  -         setEntityDecl(entityIndex, entityDecl);
  -       }
  -   } // unparsedEntityDecl
  -
  -   /**
  -    * A notation declaration
  -    * 
  -    * @param name     The name of the notation.
  -    * @param publicId The public identifier of the notation, or null if not
  -    *                 specified.
  -    * @param systemId The system identifier of the notation, or null if not
  -    *                 specified.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    */
  -   public void notationDecl(String name, String publicId, String systemId)
  -   throws SAXException {
  -       XMLNotationDecl  notationDecl = new XMLNotationDecl();
  -       notationDecl.setValues(name,publicId,systemId);
  -       int notationIndex = getNotationDeclIndex(name);
  -       if (notationIndex == -1) {
  -         notationIndex = createNotationDecl();
  -         setNotationDecl(notationIndex, notationDecl);
  -       }
  -   } // notationDecl
  -
  -   /**
  -    * The start of a conditional section.
  -    * 
  -    * @param type The type of the conditional section. This value will
  -    *             either be CONDITIONAL_INCLUDE or CONDITIONAL_IGNORE.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    *
  -    * @see CONDITIONAL_INCLUDE
  -    * @see CONDITIONAL_IGNORE
  -    */
  -   public void startConditional(short type) throws SAXException {
  -   } // startConditional
  -
  -   /**
  -    * The end of a conditional section.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    */
  -   public void endConditional() throws SAXException {
  -   } // endConditional
  -
  -   /**
  -    * The end of the DTD.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    */
  -   public void endDTD() throws SAXException {
  -      /*
  -      XMLElementDecl  elementDecl;
  -      Enumeration     elements       = fElementDeclTab.elements();
  -      int             elementDeclIdx = 0;
  -      while( elements.hasMoreElements() == true ){
  -         elementDecl    = (XMLElementDecl) elements.nextElement();
  -         elementDeclIdx = getElementDeclIndex( elementDecl.name );
  -         System.out.println( "elementDeclIdx = " + elementDeclIndex );
  -         if( elementDeclIndex != -1 ){   
  -             elementDecl.contentModelValidator = this.getElementContentModelValidator(elementDeclIdx );
  -         }
  -         fCurrentElementIndex = createElementDecl();//create element decl
  -         if ( DEBUG == true ) {
  -            System.out.println(  "name = " + fElementDecl.name.localpart );
  -            System.out.println(  "Type = " + fElementDecl.type );
  -         }
  -         setElementDecl(fCurrentElementIndex, fElementDecl );//set internal structure
  -      }
  -      }
  -      */
  -   } // endDTD
  -
  -   /**
  -    * This method notifies the end of an entity. The DTD has the pseudo-name
  -    * of "[dtd]; and parameter entity names start with '%'.
  -    * <p>
  -    * <strong>Note:</strong> Since the DTD is an entity, the handler
  -    * will be notified of the end of the DTD entity by calling the
  -    * endEntity method with the entity name "[dtd]" <em>after</em> calling
  -    * the endDTD method.
  -    * 
  -    * @param name The name of the entity.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    */
  -   public void endEntity(String name) throws SAXException {
  -       if (name.equals("[dtd]")) {
  -           fReadingExternalDTD = false;
  -       }
  -       if (name.startsWith("%")) {
  -           fPEDepth--;
  -           fReadingExternalDTD = fPEntityStack[fPEDepth];
  -       }
  -   }
  -
  -   //
  -   // XMLDTDContentModelHandler methods
  -   //
  -
  -   /**
  -    * The start of a content model. Depending on the type of the content
  -    * model, specific methods may be called between the call to the
  -    * startContentModel method and the call to the endContentModel method.
  -    * 
  -    * @param elementName The name of the element.
  -    * @param type        The content model type.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    *
  -    * @see TYPE_EMPTY
  -    * @see TYPE_ANY
  -    * @see TYPE_MIXED
  -    * @see TYPE_CHILDREN
  -    */
  -   public void startContentModel(String elementName, short type)
  -   throws SAXException {
  -      XMLElementDecl elementDecl = (XMLElementDecl) this.fElementDeclTab.get( elementName);
  -      if ( elementDecl != null ) {
  -         fElementDecl = elementDecl;
  -      }
  -      fDepth = 0;
  -      initializeContentModelStack();
  -
  -   } // startContentModel
  -
  -   /**
  -    * A referenced element in a mixed content model. If the mixed content 
  -    * model only allows text content, then this method will not be called
  -    * for that model. However, if this method is called for a mixed
  -    * content model, then the zero or more occurrence count is implied.
  -    * <p>
  -    * <strong>Note:</strong> This method is only called after a call to 
  -    * the startContentModel method where the type is TYPE_MIXED.
  -    * 
  -    * @param elementName The name of the referenced element. 
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    *
  -    * @see TYPE_MIXED
  -    */
  -   int valueIndex            = -1;
  -   int prevNodeIndex         = -1;
  -   int nodeIndex             = -1;
  -   public void mixedElement(String elementName) throws SAXException {
  -       if (fNodeIndexStack[fDepth] == -1 ) {
  -           fNodeIndexStack[fDepth] = addUniqueLeafNode(elementName);
  -       }
  -       else {
  -           fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_CHOICE, 
  -                                                        fNodeIndexStack[fDepth], 
  -                                                        addUniqueLeafNode(elementName));
  -       }
  -   } // mixedElement
  -
  -   /**
  -    * The start of a children group.
  -    * <p>
  -    * <strong>Note:</strong> This method is only called after a call to
  -    * the startContentModel method where the type is TYPE_CHILDREN.
  -    * <p>
  -    * <strong>Note:</strong> Children groups can be nested and have
  -    * associated occurrence counts.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    *
  -    * @see TYPE_CHILDREN
  -    */
  -   public void childrenStartGroup() throws SAXException {
  -      fDepth++;
  -      initializeContentModelStack();
  -   } // childrenStartGroup
  -
  -   /**
  -    * A referenced element in a children content model.
  -    * 
  -    * @param elementName The name of the referenced element.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    *
  -    * @see TYPE_CHILDREN
  -    */
  -   public void childrenElement(String elementName) throws SAXException {
  -       fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_LEAF, elementName);
  -   } // childrenElement
  -
  -   /**
  -    * The separator between choices or sequences of a children content
  -    * model.
  -    * <p>
  -    * <strong>Note:</strong> This method is only called after a call to
  -    * the startContentModel method where the type is TYPE_CHILDREN.
  -    * 
  -    * @param separator The type of children separator.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    *
  -    * @see SEPARATOR_CHOICE
  -    * @see SEPARATOR_SEQUENCE
  -    * @see TYPE_CHILDREN
  -    */
  -   public void childrenSeparator(short separator) throws SAXException {
  -       if (fOpStack[fDepth] != XMLContentSpec.CONTENTSPECNODE_SEQ && separator == XMLDTDContentModelHandler.SEPARATOR_CHOICE ) {
  -           if (fPrevNodeIndexStack[fDepth] != -1) {
  -               fNodeIndexStack[fDepth] = addContentSpecNode(fOpStack[fDepth], fPrevNodeIndexStack[fDepth], fNodeIndexStack[fDepth]);
  -           }
  -           fPrevNodeIndexStack[fDepth] = fNodeIndexStack[fDepth];
  -           fOpStack[fDepth] = XMLContentSpec.CONTENTSPECNODE_CHOICE;
  -       } else if (fOpStack[fDepth] != XMLContentSpec.CONTENTSPECNODE_CHOICE && separator == XMLDTDContentModelHandler.SEPARATOR_SEQUENCE) {
  -           if (fPrevNodeIndexStack[fDepth] != -1) {
  -               fNodeIndexStack[fDepth] = addContentSpecNode(fOpStack[fDepth], fPrevNodeIndexStack[fDepth], fNodeIndexStack[fDepth]);
  -           }
  -            fPrevNodeIndexStack[fDepth] = fNodeIndexStack[fDepth];
  -            fOpStack[fDepth] = XMLContentSpec.CONTENTSPECNODE_SEQ;
  -       }
  -   } // childrenSeparator
  -
  -   /**
  -    * The occurrence count for a child in a children content model.
  -    * <p>
  -    * <strong>Note:</strong> This method is only called after a call to
  -    * the startContentModel method where the type is TYPE_CHILDREN.
  -    * 
  -    * @param occurrence The occurrence count for the last children element
  -    *                   or children group.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    *
  -    * @see OCCURS_ZERO_OR_ONE
  -    * @see OCCURS_ZERO_OR_MORE
  -    * @see OCCURS_ONE_OR_MORE
  -    * @see TYPE_CHILDREN
  -    */
  -   public void childrenOccurrence(short occurrence) throws SAXException {
  -      if ( occurrence == XMLDTDContentModelHandler.OCCURS_ZERO_OR_ONE ) {
  -         fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE, fNodeIndexStack[fDepth], -1);
  -      } else if ( occurrence == XMLDTDContentModelHandler.OCCURS_ZERO_OR_MORE ) {
  -         fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE, fNodeIndexStack[fDepth], -1 );
  -      } else if ( occurrence == XMLDTDContentModelHandler.OCCURS_ONE_OR_MORE) {
  -         fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE, fNodeIndexStack[fDepth], -1 );
  -      }
  -
  -   } // childrenOccurrence
  -
  -   /**
  -    * The end of a children group.
  -    * <p>
  -    * <strong>Note:</strong> This method is only called after a call to
  -    * the startContentModel method where the type is TYPE_CHILDREN.
  -    *
  -    * @see TYPE_CHILDREN
  -    */
  -   public void childrenEndGroup() throws SAXException {
  -       if (fPrevNodeIndexStack[fDepth] != -1) {
  -           fNodeIndexStack[fDepth] = addContentSpecNode(fOpStack[fDepth], fPrevNodeIndexStack[fDepth], fNodeIndexStack[fDepth]);
  -       }
  -       int nodeIndex = fNodeIndexStack[fDepth--];
  -       fNodeIndexStack[fDepth] = nodeIndex;
  -   } // childrenEndGroup
  -
  -   /**
  -    * The end of a content model.
  -    *
  -    * @throws SAXException Thrown by handler to signal an error.
  -    */
  -   public void endContentModel() throws SAXException {
   
  -   } // endContentModel
  +    // for mixedElement method
   
  -
  -    // getters for isExternals 
  +    int valueIndex            = -1;
  +    int prevNodeIndex         = -1;
  +    int nodeIndex             = -1;
  +
  +    //
  +    // Constructors
  +    //
  +
  +    /** Default constructor. */
  +    public DTDGrammar() {
  +        setTargetNamespace("");
  +    } // <init>()
  +
  +    //
  +    // Public methods
  +    //
  +
  +    /**
  +     * Returns true if the specified element declaration is external.
  +     *
  +     * @param elementDeclIndex The element declaration index.
  +     */
       public boolean getElementDeclIsExternal(int elementDeclIndex) {
  +
           if (elementDeclIndex < 0) {
               return false;
           }
  +
           int chunk = elementDeclIndex >> CHUNK_SHIFT;
           int index = elementDeclIndex & CHUNK_MASK;
           return (fElementDeclIsExternal[chunk][index] != 0);
  -    }
   
  +    } // getElementDeclIsExternal(int):boolean
  +
  +    /**
  +     * Returns true if the specified attribute declaration is external.
  +     *
  +     * @param attributeDeclIndex Attribute declaration index.
  +     */
       public boolean getAttributeDeclIsExternal(int attributeDeclIndex) {
  +
           if (attributeDeclIndex < 0) {
               return false;
           }
  +
           int chunk = attributeDeclIndex >> CHUNK_SHIFT;
           int index = attributeDeclIndex & CHUNK_MASK;
           return (fAttributeDeclIsExternal[chunk][index] != 0);
  @@ -926,124 +260,768 @@
           return -1;
       } // getAttributeDeclIndex (int,QName)
   
  -   //
  -   //
  -   // private methods
  -   //
  -   //
  -
  -
  -   /**
  -  * Create an XMLContentSpec for a single non-leaf
  -  * 
  -  * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_*
  -  * @param nodeValue handle to an XMLContentSpec
  -  * @return handle to the newly create XMLContentSpec
  -  * @exception java.lang.Exception
  -  */
  -
  -   private int addContentSpecNode(short nodeType, 
  -                                  String nodeValue)  {
  -
  -      // create content spec node
  -      int contentSpecIndex = createContentSpec();
  -
  -      // set content spec node values
  -
  -
  -      fContentSpec.setValues(nodeType, nodeValue, null);
  -      setContentSpec(contentSpecIndex, fContentSpec);
  -
  -      // return index 
  -      return contentSpecIndex;
  -
  -   } // addContentSpecNode(int,int):int
  -
  -
  -   /**
  -    * create an XMLContentSpec for a leaf
  -    *
  -    * @param   elementName  the name (Element) for the node
  -    * @return handle to the newly create XMLContentSpec
  -    * @exception java.lang.Exception
  -    */
  -
  -   private int addUniqueLeafNode(String elementName) {
  -
  -      // create content spec node
  -      int contentSpecIndex = createContentSpec();
  -
  -      // set content spec node values
  -
  -      fContentSpec.setValues( XMLContentSpec.CONTENTSPECNODE_LEAF, 
  -                              elementName, null);
  -      setContentSpec(contentSpecIndex, fContentSpec);
  -
  -      // return index 
  -      return contentSpecIndex;
  -
  -   } // addUniqueLeafNode(int):int
  -
  -   /**
  -    * Create an XMLContentSpec for a two child leaf
  -    *
  -    * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_*
  -    * @param leftNodeIndex handle to an XMLContentSpec
  -    * @param rightNodeIndex handle to an XMLContentSpec
  -    * @return handle to the newly create XMLContentSpec
  -    * @exception java.lang.Exception
  -    */
  -   private int addContentSpecNode(short nodeType, 
  -                                  int leftNodeIndex, 
  -                                  int rightNodeIndex) {
  -
  -      // create content spec node
  -      int contentSpecIndex = createContentSpec();
  -
  -      // set content spec node values
  -      int[] leftIntArray  = new int[1]; 
  -      int[] rightIntArray = new int[1];
  -
  -      leftIntArray[0]      = leftNodeIndex;
  -      rightIntArray[0]    = rightNodeIndex;
  -      fContentSpec.setValues(nodeType, 
  -                             leftIntArray, rightIntArray);
  -
  -      setContentSpec(contentSpecIndex, fContentSpec);
  -
  -      // return index 
  -      return contentSpecIndex;
  -
  -   } // addContentSpecNode(int,int,int):int
  -
  -
  -   // intialize content model stack
  -   private void initializeContentModelStack() {
  -      if (fOpStack == null) {
  -         fOpStack = new short[8];
  -         fNodeIndexStack = new int[8];
  -         fPrevNodeIndexStack = new int[8];
  -      } else if (fDepth == fOpStack.length) {
  -         short[] newStack = new short[fDepth * 2];
  -         System.arraycopy(fOpStack, 0, newStack, 0, fDepth);
  -         fOpStack = newStack;
  -         int[]   newIntStack = new int[fDepth * 2];
  -         System.arraycopy(fNodeIndexStack, 0, newIntStack, 0, fDepth);
  -         fNodeIndexStack = newIntStack;
  -         newIntStack = new int[fDepth * 2];
  -         System.arraycopy(fPrevNodeIndexStack, 0, newIntStack, 0, fDepth);
  -         fPrevNodeIndexStack = newIntStack;
  -      }
  -      fOpStack[fDepth] = -1;
  -      fNodeIndexStack[fDepth] = -1;
  -      fPrevNodeIndexStack[fDepth] = -1;
  -   }
  +    //
  +    // XMLDTDHandler methods
  +    //
  +
  +    /**
  +     * The start of the DTD.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     */
  +    public void startDTD() throws SAXException {
  +        //Initialize stack
  +        fOpStack = null;
  +        fNodeIndexStack = null;
  +        fPrevNodeIndexStack = null;
  +    } // startDTD()
  +
  +    /**
  +     * This method notifies of the start of an entity. The DTD has the 
  +     * pseudo-name of "[dtd]; and parameter entity names start with '%'.
  +     * <p>
  +     * <strong>Note:</strong> Since the DTD is an entity, the handler
  +     * will be notified of the start of the DTD entity by calling the
  +     * startEntity method with the entity name "[dtd]" <em>before</em> calling
  +     * the startDTD method.
  +     * 
  +     * @param name     The name of the entity.
  +     * @param publicId The public identifier of the entity if the entity
  +     *                 is external, null otherwise.
  +     * @param systemId The system identifier of the entity if the entity
  +     *                 is external, null otherwise.
  +     * @param encoding The auto-detected IANA encoding name of the entity
  +     *                 stream. This value will be null in those situations
  +     *                 where the entity encoding is not auto-detected (e.g.
  +     *                 internal parameter entities).
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     */
  +    public void startEntity(String name, String publicId, String systemId, 
  +                            String encoding) throws SAXException {
  +
  +        if (name.startsWith("%")) {
  +            // keep track of this entity before fEntityDepth is increased
  +            if (fPEDepth == fPEntityStack.length) {
  +                boolean[] entityarray = new boolean[fPEntityStack.length * 2];
  +                System.arraycopy(fPEntityStack, 0, entityarray, 0, fPEntityStack.length);
  +                fPEntityStack = entityarray;
  +            }
  +            fPEntityStack[fPEDepth] = fReadingExternalDTD;
  +            fPEDepth++;
  +        }
   
  -    
  -   // ensure capacity
  +        if ( name.equals("[dtd]") || 
  +            (name.startsWith("%") && systemId != null )) {
  +            fReadingExternalDTD = true;
  +        }
  +
  +    } // startEntity(String,String,String,String)
  +
  +    public void textDecl(String version, String encoding) throws SAXException {}
  +    public void comment(XMLString text) throws SAXException {}
  +    public void processingInstruction(String target, XMLString data) throws SAXException {}
  +
  +    /**
  +     * An element declaration.
  +     * 
  +     * @param name         The name of the element.
  +     * @param contentModel The element content model.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     */
  +    public void elementDecl(String name, String contentModel)
  +        throws SAXException {
  +
  +        XMLElementDecl tmpElementDecl = (XMLElementDecl) fElementDeclTab.get(name) ;
  +
  +        // check if it is already defined
  +        if ( tmpElementDecl != null ) {
  +            if (tmpElementDecl.type == -1) {
  +                fCurrentElementIndex = getElementDeclIndex(name, -1);
  +            }
  +            else {
  +                // duplicate element, ignored.
  +                return;
  +            }
  +        }
  +        else {
  +            fCurrentElementIndex = createElementDecl();//create element decl
  +        }
  +
  +        XMLElementDecl elementDecl       = new XMLElementDecl();
  +        QName          elementName       = new QName(null, name, name, null);
  +        //XMLSimpleType  elementSimpleType = new XMLSimpleType();
  +
  +        elementDecl.name.setValues(elementName);
  +
  +        elementDecl.contentModelValidator = null;
  +        elementDecl.scope= -1;
  +        if (contentModel.equals("EMPTY")) {
  +            elementDecl.type = XMLElementDecl.TYPE_EMPTY;
  +        }
  +        else if (contentModel.equals("ANY")) {
  +            elementDecl.type = XMLElementDecl.TYPE_ANY;
  +        }
  +        else if (contentModel.startsWith("(") ) {
  +            if (contentModel.indexOf("#PCDATA") > 0 ) {
  +                elementDecl.type = XMLElementDecl.TYPE_MIXED;
  +            }
  +            else {
  +                elementDecl.type = XMLElementDecl.TYPE_CHILDREN;
  +            }
  +        }
  +
  +
  +        //add(or set) this elementDecl to the local cache
  +        this.fElementDeclTab.put(name, elementDecl );
  +
  +        fElementDecl         = elementDecl; 
  +
  +        if (fDepth == 0 && fNodeIndexStack != null) {
  +            if (elementDecl.type == XMLElementDecl.TYPE_MIXED) {
  +                int pcdata = addUniqueLeafNode(null);
  +                if (fNodeIndexStack[0] == -1) {
  +                    fNodeIndexStack[0] = pcdata;
  +                }
  +                else {
  +                    fNodeIndexStack[0] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_CHOICE, 
  +                                                            pcdata, fNodeIndexStack[0]);
  +                }
  +            }
  +            setContentSpecIndex(fCurrentElementIndex, fNodeIndexStack[fDepth]);
  +        }
  +
  +        if ( DEBUG ) {
  +            System.out.println(  "name = " + fElementDecl.name.localpart );
  +            System.out.println(  "Type = " + fElementDecl.type );
  +        }
  +
  +        setElementDecl(fCurrentElementIndex, fElementDecl );//set internal structure
  +
  +        int chunk = fCurrentElementIndex >> CHUNK_SHIFT;
  +        int index = fCurrentElementIndex & CHUNK_MASK;
  +        ensureElementDeclCapacity(chunk);
  +        fElementDeclIsExternal[chunk][index] = fReadingExternalDTD? 1 : 0;
  +
  +    } // elementDecl(String,String)
  +
  +    /**
  +     * The start of an attribute list.
  +     * 
  +     * @param elementName The name of the element that this attribute
  +     *                    list is associated with.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     */
  +    public void startAttlist(String elementName) throws SAXException {
  +        // no-op
  +    } // startAttlist
  +
  +    /**
  +     * An attribute declaration.
  +     * 
  +     * @param elementName   The name of the element that this attribute
  +     *                      is associated with.
  +     * @param attributeName The name of the attribute.
  +     * @param type          The attribute type. This value will be one of
  +     *                      the following: "CDATA", "ENTITY", "ENTITIES",
  +     *                      "ENUMERATION", "ID", "IDREF", "IDREFS", 
  +     *                      "NMTOKEN", "NMTOKENS", or "NOTATION".
  +     * @param enumeration   If the type has the value "ENUMERATION", this
  +     *                      array holds the allowed attribute values;
  +     *                      otherwise, this array is null.
  +     * @param defaultType   The attribute default type. This value will be
  +     *                      one of the following: "#FIXED", "#IMPLIED",
  +     *                      "#REQUIRED", or null.
  +     * @param defaultValue  The attribute default value, or null if no
  +     *                      default value is specified.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     */
  +    public void attributeDecl(String elementName, String attributeName, 
  +                              String type, String[] enumeration, 
  +                              String defaultType, XMLString defaultValue) 
  +        throws SAXException {
  +
  +        if ( this.fElementDeclTab.containsKey( (String) elementName) ) {
  +            //if ElementDecl has already being created in the Grammar then remove from table, 
  +            //this.fElementDeclTab.remove( (String) elementName );
  +        }
  +        // then it is forward reference to a element decl, create the elementDecl first.
  +        else {
  +            fCurrentElementIndex = createElementDecl();//create element decl
   
  +            XMLElementDecl elementDecl       = new XMLElementDecl();
  +            elementDecl.name.setValues(null, elementName, elementName, null);
  +          
  +            elementDecl.scope= -1;
  +          
  +            //add(or set) this elementDecl to the local cache
  +            this.fElementDeclTab.put(elementName, elementDecl );
  +
  +            //set internal structure
  +            setElementDecl(fCurrentElementIndex, elementDecl );
  +        }
  +
  +        //Get Grammar index to grammar array
  +        int elementIndex       = getElementDeclIndex( elementName, -1 );
  +
  +        fCurrentAttributeIndex = createAttributeDecl();// Create current Attribute Decl
  +
  +        fSimpleType.clear();
  +        if ( defaultType != null ) {
  +            if ( defaultType.equals( "#FIXED") ) {
  +                fSimpleType.defaultType = fSimpleType.DEFAULT_TYPE_FIXED;
  +            } else if ( defaultType.equals( "#IMPLIED") ) {
  +                fSimpleType.defaultType = fSimpleType.DEFAULT_TYPE_IMPLIED;
  +            } else if ( defaultType.equals( "#REQUIRED") ) {
  +                fSimpleType.defaultType = fSimpleType.DEFAULT_TYPE_REQUIRED;
  +            }
  +        }
  +        if ( DEBUG ) {
  +            System.out.println("defaultvalue = " + defaultValue.toString() );
  +        }
  +        fSimpleType.defaultValue      = defaultValue.length >= 0 ?  defaultValue.toString() : null;
  +        fSimpleType.enumeration       = enumeration;
  +        fSimpleType.datatypeValidator = DatatypeValidatorFactoryImpl.getDatatypeRegistry().getDatatypeValidator(type);
  +
  +        if (type.equals("CDATA")) {
  +            fSimpleType.type = XMLSimpleType.TYPE_CDATA;
  +        }
  +        else if ( type.equals("ID") ) {
  +            fSimpleType.type = XMLSimpleType.TYPE_ID;
  +        }
  +        else if ( type.startsWith("IDREF") ) {
  +            fSimpleType.type = XMLSimpleType.TYPE_IDREF;
  +            if (type.indexOf("S") > 0) {
  +                fSimpleType.list = true;
  +            }
  +        }
  +        else if (type.equals("ENTITIES")) {
  +            fSimpleType.type = XMLSimpleType.TYPE_ENTITY;
  +            fSimpleType.list = true;
  +        }
  +        else if (type.equals("ENTITY")) {
  +            fSimpleType.type = XMLSimpleType.TYPE_ENTITY;
  +        }
  +        else if (type.equals("NMTOKENS")) {
  +            fSimpleType.type = XMLSimpleType.TYPE_NMTOKEN;
  +            fSimpleType.list = true;
  +        }
  +        else if (type.equals("NMTOKEN")) {
  +            fSimpleType.type = XMLSimpleType.TYPE_NMTOKEN;
  +        }
  +        else if (type.startsWith("NOTATION") ) {
  +            fSimpleType.type = XMLSimpleType.TYPE_NOTATION;
  +            Hashtable facets = new Hashtable();
  +            facets.put(SchemaSymbols.ELT_ENUMERATION, fSimpleType.enumeration);
  +        }
  +        else if (type.startsWith("ENUMERATION") ) {
  +            fSimpleType.type = XMLSimpleType.TYPE_ENUMERATION;
  +            Hashtable facets = new Hashtable();
  +            facets.put(SchemaSymbols.ELT_ENUMERATION, fSimpleType.enumeration);
  +        }
  +
  +        fQName.setValues(null, attributeName, attributeName, null);
  +        fAttributeDecl.setValues( fQName, fSimpleType, false );
  +
  +        setAttributeDecl( elementIndex, fCurrentAttributeIndex,
  +                           fAttributeDecl );
  +
  +        int chunk = fCurrentAttributeIndex >> CHUNK_SHIFT;
  +        int index = fCurrentAttributeIndex & CHUNK_MASK;
  +        ensureAttributeDeclCapacity(chunk);
  +        fAttributeDeclIsExternal[chunk][index] = fReadingExternalDTD ?  1 : 0;
  +
  +    } // attributeDecl(String,String,String,String[],String,XMLString)
  +
  +    /**
  +     * The end of an attribute list.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     */
  +    public void endAttlist() throws SAXException {
  +        // no-op
  +    } // endAttlist()
  +
  +    /**
  +     * An internal entity declaration.
  +     * 
  +     * @param name The name of the entity. Parameter entity names start with
  +     *             '%', whereas the name of a general entity is just the 
  +     *             entity name.
  +     * @param text The value of the entity.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     */
  +    public void internalEntityDecl(String name, XMLString text)
  +        throws SAXException {
  +
  +        XMLEntityDecl  entityDecl = new XMLEntityDecl();
  +        boolean isPE = name.startsWith("%");
  +        boolean inExternal = fReadingExternalDTD;
  +
  +        entityDecl.setValues(name,null,null, null, null, isPE, inExternal);
  +        int entityIndex = getEntityDeclIndex(name);
  +        if (entityIndex == -1) {
  +            entityIndex = createEntityDecl();
  +            setEntityDecl(entityIndex, entityDecl);
  +        }
  +
  +    } // internalEntityDecl(String,XMLString)
  +
  +    /**
  +     * An external entity declaration.
  +     * 
  +     * @param name     The name of the entity. Parameter entity names start
  +     *                 with '%', whereas the name of a general entity is just
  +     *                 the entity name.
  +     * @param publicId The public identifier of the entity or null if the
  +     *                 the entity was specified with SYSTEM.
  +     * @param systemId The system identifier of the entity.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     */
  +    public void externalEntityDecl(String name, String publicId, 
  +                                   String systemId) throws SAXException {
  +
  +        XMLEntityDecl  entityDecl = new XMLEntityDecl();
  +        boolean isPE = name.startsWith("%");
  +        boolean inExternal = fReadingExternalDTD;
  +       
  +        entityDecl.setValues(name,publicId,systemId, null, null, isPE, inExternal);
  +
  +        int entityIndex = getEntityDeclIndex(name);
  +        if (entityIndex == -1) {
  +            entityIndex = createEntityDecl();
  +            setEntityDecl(entityIndex, entityDecl);
  +        }
  +
  +    } // externalEntityDecl(String,String,String)
  +
  +    /**
  +     * An unparsed entity declaration.
  +     * 
  +     * @param name     The name of the entity.
  +     * @param publicId The public identifier of the entity, or null if not
  +     *                 specified.
  +     * @param systemId The system identifier of the entity, or null if not
  +     *                 specified.
  +     * @param notation The name of the notation.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     */
  +    public void unparsedEntityDecl(String name, String publicId, 
  +                                   String systemId, String notation)
  +        throws SAXException {
  +
  +        XMLEntityDecl  entityDecl = new XMLEntityDecl();
  +        boolean isPE = name.startsWith("%");
  +        boolean inExternal = fReadingExternalDTD;
  +
  +        entityDecl.setValues(name,publicId,systemId, null, notation, isPE, inExternal);
  +        int entityIndex = getEntityDeclIndex(name);
  +        if (entityIndex == -1) {
  +            entityIndex = createEntityDecl();
  +            setEntityDecl(entityIndex, entityDecl);
  +        }
  +
  +    } // unparsedEntityDecl(String,String,String,String)
  +
  +    /**
  +     * A notation declaration
  +     * 
  +     * @param name     The name of the notation.
  +     * @param publicId The public identifier of the notation, or null if not
  +     *                 specified.
  +     * @param systemId The system identifier of the notation, or null if not
  +     *                 specified.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     */
  +    public void notationDecl(String name, String publicId, String systemId)
  +        throws SAXException {
  +
  +        XMLNotationDecl  notationDecl = new XMLNotationDecl();
  +        notationDecl.setValues(name,publicId,systemId);
  +        int notationIndex = getNotationDeclIndex(name);
  +        if (notationIndex == -1) {
  +            notationIndex = createNotationDecl();
  +            setNotationDecl(notationIndex, notationDecl);
  +        }
  +
  +    } // notationDecl(String,String,String)
  +
  +    /**
  +     * The start of a conditional section.
  +     * 
  +     * @param type The type of the conditional section. This value will
  +     *             either be CONDITIONAL_INCLUDE or CONDITIONAL_IGNORE.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     *
  +     * @see CONDITIONAL_INCLUDE
  +     * @see CONDITIONAL_IGNORE
  +     */
  +    public void startConditional(short type) throws SAXException {
  +        // no-op
  +    } // startConditional(short)
  +
  +    /**
  +     * The end of a conditional section.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     */
  +    public void endConditional() throws SAXException {
  +        // no-op
  +    } // endConditional()
  +
  +    /**
  +     * The end of the DTD.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     */
  +    public void endDTD() throws SAXException {
  +
  +        // REVISIT: What is this for? -Ac
  +        /*
  +        XMLElementDecl  elementDecl;
  +        Enumeration     elements       = fElementDeclTab.elements();
  +        int             elementDeclIdx = 0;
  +        while( elements.hasMoreElements() == true ) {
  +            elementDecl    = (XMLElementDecl) elements.nextElement();
  +            elementDeclIdx = getElementDeclIndex( elementDecl.name );
  +            System.out.println( "elementDeclIdx = " + elementDeclIndex );
  +            if( elementDeclIndex != -1 ) {   
  +                elementDecl.contentModelValidator = this.getElementContentModelValidator(elementDeclIdx );
  +            }
  +            fCurrentElementIndex = createElementDecl();//create element decl
  +            if ( DEBUG == true ) {
  +                System.out.println(  "name = " + fElementDecl.name.localpart );
  +                System.out.println(  "Type = " + fElementDecl.type );
  +            }
  +            setElementDecl(fCurrentElementIndex, fElementDecl );//set internal structure
  +        }
  +        */
  +
  +    } // endDTD()
  +
  +    /**
  +     * This method notifies the end of an entity. The DTD has the pseudo-name
  +     * of "[dtd]; and parameter entity names start with '%'.
  +     * <p>
  +     * <strong>Note:</strong> Since the DTD is an entity, the handler
  +     * will be notified of the end of the DTD entity by calling the
  +     * endEntity method with the entity name "[dtd]" <em>after</em> calling
  +     * the endDTD method.
  +     * 
  +     * @param name The name of the entity.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     */
  +    public void endEntity(String name) throws SAXException {
  +
  +        if (name.equals("[dtd]")) {
  +            fReadingExternalDTD = false;
  +        }
  +        if (name.startsWith("%")) {
  +            fPEDepth--;
  +            fReadingExternalDTD = fPEntityStack[fPEDepth];
  +        }
  +
  +    } // endEntity(String)
  +
  +    //
  +    // XMLDTDContentModelHandler methods
  +    //
  +
  +    /**
  +     * The start of a content model. Depending on the type of the content
  +     * model, specific methods may be called between the call to the
  +     * startContentModel method and the call to the endContentModel method.
  +     * 
  +     * @param elementName The name of the element.
  +     * @param type        The content model type.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     *
  +     * @see TYPE_EMPTY
  +     * @see TYPE_ANY
  +     * @see TYPE_MIXED
  +     * @see TYPE_CHILDREN
  +     */
  +    public void startContentModel(String elementName, short type)
  +        throws SAXException {
  +      
  +        XMLElementDecl elementDecl = (XMLElementDecl) this.fElementDeclTab.get( elementName);
  +        if ( elementDecl != null ) {
  +            fElementDecl = elementDecl;
  +        }
  +        fDepth = 0;
  +        initializeContentModelStack();
  +
  +    } // startContentModel(String,short)
  +
  +    /**
  +     * A referenced element in a mixed content model. If the mixed content 
  +     * model only allows text content, then this method will not be called
  +     * for that model. However, if this method is called for a mixed
  +     * content model, then the zero or more occurrence count is implied.
  +     * <p>
  +     * <strong>Note:</strong> This method is only called after a call to 
  +     * the startContentModel method where the type is TYPE_MIXED.
  +     * 
  +     * @param elementName The name of the referenced element. 
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     *
  +     * @see TYPE_MIXED
  +     */
  +    public void mixedElement(String elementName) throws SAXException {
  +
  +        if (fNodeIndexStack[fDepth] == -1 ) {
  +            fNodeIndexStack[fDepth] = addUniqueLeafNode(elementName);
  +        }
  +        else {
  +            fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_CHOICE, 
  +                                                         fNodeIndexStack[fDepth], 
  +                                                         addUniqueLeafNode(elementName));
  +        }
  +
  +    } // mixedElement(String)
  +
  +    /**
  +     * The start of a children group.
  +     * <p>
  +     * <strong>Note:</strong> This method is only called after a call to
  +     * the startContentModel method where the type is TYPE_CHILDREN.
  +     * <p>
  +     * <strong>Note:</strong> Children groups can be nested and have
  +     * associated occurrence counts.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     *
  +     * @see TYPE_CHILDREN
  +     */
  +    public void childrenStartGroup() throws SAXException {
  +        fDepth++;
  +        initializeContentModelStack();
  +    } // childrenStartGroup()
  +
  +    /**
  +     * A referenced element in a children content model.
  +     * 
  +     * @param elementName The name of the referenced element.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     *
  +     * @see TYPE_CHILDREN
  +     */
  +    public void childrenElement(String elementName) throws SAXException {
  +        fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_LEAF, elementName);
  +    } // childrenElement(String)
  +
  +    /**
  +     * The separator between choices or sequences of a children content
  +     * model.
  +     * <p>
  +     * <strong>Note:</strong> This method is only called after a call to
  +     * the startContentModel method where the type is TYPE_CHILDREN.
  +     * 
  +     * @param separator The type of children separator.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     *
  +     * @see SEPARATOR_CHOICE
  +     * @see SEPARATOR_SEQUENCE
  +     * @see TYPE_CHILDREN
  +     */
  +    public void childrenSeparator(short separator) throws SAXException {
  +
  +        if (fOpStack[fDepth] != XMLContentSpec.CONTENTSPECNODE_SEQ && separator == XMLDTDContentModelHandler.SEPARATOR_CHOICE ) {
  +            if (fPrevNodeIndexStack[fDepth] != -1) {
  +                fNodeIndexStack[fDepth] = addContentSpecNode(fOpStack[fDepth], fPrevNodeIndexStack[fDepth], fNodeIndexStack[fDepth]);
  +            }
  +            fPrevNodeIndexStack[fDepth] = fNodeIndexStack[fDepth];
  +            fOpStack[fDepth] = XMLContentSpec.CONTENTSPECNODE_CHOICE;
  +        } else if (fOpStack[fDepth] != XMLContentSpec.CONTENTSPECNODE_CHOICE && separator == XMLDTDContentModelHandler.SEPARATOR_SEQUENCE) {
  +            if (fPrevNodeIndexStack[fDepth] != -1) {
  +                fNodeIndexStack[fDepth] = addContentSpecNode(fOpStack[fDepth], fPrevNodeIndexStack[fDepth], fNodeIndexStack[fDepth]);
  +            }
  +            fPrevNodeIndexStack[fDepth] = fNodeIndexStack[fDepth];
  +            fOpStack[fDepth] = XMLContentSpec.CONTENTSPECNODE_SEQ;
  +        }
  +
  +    } // childrenSeparator(short)
  +
  +    /**
  +     * The occurrence count for a child in a children content model.
  +     * <p>
  +     * <strong>Note:</strong> This method is only called after a call to
  +     * the startContentModel method where the type is TYPE_CHILDREN.
  +     * 
  +     * @param occurrence The occurrence count for the last children element
  +     *                   or children group.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     *
  +     * @see OCCURS_ZERO_OR_ONE
  +     * @see OCCURS_ZERO_OR_MORE
  +     * @see OCCURS_ONE_OR_MORE
  +     * @see TYPE_CHILDREN
  +     */
  +    public void childrenOccurrence(short occurrence) throws SAXException {
  +
  +        if ( occurrence == XMLDTDContentModelHandler.OCCURS_ZERO_OR_ONE ) {
  +            fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE, fNodeIndexStack[fDepth], -1);
  +        } else if ( occurrence == XMLDTDContentModelHandler.OCCURS_ZERO_OR_MORE ) {
  +            fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE, fNodeIndexStack[fDepth], -1 );
  +        } else if ( occurrence == XMLDTDContentModelHandler.OCCURS_ONE_OR_MORE) {
  +            fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE, fNodeIndexStack[fDepth], -1 );
  +        }
  +
  +    } // childrenOccurrence(short)
  +
  +    /**
  +     * The end of a children group.
  +     * <p>
  +     * <strong>Note:</strong> This method is only called after a call to
  +     * the startContentModel method where the type is TYPE_CHILDREN.
  +     *
  +     * @see TYPE_CHILDREN
  +     */
  +    public void childrenEndGroup() throws SAXException {
  +
  +        if (fPrevNodeIndexStack[fDepth] != -1) {
  +            fNodeIndexStack[fDepth] = addContentSpecNode(fOpStack[fDepth], fPrevNodeIndexStack[fDepth], fNodeIndexStack[fDepth]);
  +        }
  +        int nodeIndex = fNodeIndexStack[fDepth--];
  +        fNodeIndexStack[fDepth] = nodeIndex;
  +
  +    } // childrenEndGroup()
  +
  +    /**
  +     * The end of a content model.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     */
  +    public void endContentModel() throws SAXException {
  +        // no-op
  +    } // endContentModel()
  +
  +    //
  +    // Grammar methods
  +    //
  +
  +    /** Returns the element decl index. */
  +    public int getElementDeclIndex(QName elementDeclQName, int scope) {
  +        return getElementDeclIndex(elementDeclQName.rawname, scope);
  +    } // getElementDeclIndex(QName,int):int
  +   
  +    //
  +    // Protected methods
  +    //
  +
  +    /**
  +     * Create an XMLContentSpec for a single non-leaf
  +     * 
  +     * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_*
  +     * @param nodeValue handle to an XMLContentSpec
  +     * @return handle to the newly create XMLContentSpec
  +     * @exception java.lang.Exception
  +     */
  +    protected int addContentSpecNode(short nodeType, String nodeValue) {
  +
  +        // create content spec node
  +        int contentSpecIndex = createContentSpec();
  +
  +        // set content spec node values
  +        fContentSpec.setValues(nodeType, nodeValue, null);
  +        setContentSpec(contentSpecIndex, fContentSpec);
  +
  +        // return index 
  +        return contentSpecIndex;
  +
  +    } // addContentSpecNode(short,String):int
  +
  +    /**
  +     * create an XMLContentSpec for a leaf
  +     *
  +     * @param   elementName  the name (Element) for the node
  +     * @return handle to the newly create XMLContentSpec
  +     * @exception java.lang.Exception
  +     */
  +    protected int addUniqueLeafNode(String elementName) {
  +
  +        // create content spec node
  +        int contentSpecIndex = createContentSpec();
  +
  +        // set content spec node values
  +        fContentSpec.setValues( XMLContentSpec.CONTENTSPECNODE_LEAF, 
  +                                elementName, null);
  +        setContentSpec(contentSpecIndex, fContentSpec);
  +
  +        // return index 
  +        return contentSpecIndex;
  +
  +    } // addUniqueLeafNode(String):int
  +
  +    /**
  +     * Create an XMLContentSpec for a two child leaf
  +     *
  +     * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_*
  +     * @param leftNodeIndex handle to an XMLContentSpec
  +     * @param rightNodeIndex handle to an XMLContentSpec
  +     * @return handle to the newly create XMLContentSpec
  +     * @exception java.lang.Exception
  +     */
  +    protected int addContentSpecNode(short nodeType, 
  +                                     int leftNodeIndex, int rightNodeIndex) {
  +
  +        // create content spec node
  +        int contentSpecIndex = createContentSpec();
  +
  +        // set content spec node values
  +        int[] leftIntArray  = new int[1]; 
  +        int[] rightIntArray = new int[1];
  +
  +        leftIntArray[0]      = leftNodeIndex;
  +        rightIntArray[0]    = rightNodeIndex;
  +        fContentSpec.setValues(nodeType, leftIntArray, rightIntArray);
  +        setContentSpec(contentSpecIndex, fContentSpec);
  +
  +        // return index 
  +        return contentSpecIndex;
  +
  +    } // addContentSpecNode(short,int,int):int
  +
  +    protected void initializeContentModelStack() {
  +
  +        if (fOpStack == null) {
  +            fOpStack = new short[8];
  +            fNodeIndexStack = new int[8];
  +            fPrevNodeIndexStack = new int[8];
  +        } else if (fDepth == fOpStack.length) {
  +            short[] newStack = new short[fDepth * 2];
  +            System.arraycopy(fOpStack, 0, newStack, 0, fDepth);
  +            fOpStack = newStack;
  +            int[]   newIntStack = new int[fDepth * 2];
  +            System.arraycopy(fNodeIndexStack, 0, newIntStack, 0, fDepth);
  +            fNodeIndexStack = newIntStack;
  +            newIntStack = new int[fDepth * 2];
  +            System.arraycopy(fPrevNodeIndexStack, 0, newIntStack, 0, fDepth);
  +            fPrevNodeIndexStack = newIntStack;
  +        }
  +        fOpStack[fDepth] = -1;
  +        fNodeIndexStack[fDepth] = -1;
  +        fPrevNodeIndexStack[fDepth] = -1;
  +
  +    } // initializeContentModelStack()
  +
  +    
       /** Ensures storage for element declaration mappings. */
  -    private boolean ensureElementDeclCapacity(int chunk) {
  +    protected boolean ensureElementDeclCapacity(int chunk) {
           try {
               return fElementDeclIsExternal[chunk][0] == 0;
           } catch (ArrayIndexOutOfBoundsException ex) {
  @@ -1057,7 +1035,7 @@
       }
   
       /** Ensures storage for attribute declaration mappings. */
  -    private boolean ensureAttributeDeclCapacity(int chunk) {
  +    protected boolean ensureAttributeDeclCapacity(int chunk) {
           try {
               return fAttributeDeclIsExternal[chunk][0] == 0;
           } catch (ArrayIndexOutOfBoundsException ex) {
  @@ -1070,14 +1048,11 @@
           return true;
       }
   
  -    // resize initial chunk
  -
       /** Resizes chunked integer arrays. */
  -    private int[][] resize(int array[][], int newsize) {
  +    protected int[][] resize(int array[][], int newsize) {
           int newarray[][] = new int[newsize][];
           System.arraycopy(array, 0, newarray, 0, array.length);
           return newarray;
       }
  -
   
   } // class DTDGrammar
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.12.2.16 +37 -1     xml-xerces/java/src/org/apache/xerces/parsers/SAXParser.java
  
  Index: SAXParser.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/parsers/SAXParser.java,v
  retrieving revision 1.12.2.15
  retrieving revision 1.12.2.16
  diff -u -r1.12.2.15 -r1.12.2.16
  --- SAXParser.java	2000/12/27 10:15:12	1.12.2.15
  +++ SAXParser.java	2000/12/28 09:41:25	1.12.2.16
  @@ -88,7 +88,7 @@
    * @author Stubs generated by DesignDoc on Mon Sep 11 11:10:57 PDT 2000
    * @author Andy Clark, IBM
    *
  - * @version $Id: SAXParser.java,v 1.12.2.15 2000/12/27 10:15:12 andyc Exp $
  + * @version $Id: SAXParser.java,v 1.12.2.16 2000/12/28 09:41:25 andyc Exp $
    */
   public class SAXParser
       extends XMLDocumentParser
  @@ -188,6 +188,25 @@
       } // doctypeDecl(String,String,String)
   
       /**
  +     * The start of a namespace prefix mapping. This method will only be
  +     * called when namespace processing is enabled.
  +     * 
  +     * @param prefix The namespace prefix.
  +     * @param uri    The URI bound to the prefix.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     */
  +    public void startPrefixMapping(String prefix, String uri)
  +        throws SAXException {
  +
  +        // SAX2
  +        if (fContentHandler != null) {
  +            fContentHandler.startPrefixMapping(prefix, uri);
  +        }
  +
  +    } // startPrefixMapping(String prefix, String uri)
  +
  +    /**
        * The start of an element. If the document specifies the start element
        * by using an empty tag, then the startElement method will immediately
        * be followed by the endElement method, with no intervening methods.
  @@ -284,6 +303,23 @@
           }
   
       } // endElement(QName)
  +
  +    /**
  +     * The end of a namespace prefix mapping. This method will only be
  +     * called when namespace processing is enabled.
  +     * 
  +     * @param prefix The namespace prefix.
  +     *
  +     * @throws SAXException Thrown by handler to signal an error.
  +     */
  +    public void endPrefixMapping(String prefix) throws SAXException {
  +
  +        // SAX2
  +        if (fContentHandler != null) {
  +            fContentHandler.endPrefixMapping(prefix);
  +        }
  +
  +    } // endPrefixMapping(String)
   
       /**
        * The end of the document.
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.2   +140 -19   xml-xerces/java/src/org/apache/xerces/util/Attic/NamespaceSupport.java
  
  Index: NamespaceSupport.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/util/Attic/NamespaceSupport.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- NamespaceSupport.java	2000/10/24 22:49:57	1.1.2.1
  +++ NamespaceSupport.java	2000/12/28 09:41:27	1.1.2.2
  @@ -57,10 +57,7 @@
   
   package org.apache.xerces.util;
   
  -import java.util.EmptyStackException;
  -import java.util.Enumeration;
  -import java.util.Hashtable;
  -import java.util.Vector;
  +import org.apache.xerces.xni.NamespaceContext;
   
   /**
    * Namespace support for XML document handlers. This class doesn't 
  @@ -70,21 +67,12 @@
    *
    * @author Andy Clark, IBM
    *
  - * @version $Id: NamespaceSupport.java,v 1.1.2.1 2000/10/24 22:49:57 andyc Exp $
  + * @version $Id: NamespaceSupport.java,v 1.1.2.2 2000/12/28 09:41:27 andyc Exp $
    */
  -public class NamespaceSupport {
  +public class NamespaceSupport 
  +    implements NamespaceContext {
   
       //
  -    // Constants
  -    //
  -
  -    /**
  -     * The XML Namespace ("http://www.w3.org/XML/1998/namespace"). This is
  -     * the Namespace URI that is automatically mapped to the "xml" prefix.
  -     */
  -    protected final static String XMLNS = "http://www.w3.org/XML/1998/namespace";
  -
  -    //
       // Data
       //
   
  @@ -102,6 +90,9 @@
       /** The top of the namespace information array. */
       protected int fNamespaceSize;
   
  +    // NOTE: The constructor depends on the initial context size 
  +    //       being at least 1. -Ac
  +
       /** 
        * Context indexes. This array contains indexes into the namespace
        * information array. The index at the current context is the start
  @@ -162,7 +153,7 @@
           // bind "xml" prefix to the XMLNS uri
           fNamespace[fNamespaceSize++] = fXmlSymbol;
           fNamespace[fNamespaceSize++] = symbolTable.addSymbol(XMLNS);
  -        fCurrentContext++;
  +        ++fCurrentContext;
   
       } // reset(SymbolTable)
   
  @@ -204,12 +195,12 @@
        * <p>
        * You must not attempt to declare additional Namespace
        * prefixes after popping a context, unless you push another
  -     * context first.</p>
  +     * context first.
        *
        * @see #pushContext
        */
       public void popContext() {
  -    	fCurrentContext--;
  +        fNamespaceSize = fContext[fCurrentContext--];
       } // popContext()
   
       // operations within a context.
  @@ -247,6 +238,12 @@
           // see if prefix already exists in current context
           for (int i = fNamespaceSize; i > fContext[fCurrentContext]; i -= 2) {
               if (fNamespace[i - 2] == prefix) {
  +                // REVISIT: [Q] Should the new binding override the
  +                //          previously declared binding or should it
  +                //          it be ignored? -Ac
  +                // NOTE:    The SAX2 "NamespaceSupport" helper allows
  +                //          re-bindings with the new binding overwriting
  +                //          the previous binding. -Ac
                   fNamespace[i - 1] = uri;
                   return true;
               }
  @@ -308,5 +305,129 @@
       public String getDeclaredPrefixAt(int index) {
           return fNamespace[fContext[fCurrentContext] + index * 2];
       } // getDeclaredPrefixAt(int):String
  +
  +    /**
  +     * Returns the parent namespace context or null if there is no
  +     * parent context. The total depth of the namespace contexts 
  +     * matches the element depth in the document.
  +     * <p>
  +     * <strong>Note:</strong> This method <em>may</em> return the same 
  +     * NamespaceContext object reference. The caller is responsible for
  +     * saving the declared prefix mappings before calling this method.
  +     */
  +    public NamespaceContext getParentContext() {
  +        if (fCurrentContext == 1) {
  +            return null;
  +        }
  +        return new Context(fCurrentContext - 1);
  +    } // getParentContext():NamespaceContext
  +
  +    //
  +    // Classes
  +    //
  +
  +    /**
  +     * Namespace context information. The current context is always
  +     * handled directly by the NamespaceSupport class. This class is
  +     * used when a user queries the parent context.
  +     *
  +     * @author Andy Clark, IBM
  +     */
  +    final class Context 
  +        implements NamespaceContext {
  +    
  +        //
  +        // Data
  +        //
  +
  +        /** The current context. */
  +        private int fCurrentContext;
  +
  +        //
  +        // Constructors
  +        //
  +
  +        /** 
  +         * Constructs a new context. Once constructed, this object will
  +         * be re-used when the application calls <code>getParentContext</code.
  +         */
  +        public Context(int currentContext) {
  +            setCurrentContext(currentContext);
  +        } // <init>(int)
  +
  +        //
  +        // Public methods
  +        //
  +
  +        /** Sets the current context. */
  +        public void setCurrentContext(int currentContext) {
  +            fCurrentContext = currentContext;
  +        } // setCurrentContext(int)
  +
  +        //
  +        // NamespaceContext methods
  +        //
  +
  +        /**
  +         * Look up a prefix and get the currently-mapped Namespace URI.
  +         * <p>
  +         * This method looks up the prefix in the current context.
  +         * Use the empty string ("") for the default Namespace.
  +         *
  +         * @param prefix The prefix to look up.
  +         *
  +         * @return The associated Namespace URI, or null if the prefix
  +         *         is undeclared in this context.
  +         *
  +         * @see #getPrefix
  +         * @see #getPrefixes
  +         */
  +        public String getURI(String prefix) {
  +
  +            // find prefix in current context
  +            for (int i = fNamespaceSize; i > 0; i -= 2) {
  +                if (fNamespace[i - 2] == prefix) {
  +                    return fNamespace[i - 1];
  +                }
  +            }
  +
  +            // prefix not found
  +            return null;
  +
  +        } // getURI(String):String
  +
  +        /**
  +         * Return a count of all prefixes currently declared, including
  +         * the default prefix if bound.
  +         */
  +        public int getDeclaredPrefixCount() {
  +            return (fNamespaceSize - fContext[fCurrentContext]) / 2;
  +        } // getDeclaredPrefixCount():int
  +
  +        /** 
  +         * Returns the prefix at the specified index in the current context.
  +         */
  +        public String getDeclaredPrefixAt(int index) {
  +            return fNamespace[fContext[fCurrentContext] + index * 2];
  +        } // getDeclaredPrefixAt(int):String
  +
  +        /**
  +         * Returns the parent namespace context or null if there is no
  +         * parent context. The total depth of the namespace contexts 
  +         * matches the element depth in the document.
  +         * <p>
  +         * <strong>Note:</strong> This method <em>may</em> return the same 
  +         * NamespaceContext object reference. The caller is responsible for
  +         * saving the declared prefix mappings before calling this method.
  +         */
  +        public NamespaceContext getParentContext() {
  +            if (fCurrentContext == 1) {
  +                return null;
  +            }
  +            setCurrentContext(fCurrentContext - 1);
  +            return this;
  +        } // getParentContext():NamespaceContext
  +
  +    } // class Context
   
   } // class NamespaceSupport
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.1.2.6   +2 -2      xml-xerces/java/src/org/apache/xerces/xni/Attic/XMLString.java
  
  Index: XMLString.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/xni/Attic/XMLString.java,v
  retrieving revision 1.1.2.5
  retrieving revision 1.1.2.6
  diff -u -r1.1.2.5 -r1.1.2.6
  --- XMLString.java	2000/10/12 00:17:32	1.1.2.5
  +++ XMLString.java	2000/12/28 09:41:29	1.1.2.6
  @@ -79,7 +79,7 @@
    * @author Stubs generated by DesignDoc on Mon Sep 11 11:10:57 PDT 2000
    * @author Eric Ye
    *
  - * @version $Id: XMLString.java,v 1.1.2.5 2000/10/12 00:17:32 andyc Exp $
  + * @version $Id: XMLString.java,v 1.1.2.6 2000/12/28 09:41:29 andyc Exp $
    */
   public class XMLString {
   
  @@ -164,7 +164,7 @@
       public void clear() {
           this.ch = null;
           this.offset = 0;
  -        this.length = 0;
  +        this.length = -1;
       } // clear()
   
       /**