/*
 * reserved comment block
 * DO NOT REMOVE OR ALTER!
 */
/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2002 The Apache Software Foundation.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.apache.org.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package com.sun.org.apache.xerces.internal.impl.dtd;

import java.util.ArrayList;
import java.util.Hashtable;

import com.sun.org.apache.xerces.internal.impl.dtd.models.CMAny;
import com.sun.org.apache.xerces.internal.impl.dtd.models.CMBinOp;
import com.sun.org.apache.xerces.internal.impl.dtd.models.CMLeaf;
import com.sun.org.apache.xerces.internal.impl.dtd.models.CMNode;
import com.sun.org.apache.xerces.internal.impl.dtd.models.CMUniOp;
import com.sun.org.apache.xerces.internal.impl.dtd.models.ContentModelValidator;
import com.sun.org.apache.xerces.internal.impl.dtd.models.DFAContentModel;
import com.sun.org.apache.xerces.internal.impl.dtd.models.MixedContentModel;
import com.sun.org.apache.xerces.internal.impl.dtd.models.SimpleContentModel;
import com.sun.org.apache.xerces.internal.impl.dv.DatatypeValidator;
import com.sun.org.apache.xerces.internal.impl.validation.EntityState;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
import com.sun.org.apache.xerces.internal.xni.Augmentations;
import com.sun.org.apache.xerces.internal.xni.QName;
import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler;
import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler;
import com.sun.org.apache.xerces.internal.xni.XMLLocator;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
import com.sun.org.apache.xerces.internal.xni.XMLString;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDContentModelSource;
import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource;

/**
 * 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.
 *
 * @xerces.internal
 *
 * @author Eric Ye, IBM
 * @author Jeffrey Rodriguez, IBM
 * @author Andy Clark, IBM
 * @author Neil Graham, IBM
 *
 * @version $Id: DTDGrammar.java,v 1.4 2010/08/11 07:18:37 joehw Exp $
 */
public class DTDGrammar
    implements XMLDTDHandler, XMLDTDContentModelHandler, EntityState, Grammar {

    //
    // Constants
    //

    /** Top level scope (-1). */
    public static final int TOP_LEVEL_SCOPE = -1;

    // private

    /** 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 (1 << (10 - CHUNK_SHIFT)). */
    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;

    // debugging

    /** Debug DTDGrammar. */
    private static final boolean DEBUG = false;

    //
    // Data
    //

    protected XMLDTDSource fDTDSource = null;
    protected XMLDTDContentModelSource fDTDContentModelSource = null;

    /** Current element index. */
    protected int fCurrentElementIndex;

    /** Current attribute index. */
    protected int fCurrentAttributeIndex;

    /** fReadingExternalDTD */
    protected boolean fReadingExternalDTD = false;

    /** Symbol table. */
    private SymbolTable fSymbolTable;

    // The XMLDTDDescription with which this Grammar is associated
    protected XMLDTDDescription fGrammarDescription = null;

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

    // is this grammar immutable?  (fully constructed and not changeable)
    private boolean fIsImmutable = false;

    /**
     * Attribute declaration type.
     * @see XMLAttributeDecl
     */
    private short fAttributeDeclType[][] = new short[INITIAL_CHUNK_COUNT][];

    /** Attribute declaration 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 String fAttributeDeclNonNormalizedDefaultValue[][] = 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][];
    private String[][] fNotationBaseSystemId = new String[INITIAL_CHUNK_COUNT][];

    // other information

    /** Element index mapping table. */
    private QNameHashtable fElementIndexMap = new QNameHashtable();

    /** Entity index mapping table. */
    private QNameHashtable fEntityIndexMap = new QNameHashtable();

    /** Notation index mapping table. */
    private QNameHashtable fNotationIndexMap = new QNameHashtable();

    // temp variables

    /** Mixed. */
    private boolean fMixed;

    /** Temporary qualified name. */
    private final QName fQName = new QName();

    /** Temporary qualified name. */
    private final QName fQName2 = new QName();

    /** Temporary Attribute decl. */
    protected final XMLAttributeDecl fAttributeDecl = new XMLAttributeDecl();

    // for buildSyntaxTree method

    private int fLeafCount = 0;
    private int fEpsilonIndex = -1;

    /** Element declaration. */
    private XMLElementDecl fElementDecl = new XMLElementDecl();

    /** Entity declaration. */
    private XMLEntityDecl fEntityDecl = new XMLEntityDecl();

    /** Simple type. */
    private XMLSimpleType fSimpleType = new XMLSimpleType();

    /** Content spec node. */
    private XMLContentSpec fContentSpec = new XMLContentSpec();

    /** table of XMLElementDecl   */
    Hashtable   fElementDeclTab     = new Hashtable();

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

    /** Stack depth   */
    private int fDepth = 0;

    /** Entity stack. */
    private boolean[] fPEntityStack = new boolean[4];
    private int fPEDepth = 0;

    // additional fields(columns) for the element Decl pool in the Grammar

    /** flag if the elementDecl is External. */
    private int fElementDeclIsExternal[][] = new int[INITIAL_CHUNK_COUNT][];


    // additional fields(columns) for the attribute Decl pool in the Grammar

    /** flag if the AttributeDecl is External. */
    private int fAttributeDeclIsExternal[][] = new int[INITIAL_CHUNK_COUNT][];

    // for mixedElement method

    int valueIndex            = -1;
    int prevNodeIndex         = -1;
    int nodeIndex             = -1;

    //
    // Constructors
    //

    /** Default constructor. */
    public DTDGrammar(SymbolTable symbolTable, XMLDTDDescription desc) {
        fSymbolTable = symbolTable;
        fGrammarDescription = desc;
    } // <init>(SymbolTable)

    // Grammar methods

    // return the XMLDTDDescription object with which this is associated
    public XMLGrammarDescription getGrammarDescription() {
        return fGrammarDescription;
    } // getGrammarDescription():  XMLGrammarDescription

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

    public int getAttributeDeclIndex(int elementDeclIndex, String attributeDeclName) {
        if (elementDeclIndex == -1) {
            return -1;
        }
        int attDefIndex = getFirstAttributeDeclIndex(elementDeclIndex);
        while (attDefIndex != -1) {
            getAttributeDecl(attDefIndex, fAttributeDecl);

            if (fAttributeDecl.name.rawname == attributeDeclName
                || attributeDeclName.equals(fAttributeDecl.name.rawname) ) {
                return attDefIndex;
            }
            attDefIndex = getNextAttributeDeclIndex(attDefIndex);
        }
        return -1;
    } // getAttributeDeclIndex (int,QName)

    //
    // XMLDTDHandler methods
    //

    /**
     * The start of the DTD.
     *
     * @param locator  The document locator, or null if the document
     *                 location cannot be reported during the parsing of
     *                 the document DTD. However, it is <em>strongly</em>
     *                 recommended that a locator be supplied that can
     *                 at least report the base system identifier of the
     *                 DTD.
     *
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void startDTD(XMLLocator locator, Augmentations augs) throws XNIException {
        //Initialize stack
        fOpStack = null;
        fNodeIndexStack = null;
        fPrevNodeIndexStack = null;
    } // startDTD(XMLLocator)

    /**
     * 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
     * startParameterEntity method with the entity name "[dtd]" <em>before</em> calling
     * the startDTD method.
     *
     * @param name     The name of the parameter entity.
     * @param identifier The resource identifier.
     * @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).
     * @param augs Additional information that may include infoset
     *                      augmentations.
     *
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void startParameterEntity(String name,
                                     XMLResourceIdentifier identifier,
                                     String encoding,
                                     Augmentations augs) throws XNIException {

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

    } // startParameterEntity(String,XMLResourceIdentifier,String,Augmentations)

    /**
     * The start of the DTD external subset.
     *
     * @param augs Additional information that may include infoset
     *                      augmentations.
     *
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void startExternalSubset(XMLResourceIdentifier identifier,
                                    Augmentations augs) throws XNIException {
        fReadingExternalDTD = true;
    } // startExternalSubset(Augmentations)

    /**
     * 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.
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void endParameterEntity(String name, Augmentations augs) throws XNIException {

        fPEDepth--;
        fReadingExternalDTD = fPEntityStack[fPEDepth];

    } // endParameterEntity(String,Augmentations)

    /**
     * The end of the DTD external subset.
     *
     * @param augs Additional information that may include infoset
     *                      augmentations.
     *
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void endExternalSubset(Augmentations augs) throws XNIException {
        fReadingExternalDTD = false;
    } // endExternalSubset(Augmentations)

    /**
     * An element declaration.
     *
     * @param name         The name of the element.
     * @param contentModel The element content model.
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void elementDecl(String name, String contentModel, Augmentations augs)
        throws XNIException {

        XMLElementDecl tmpElementDecl = (XMLElementDecl) fElementDeclTab.get(name) ;

        // check if it is already defined
        if ( tmpElementDecl != null ) {
            if (tmpElementDecl.type == -1) {
                fCurrentElementIndex = getElementDeclIndex(name);
            }
            else {
                // duplicate element, ignored.
                return;
            }
        }
        else {
            fCurrentElementIndex = createElementDecl();//create element decl
        }

        XMLElementDecl elementDecl       = new XMLElementDecl();

        fQName.setValues(null, name, name, null);

        elementDecl.name.setValues(fQName);

        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;
        addContentSpecToElement(elementDecl);

        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 || fPEDepth > 0) ? 1 : 0;

    } // elementDecl(String,String)

    /**
     * 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.
     * @param nonNormalizedDefaultValue  The attribute default value with no normalization
     *                      performed, or null if no default value is specified.
     *
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void attributeDecl(String elementName, String attributeName,
                              String type, String[] enumeration,
                              String defaultType, XMLString defaultValue,
                              XMLString nonNormalizedDefaultValue, Augmentations augs) throws XNIException {

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

        //return, when more than one definition is provided for the same attribute of given element type
        //only the first declaration is binding and later declarations are ignored
        if (getAttributeDeclIndex(elementIndex, attributeName) != -1) {
            return;
        }

        fCurrentAttributeIndex = createAttributeDecl();// Create current Attribute Decl

        fSimpleType.clear();
        if ( defaultType != null ) {
            if ( defaultType.equals( "#FIXED") ) {
                fSimpleType.defaultType = XMLSimpleType.DEFAULT_TYPE_FIXED;
            } else if ( defaultType.equals( "#IMPLIED") ) {
                fSimpleType.defaultType = XMLSimpleType.DEFAULT_TYPE_IMPLIED;
            } else if ( defaultType.equals( "#REQUIRED") ) {
                fSimpleType.defaultType = XMLSimpleType.DEFAULT_TYPE_REQUIRED;
            }
        }
        if ( DEBUG ) {
            System.out.println("defaultvalue = " + defaultValue.toString() );
        }
        fSimpleType.defaultValue      = defaultValue!=null ?  defaultValue.toString() : null;
        fSimpleType.nonNormalizedDefaultValue      = nonNormalizedDefaultValue!=null ?  nonNormalizedDefaultValue.toString() : null;
        fSimpleType.enumeration       = enumeration;

        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;
        }
        else if (type.startsWith("ENUMERATION") ) {
            fSimpleType.type = XMLSimpleType.TYPE_ENUMERATION;
        }
        else {
            // REVISIT: Report error message. -Ac
            System.err.println("!!! unknown attribute type "+type);
        }
        // REVISIT: The datatype should be stored with the attribute value
        //          and not special-cased in the XMLValidator. -Ac
        //fSimpleType.datatypeValidator = fDatatypeValidatorFactory.createDatatypeValidator(type, null, facets, fSimpleType.list);

        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 || fPEDepth > 0) ?  1 : 0;

    } // attributeDecl(String,String,String,String[],String,XMLString,XMLString, Augmentations)

    /**
     * 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.
     * @param nonNormalizedText The non-normalized value of the entity. This
     *             value contains the same sequence of characters that was in
     *             the internal entity declaration, without any entity
     *             references expanded.
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void internalEntityDecl(String name, XMLString text,
                                   XMLString nonNormalizedText,
                                   Augmentations augs) throws XNIException {

        int entityIndex = getEntityDeclIndex(name);
        if( entityIndex == -1){
            entityIndex = createEntityDecl();
            boolean isPE = name.startsWith("%");
            boolean inExternal = (fReadingExternalDTD || fPEDepth > 0);
            XMLEntityDecl  entityDecl = new XMLEntityDecl();
            entityDecl.setValues(name,null,null, null, null,
                                 text.toString(), isPE, inExternal);

            setEntityDecl(entityIndex, entityDecl);
        }

    } // internalEntityDecl(String,XMLString,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 identifier    An object containing all location information
     *                      pertinent to this external entity declaration.
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void externalEntityDecl(String name,
                                   XMLResourceIdentifier identifier,
                                   Augmentations augs) throws XNIException {

        int entityIndex = getEntityDeclIndex(name);
        if( entityIndex == -1){
            entityIndex = createEntityDecl();
            boolean isPE = name.startsWith("%");
            boolean inExternal = (fReadingExternalDTD || fPEDepth > 0);

            XMLEntityDecl  entityDecl = new XMLEntityDecl();
            entityDecl.setValues(name, identifier.getPublicId(), identifier.getLiteralSystemId(),
                                identifier.getBaseSystemId(),
                                null, null, isPE, inExternal);

            setEntityDecl(entityIndex, entityDecl);
        }
    } // externalEntityDecl(String, XMLResourceIdentifier, Augmentations)

    /**
     * An unparsed entity declaration.
     *
     * @param name     The name of the entity.
     * @param identifier    An object containing all location information
     *                      pertinent to this entity.
     * @param notation The name of the notation.
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void unparsedEntityDecl(String name, XMLResourceIdentifier identifier,
                                   String notation,
                                   Augmentations augs) throws XNIException {

        XMLEntityDecl  entityDecl = new XMLEntityDecl();
        boolean isPE = name.startsWith("%");
        boolean inExternal = (fReadingExternalDTD || fPEDepth > 0);

        entityDecl.setValues(name,identifier.getPublicId(),identifier.getLiteralSystemId(),
                            identifier.getBaseSystemId(), notation,
                            null, isPE, inExternal);
        int entityIndex = getEntityDeclIndex(name);
        if (entityIndex == -1) {
            entityIndex = createEntityDecl();
            setEntityDecl(entityIndex, entityDecl);
        }

    } // unparsedEntityDecl(String,StringXMLResourceIdentifier,Augmentations)

    /**
     * A notation declaration
     *
     * @param name     The name of the notation.
     * @param identifier    An object containing all location information
     *                      pertinent to this notation.
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void notationDecl(String name, XMLResourceIdentifier identifier,
                             Augmentations augs) throws XNIException {

        XMLNotationDecl  notationDecl = new XMLNotationDecl();
        notationDecl.setValues(name,identifier.getPublicId(),identifier.getLiteralSystemId(),
                identifier.getBaseSystemId());
        int notationIndex = getNotationDeclIndex(name);
        if (notationIndex == -1) {
            notationIndex = createNotationDecl();
            setNotationDecl(notationIndex, notationDecl);
        }

    } // notationDecl(String,XMLResourceIdentifier,Augmentations)

    /**
     * The end of the DTD.
     *
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void endDTD(Augmentations augs) throws XNIException {
        fIsImmutable = true;
        // make sure our description contains useful stuff...
        if (fGrammarDescription.getRootName() == null) {
            // we don't know what the root is; so use possibleRoots...
            int chunk, index = 0;
            String currName = null;
            final int size = fElementDeclCount;
            ArrayList elements = new ArrayList(size);
            for (int i = 0; i < size; ++i) {
                chunk = i >> CHUNK_SHIFT;
                index = i & CHUNK_MASK;
                currName = fElementDeclName[chunk][index].rawname;
                elements.add(currName);
            }
            fGrammarDescription.setPossibleRoots(elements);
        }
    } // endDTD()

    // sets the source of this handler
    public void setDTDSource(XMLDTDSource source) {
        fDTDSource = source;
    } // setDTDSource(XMLDTDSource)

    // returns the source of this handler
    public XMLDTDSource getDTDSource() {
        return fDTDSource;
    } // getDTDSource():  XMLDTDSource

    // no-op methods

    /**
     * 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.
     *
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void textDecl(String version, String encoding, Augmentations augs)
        throws XNIException {}

    /**
     * A comment.
     *
     * @param text The text in the comment.
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by application to signal an error.
     */
    public void comment(XMLString text, Augmentations augs) throws XNIException {}

    /**
     * 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.
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void processingInstruction(String target, XMLString data,
                                      Augmentations augs) throws XNIException {}

    /**
     * The start of an attribute list.
     *
     * @param elementName The name of the element that this attribute
     *                    list is associated with.
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void startAttlist(String elementName, Augmentations augs)
        throws XNIException {}

    /**
     * The end of an attribute list.
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void endAttlist(Augmentations augs) throws XNIException {}

    /**
     * The start of a conditional section.
     *
     * @param type The type of the conditional section. This value will
     *             either be CONDITIONAL_INCLUDE or CONDITIONAL_IGNORE.
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     *
     * @see XMLDTDHandler#CONDITIONAL_INCLUDE
     * @see XMLDTDHandler#CONDITIONAL_IGNORE
     */
    public void startConditional(short type, Augmentations augs)
        throws XNIException {}

    /**
     * Characters within an IGNORE conditional section.
     *
     * @param text The ignored text.
     * @param augs Additional information that may include infoset
     *                      augmentations.
     */
    public void ignoredCharacters(XMLString text, Augmentations augs)
        throws XNIException {}

    /**
     * The end of a conditional section.
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void endConditional(Augmentations augs) throws XNIException {}

    //
    // XMLDTDContentModelHandler methods
    //

    // set content model source
    public void setDTDContentModelSource(XMLDTDContentModelSource source) {
        fDTDContentModelSource = source;
    }

    // get content model source
    public XMLDTDContentModelSource getDTDContentModelSource() {
        return fDTDContentModelSource;
    }

    /**
     * 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 augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void startContentModel(String elementName, Augmentations augs)
        throws XNIException {

        XMLElementDecl elementDecl = (XMLElementDecl) this.fElementDeclTab.get( elementName);
        if ( elementDecl != null ) {
            fElementDecl = elementDecl;
        }
        fDepth = 0;
        initializeContentModelStack();

    } // startContentModel(String)

    /**
     * A start of either a mixed or children content model. A mixed
     * content model will immediately be followed by a call to the
     * <code>pcdata()</code> method. A children content model will
     * contain additional groups and/or elements.
     *
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     *
     * @see #any
     * @see #empty
     */
    public void startGroup(Augmentations augs) throws XNIException {
        fDepth++;
        initializeContentModelStack();
        fMixed = false;
    } // startGroup()

    /**
     * The appearance of "#PCDATA" within a group signifying a
     * mixed content model. This method will be the first called
     * following the content model's <code>startGroup()</code>.
     *
     *@param augs Additional information that may include infoset
     *                      augmentations.
     *
     * @throws XNIException Thrown by handler to signal an error.
     *
     * @see #startGroup
     */
    public void pcdata(Augmentations augs) throws XNIException {
        fMixed = true;
    } // pcdata()

    /**
     * A referenced element in a mixed or children content model.
     *
     * @param elementName The name of the referenced element.
     * @param augs Additional information that may include infoset
     *                      augmentations.
     *
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void element(String elementName, Augmentations augs) throws XNIException {
        if (fMixed) {
            if (fNodeIndexStack[fDepth] == -1 ) {
                fNodeIndexStack[fDepth] = addUniqueLeafNode(elementName);
            }
            else {
                fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_CHOICE,
                                                             fNodeIndexStack[fDepth],
                                                             addUniqueLeafNode(elementName));
            }
        }
        else {
            fNodeIndexStack[fDepth] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_LEAF, elementName);
        }
    } // element(String)

    /**
     * The separator between choices or sequences of a mixed or children
     * content model.
     *
     * @param separator The type of children separator.
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     *
     * @see org.apache.xerces.xni.XMLDTDContentModelHandler#SEPARATOR_CHOICE
     * @see org.apache.xerces.xni.XMLDTDContentModelHandler#SEPARATOR_SEQUENCE
     */
    public void separator(short separator, Augmentations augs) throws XNIException {

        if (!fMixed) {
            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;
            }
        }

    } // separator(short)

    /**
     * The occurrence count for a child in a children content model or
     * for the mixed content model group.
     *
     * @param occurrence The occurrence count for the last element
     *                   or group.
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     *
     * @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ZERO_OR_ONE
     * @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ZERO_OR_MORE
     * @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ONE_OR_MORE
     */
    public void occurrence(short occurrence, Augmentations augs) throws XNIException {

        if (!fMixed) {
            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 );
            }
        }

    } // occurrence(short)

    /**
     * The end of a group for mixed or children content models.
     *
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void endGroup(Augmentations augs) throws XNIException {

        if (!fMixed) {
            if (fPrevNodeIndexStack[fDepth] != -1) {
                fNodeIndexStack[fDepth] = addContentSpecNode(fOpStack[fDepth], fPrevNodeIndexStack[fDepth], fNodeIndexStack[fDepth]);
            }
            int nodeIndex = fNodeIndexStack[fDepth--];
            fNodeIndexStack[fDepth] = nodeIndex;
        }

    } // endGroup()

    // no-op methods

    /**
     * A content model of ANY.
     *
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     *
     * @see #empty
     * @see #startGroup
     */
    public void any(Augmentations augs) throws XNIException {}

    /**
     * A content model of EMPTY.
     *
     * @param augs Additional information that may include infoset
     *                      augmentations.
     * @throws XNIException Thrown by handler to signal an error.
     *
     * @see #any
     * @see #startGroup
     */
    public void empty(Augmentations augs) throws XNIException {}

    /**
     * The end of a content model.
     * @param augs Additional information that may include infoset
     *                      augmentations.
     *
     * @throws XNIException Thrown by handler to signal an error.
     */
    public void endContentModel(Augmentations augs) throws XNIException {}

    //
    // Grammar methods
    //

    /** Returns true if this grammar is namespace aware. */
    public boolean isNamespaceAware() {
        return false;
    } // isNamespaceAware():boolean

    /** Returns the symbol table. */
    public SymbolTable getSymbolTable() {
        return fSymbolTable;
    } // getSymbolTable():SymbolTable

    /**
     * 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 ? 0 : -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
     *
     * @return index of the elementDeclName in scope
     */
    public int getElementDeclIndex(String elementDeclName) {
        int mapping = fElementIndexMap.get(elementDeclName);
        //System.out.println("getElementDeclIndex("+elementDeclName+") -> "+mapping);
        return mapping;
    } // getElementDeclIndex(String):int

    /** Returns the element decl index.
     * @param elementDeclQName qualilfied name of the element
     */
    public int getElementDeclIndex(QName elementDeclQName) {
        return getElementDeclIndex(elementDeclQName.rawname);
    } // getElementDeclIndex(QName):int

                /** make separate function for getting contentSpecType of element.
      * we can avoid setting of the element values.
                */

                public short getContentSpecType(int elementIndex){
        if (elementIndex < 0 || elementIndex >= fElementDeclCount) {
            return -1 ;
        }

        int chunk = elementIndex >> CHUNK_SHIFT;
        int index = elementIndex &  CHUNK_MASK;

        if(fElementDeclType[chunk][index] == -1){
            return -1 ;
                            }
        else{
                                       return (short) (fElementDeclType[chunk][index] & LIST_MASK);
                            }

                }//getContentSpecType

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

        int chunk = elementDeclIndex >> CHUNK_SHIFT;
        int index = elementDeclIndex &  CHUNK_MASK;

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

        /* 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 = null;
        elementDecl.simpleType.defaultType       = -1;
        elementDecl.simpleType.defaultValue      = null;

        return true;

    } // getElementDecl(int,XMLElementDecl):boolean

    QName getElementDeclName(int elementDeclIndex) {
        if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
            return null;
        }
        int chunk = elementDeclIndex >> CHUNK_SHIFT;
        int index = elementDeclIndex &  CHUNK_MASK;
        return fElementDeclName[chunk][index];
    }

    // REVISIT: Make this getAttributeDeclCount/getAttributeDeclAt. -Ac

    /**
     * getFirstAttributeDeclIndex
     *
     * @param elementDeclIndex
     *
     * @return index of the first attribute for element declaration elementDeclIndex
     */
    public int getFirstAttributeDeclIndex(int elementDeclIndex) {
        int chunk = elementDeclIndex >> CHUNK_SHIFT;
        int index = elementDeclIndex &  CHUNK_MASK;

        return  fElementDeclFirstAttributeDeclIndex[chunk][index];
    } // getFirstAttributeDeclIndex

    /**
     * getNextAttributeDeclIndex
     *
     * @param attributeDeclIndex
     *
     * @return index of the next attribute of the attribute at attributeDeclIndex
     */
    public int getNextAttributeDeclIndex(int attributeDeclIndex) {
        int chunk = attributeDeclIndex >> CHUNK_SHIFT;
        int index = attributeDeclIndex &  CHUNK_MASK;

        return fAttributeDeclNextAttributeDeclIndex[chunk][index];
    } // getNextAttributeDeclIndex

    /**
     * getAttributeDecl
     *
     * @param attributeDeclIndex
     * @param attributeDecl The values of this structure are set by this call.
     *
     * @return true if getAttributeDecl was able to fill in the value of attributeDecl
     */
    public boolean getAttributeDecl(int attributeDeclIndex, XMLAttributeDecl attributeDecl) {
        if (attributeDeclIndex < 0 || attributeDeclIndex >= fAttributeDeclCount) {
            return false;
        }
        int chunk = attributeDeclIndex >> CHUNK_SHIFT;
        int index = attributeDeclIndex & CHUNK_MASK;

        attributeDecl.name.setValues(fAttributeDeclName[chunk][index]);

        short attributeType;
        boolean isList;

        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],
                                           fAttributeDeclNonNormalizedDefaultValue[chunk][index],
                                           fAttributeDeclDatatypeValidator[chunk][index]);
        return true;

    } // getAttributeDecl


    /**
     * Returns whether the given attribute is of type CDATA or not
     *
     * @param elName The element name.
     * @param atName The attribute name.
     *
     * @return true if the attribute is of type CDATA
     */
    public boolean isCDATAAttribute(QName elName, QName atName) {
        int elDeclIdx = getElementDeclIndex(elName);
        if (getAttributeDecl(elDeclIdx, fAttributeDecl)
            && fAttributeDecl.simpleType.type != XMLSimpleType.TYPE_CDATA){
            return false;
        }
        return true;
    }

    /**
     * getEntityDeclIndex
     *
     * @param entityDeclName
     *
     * @return the index of the EntityDecl
     */
    public int getEntityDeclIndex(String entityDeclName) {
        if (entityDeclName == null) {
            return -1;
        }

        return fEntityIndexMap.get(entityDeclName);
    } // getEntityDeclIndex

    /**
     * getEntityDecl
     *
     * @param entityDeclIndex
     * @param entityDecl
     *
     * @return true if getEntityDecl was able to fill entityDecl with the contents of the entity
     * with index entityDeclIndex
     */
    public boolean getEntityDecl(int entityDeclIndex, XMLEntityDecl entityDecl) {
        if (entityDeclIndex < 0 || entityDeclIndex >= fEntityCount) {
            return false;
        }
        int chunk = entityDeclIndex >> CHUNK_SHIFT;
        int index = entityDeclIndex & CHUNK_MASK;

        entityDecl.setValues(fEntityName[chunk][index],
                             fEntityPublicId[chunk][index],
                             fEntitySystemId[chunk][index],
                             fEntityBaseSystemId[chunk][index],
                             fEntityNotation[chunk][index],
                             fEntityValue[chunk][index],
                             fEntityIsPE[chunk][index] == 0 ? false : true ,
                             fEntityInExternal[chunk][index] == 0 ? false : true );

        return true;
    } // getEntityDecl

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

        return fNotationIndexMap.get(notationDeclName);
    } // getNotationDeclIndex

    /**
     * getNotationDecl
     *
     * @param notationDeclIndex
     * @param notationDecl
     *
     * @return return true of getNotationDecl can fill notationDecl with information about
     * the notation at notationDeclIndex.
     */
    public boolean getNotationDecl(int notationDeclIndex, XMLNotationDecl notationDecl) {
        if (notationDeclIndex < 0 || notationDeclIndex >= fNotationCount) {
            return false;
        }
        int chunk = notationDeclIndex >> CHUNK_SHIFT;
        int index = notationDeclIndex & CHUNK_MASK;

        notationDecl.setValues(fNotationName[chunk][index],
                               fNotationPublicId[chunk][index],
                               fNotationSystemId[chunk][index],
                               fNotationBaseSystemId[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;
    }

    /**
     * Returns the index to the content spec for the given element
     * declaration, or <code>-1</code> if the element declaration
     * index was invalid.
     */
    public int getContentSpecIndex(int elementDeclIndex) {
        if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
            return -1;
        }
        final int chunk = elementDeclIndex >> CHUNK_SHIFT;
        final int index = elementDeclIndex & CHUNK_MASK;
        return fElementDeclContentSpecIndex[chunk][index];
    }

    /**
     * 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=").append(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=").append(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();
        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
    //

    /**
     * Adds the content spec to the given element declaration.
     */
    protected void addContentSpecToElement(XMLElementDecl elementDecl) {
        if ((fDepth == 0 || (fDepth == 1 && elementDecl.type == XMLElementDecl.TYPE_MIXED)) &&
                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]);
        }
    }

    /**
     * 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);
        } 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 AbstractDTDGrammar class");
        }

        // Add the new model to the content model for this element
        fElementDeclContentModelValidator[chunk][index] = contentModel;

        return contentModel;

    } // getElementContentModelValidator(int):ContentModelValidator

   protected int createElementDecl() {
      int chunk = fElementDeclCount >> CHUNK_SHIFT;
      int index = fElementDeclCount & CHUNK_MASK;
      ensureElementDeclCapacity(chunk);
      fElementDeclName[chunk][index]                    = new QName();
      fElementDeclType[chunk][index]                    = -1;
      fElementDeclContentModelValidator[chunk][index]   = null;
      fElementDeclFirstAttributeDeclIndex[chunk][index] = -1;
      fElementDeclLastAttributeDeclIndex[chunk][index]  = -1;
      return fElementDeclCount++;
   }

   protected void setElementDecl(int elementDeclIndex, XMLElementDecl elementDecl) {
      if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
         return;
      }
      int     chunk       = elementDeclIndex >> CHUNK_SHIFT;
      int     index       = elementDeclIndex &  CHUNK_MASK;

      fElementDeclName[chunk][index].setValues(elementDecl.name);
      fElementDeclType[chunk][index]                  = elementDecl.type;

      fElementDeclContentModelValidator[chunk][index] = elementDecl.contentModelValidator;

      if (elementDecl.simpleType.list  == true ) {
         fElementDeclType[chunk][index] |= LIST_FLAG;
      }

      fElementIndexMap.put(elementDecl.name.rawname, elementDeclIndex);
   }




   protected void putElementNameMapping(QName name, int scope,
                                        int elementDeclIndex) {
   }

   protected void setFirstAttributeDeclIndex(int elementDeclIndex, int newFirstAttrIndex){

      if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
         return;
      }

      int chunk = elementDeclIndex >> CHUNK_SHIFT;
      int index = elementDeclIndex &  CHUNK_MASK;

      fElementDeclFirstAttributeDeclIndex[chunk][index] = newFirstAttrIndex;
   }

   protected void setContentSpecIndex(int elementDeclIndex, int contentSpecIndex){

      if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
         return;
      }

      int chunk = elementDeclIndex >> CHUNK_SHIFT;
      int index = elementDeclIndex &  CHUNK_MASK;

      fElementDeclContentSpecIndex[chunk][index] = contentSpecIndex;
   }


   protected int createAttributeDecl() {
      int chunk = fAttributeDeclCount >> CHUNK_SHIFT;
      int index = fAttributeDeclCount & CHUNK_MASK;

      ensureAttributeDeclCapacity(chunk);
      fAttributeDeclName[chunk][index]                    = new QName();
      fAttributeDeclType[chunk][index]                    = -1;
      fAttributeDeclDatatypeValidator[chunk][index]       = null;
      fAttributeDeclEnumeration[chunk][index]             = null;
      fAttributeDeclDefaultType[chunk][index]             = XMLSimpleType.DEFAULT_TYPE_IMPLIED;
      fAttributeDeclDefaultValue[chunk][index]            = null;
      fAttributeDeclNonNormalizedDefaultValue[chunk][index]            = null;
      fAttributeDeclNextAttributeDeclIndex[chunk][index]  = -1;
      return fAttributeDeclCount++;
   }


   protected void setAttributeDecl(int elementDeclIndex, int attributeDeclIndex,
                                   XMLAttributeDecl attributeDecl) {
      int attrChunk = attributeDeclIndex >> CHUNK_SHIFT;
      int attrIndex = attributeDeclIndex &  CHUNK_MASK;
      fAttributeDeclName[attrChunk][attrIndex].setValues(attributeDecl.name);
      fAttributeDeclType[attrChunk][attrIndex]  =  attributeDecl.simpleType.type;

      if (attributeDecl.simpleType.list) {
         fAttributeDeclType[attrChunk][attrIndex] |= LIST_FLAG;
      }
      fAttributeDeclEnumeration[attrChunk][attrIndex]  =  attributeDecl.simpleType.enumeration;
      fAttributeDeclDefaultType[attrChunk][attrIndex]  =  attributeDecl.simpleType.defaultType;
      fAttributeDeclDatatypeValidator[attrChunk][attrIndex] =  attributeDecl.simpleType.datatypeValidator;

      fAttributeDeclDefaultValue[attrChunk][attrIndex] = attributeDecl.simpleType.defaultValue;
      fAttributeDeclNonNormalizedDefaultValue[attrChunk][attrIndex] = attributeDecl.simpleType.nonNormalizedDefaultValue;

      int elemChunk     = elementDeclIndex >> CHUNK_SHIFT;
      int elemIndex     = elementDeclIndex &  CHUNK_MASK;
      int index         = fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex];
      while (index != -1) {
         if (index == attributeDeclIndex) {
            break;
         }
         attrChunk = index >> CHUNK_SHIFT;
         attrIndex = index & CHUNK_MASK;
         index = fAttributeDeclNextAttributeDeclIndex[attrChunk][attrIndex];
      }
      if (index == -1) {
         if (fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex] == -1) {
            fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex] = attributeDeclIndex;
         } else {
            index = fElementDeclLastAttributeDeclIndex[elemChunk][elemIndex];
            attrChunk = index >> CHUNK_SHIFT;
            attrIndex = index & CHUNK_MASK;
            fAttributeDeclNextAttributeDeclIndex[attrChunk][attrIndex] = attributeDeclIndex;
         }
         fElementDeclLastAttributeDeclIndex[elemChunk][elemIndex] = attributeDeclIndex;
      }
   }

   protected int createContentSpec() {
      int chunk = fContentSpecCount >> CHUNK_SHIFT;
      int index = fContentSpecCount & CHUNK_MASK;

      ensureContentSpecCapacity(chunk);
      fContentSpecType[chunk][index]       = -1;
      fContentSpecValue[chunk][index]      = null;
      fContentSpecOtherValue[chunk][index] = null;

      return fContentSpecCount++;
   }

   protected void setContentSpec(int contentSpecIndex, XMLContentSpec contentSpec) {
      int   chunk = contentSpecIndex >> CHUNK_SHIFT;
      int   index = contentSpecIndex & CHUNK_MASK;

      fContentSpecType[chunk][index]       = contentSpec.type;
      fContentSpecValue[chunk][index]      = contentSpec.value;
      fContentSpecOtherValue[chunk][index] = contentSpec.otherValue;
   }


   protected int createEntityDecl() {
       int chunk = fEntityCount >> CHUNK_SHIFT;
       int index = fEntityCount & CHUNK_MASK;

      ensureEntityDeclCapacity(chunk);
      fEntityIsPE[chunk][index] = 0;
      fEntityInExternal[chunk][index] = 0;

      return fEntityCount++;
   }

   protected void setEntityDecl(int entityDeclIndex, XMLEntityDecl entityDecl) {
       int chunk = entityDeclIndex >> CHUNK_SHIFT;
       int index = entityDeclIndex & CHUNK_MASK;

       fEntityName[chunk][index] = entityDecl.name;
       fEntityValue[chunk][index] = entityDecl.value;
       fEntityPublicId[chunk][index] = entityDecl.publicId;
       fEntitySystemId[chunk][index] = entityDecl.systemId;
       fEntityBaseSystemId[chunk][index] = entityDecl.baseSystemId;
       fEntityNotation[chunk][index] = entityDecl.notation;
       fEntityIsPE[chunk][index] = entityDecl.isPE ? (byte)1 : (byte)0;
       fEntityInExternal[chunk][index] = entityDecl.inExternal ? (byte)1 : (byte)0;

       fEntityIndexMap.put(entityDecl.name, entityDeclIndex);
   }

   protected int createNotationDecl() {
       int chunk = fNotationCount >> CHUNK_SHIFT;
       ensureNotationDeclCapacity(chunk);
       return fNotationCount++;
   }

   protected void setNotationDecl(int notationDeclIndex, XMLNotationDecl notationDecl) {
       int chunk = notationDeclIndex >> CHUNK_SHIFT;
       int index = notationDeclIndex & CHUNK_MASK;

       fNotationName[chunk][index] = notationDecl.name;
       fNotationPublicId[chunk][index] = notationDecl.publicId;
       fNotationSystemId[chunk][index] = notationDecl.systemId;
       fNotationBaseSystemId[chunk][index] = notationDecl.baseSystemId;

       fNotationIndexMap.put(notationDecl.name, notationDeclIndex);
   }

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

    /** Initialize content model stack. */
    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()

    boolean isImmutable() {
        return fIsImmutable;
    }

    //
    // 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=").append(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;
            }

        } // switch type

    } // appendContentSpec(XMLContentSpec.Provider,StringPool,XMLContentSpec,StringBuffer,boolean)

    // debugging

    private void printAttribute(int attributeDeclIndex) {

        XMLAttributeDecl attributeDecl = new XMLAttributeDecl();
        if (getAttributeDecl(attributeDeclIndex, attributeDecl)) {
            System.out.print(" { ");
            System.out.print(attributeDecl.name.localpart);
            System.out.print(" }");
        }

    } // 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 synchronized 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
        }

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

            fQName.setValues(null, (String)contentSpec.value,
                              (String)contentSpec.value, (String)contentSpec.otherValue);
            return new SimpleContentModel(contentSpec.type, fQName, null);
        } 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();

            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.
                //
                fQName.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, fQName, fQName2);
            }
        } 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);

            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.
                //
                fQName.setValues(null, (String)contentSpecLeft.value,
                                  (String)contentSpecLeft.value, (String)contentSpecLeft.otherValue);
                return new SimpleContentModel(contentSpec.type, fQName, null);
            }
        } 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);

        // REVISIT: has to be fLeafCount because we convert x+ to x,x*, one more leaf
        return new DFAContentModel(  cmn, fLeafCount, 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);
        if ((contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY) {
            //nodeRet = new CMAny(contentSpec.type, -1, fLeafCount++);
            nodeRet = new CMAny(contentSpec.type, (String)contentSpec.otherValue, fLeafCount++);
        }
        else if ((contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_OTHER) {
            nodeRet = new CMAny(contentSpec.type, (String)contentSpec.otherValue, fLeafCount++);
        }
        else if ((contentSpec.type & 0x0f) == XMLContentSpec.CONTENTSPECNODE_ANY_LOCAL) {
            nodeRet = new CMAny(contentSpec.type, null, fLeafCount++);
        }
        //
        //  If this node is a leaf, then its an easy one. We just add it
        //  to the tree.
        //
        else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
            //
            //  Create a new leaf node, and pass it the current leaf count,
            //  which is its DFA state position. Bump the leaf count after
            //  storing it. This makes the positions zero based since we
            //  store first and then increment.
            //
            fQName.setValues(null, (String)contentSpec.value,
                              (String)contentSpec.value, (String)contentSpec.otherValue);
            nodeRet = new CMLeaf(fQName, fLeafCount++);
        }
        else {
            //
            //  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];
            final int rightNode = ((int[])contentSpec.otherValue)[0];

            if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE)
                ||  (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ)) {
                //
                //  Recurse on both children, and return a binary op node
                //  with the two created sub nodes as its children. The node
                //  type is the same type as the source.
                //

                nodeRet = new CMBinOp( contentSpec.type, buildSyntaxTree(leftNode, contentSpec)
                                       , buildSyntaxTree(rightNode, contentSpec));
            }
            else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE) {
                nodeRet = new CMUniOp( contentSpec.type, buildSyntaxTree(leftNode, contentSpec));
            }
            else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE
                  || contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE
                  || contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) {
                nodeRet = new CMUniOp(contentSpec.type, buildSyntaxTree(leftNode, contentSpec));
            }
            else {
                throw new RuntimeException("ImplementationMessages.VAL_CST");
            }
        }
        // And return our new node for this level
        return nodeRet;
    }

    /**
     * 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,
                                                     (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 = contentSpec.value != null
                           ? ((int[])(contentSpec.value))[0] : -1;
        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 AbstractDTDGrammar class : "+contentSpec.type);

    } // contentSpecTree(int,XMLContentSpec,ChildrenList)

    // ensure capacity

    private void ensureElementDeclCapacity(int chunk) {
        if (chunk >= fElementDeclName.length) {
            fElementDeclIsExternal = resize(fElementDeclIsExternal,
                                     fElementDeclIsExternal.length * 2);

            fElementDeclName = resize(fElementDeclName, fElementDeclName.length * 2);
            fElementDeclType = resize(fElementDeclType, fElementDeclType.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);
        }
        else if (fElementDeclName[chunk] != null) {
            return;
        }

        fElementDeclIsExternal[chunk] = new int[CHUNK_SIZE];
        fElementDeclName[chunk] = new QName[CHUNK_SIZE];
        fElementDeclType[chunk] = new short[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];
        return;
    }

    private void ensureAttributeDeclCapacity(int chunk) {

        if (chunk >= fAttributeDeclName.length) {
            fAttributeDeclIsExternal = resize(fAttributeDeclIsExternal,
                                       fAttributeDeclIsExternal.length * 2);
            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);
            fAttributeDeclNonNormalizedDefaultValue = resize(fAttributeDeclNonNormalizedDefaultValue, fAttributeDeclNonNormalizedDefaultValue.length * 2);
            fAttributeDeclNextAttributeDeclIndex = resize(fAttributeDeclNextAttributeDeclIndex, fAttributeDeclNextAttributeDeclIndex.length * 2);
        }
        else if (fAttributeDeclName[chunk] != null) {
            return;
        }

        fAttributeDeclIsExternal[chunk] = new int[CHUNK_SIZE];
        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];
        fAttributeDeclNonNormalizedDefaultValue[chunk] = new String[CHUNK_SIZE];
        fAttributeDeclNextAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
        return;
    }

    private void ensureEntityDeclCapacity(int chunk) {
        if (chunk >= fEntityName.length) {
            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);
        }
        else if (fEntityName[chunk] != null) {
            return;
        }

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

    private void ensureNotationDeclCapacity(int chunk) {
        if (chunk >= fNotationName.length) {
            fNotationName = resize(fNotationName, fNotationName.length * 2);
            fNotationPublicId = resize(fNotationPublicId, fNotationPublicId.length * 2);
            fNotationSystemId = resize(fNotationSystemId, fNotationSystemId.length * 2);
            fNotationBaseSystemId = resize(fNotationBaseSystemId, fNotationBaseSystemId.length * 2);
        }
        else if (fNotationName[chunk] != null) {
            return;
        }

        fNotationName[chunk] = new String[CHUNK_SIZE];
        fNotationPublicId[chunk] = new String[CHUNK_SIZE];
        fNotationSystemId[chunk] = new String[CHUNK_SIZE];
        fNotationBaseSystemId[chunk] = new String[CHUNK_SIZE];
        return;
    }

    private void ensureContentSpecCapacity(int chunk) {
        if (chunk >= fContentSpecType.length) {
            fContentSpecType = resize(fContentSpecType, fContentSpecType.length * 2);
            fContentSpecValue = resize(fContentSpecValue, fContentSpecValue.length * 2);
            fContentSpecOtherValue = resize(fContentSpecOtherValue, fContentSpecOtherValue.length * 2);
        }
        else if (fContentSpecType[chunk] != null) {
            return;
        }

        fContentSpecType[chunk] = new short[CHUNK_SIZE];
        fContentSpecValue[chunk] = new Object[CHUNK_SIZE];
        fContentSpecOtherValue[chunk] = new Object[CHUNK_SIZE];
        return;
    }

    //
    // 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 static int[][] resize(int array[][], int newsize) {
        int newarray[][] = new int[newsize][];
        System.arraycopy(array, 0, newarray, 0, array.length);
        return newarray;
    }

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

    private static Object[][] resize(Object array[][], int newsize) {
        Object newarray[][] = new Object[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 static String[][][] resize(String array[][][], int newsize) {
        String newarray[][][] = new String[newsize] [][];
        System.arraycopy(array, 0, newarray, 0, array.length);
        return newarray;
    }

    //
    // Classes
    //

    /**
     * Children list for <code>contentSpecTree</code> method.
     *
     * @xerces.internal
     *
     * @author Eric Ye, IBM
     */
    private static class ChildrenList {

        //
        // Data
        //

        /** Length. */
        public int length = 0;

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

        /** Left and right children names. */
        public QName[] qname = new QName[2];

        /** Left and right children types. */
        public int[] type = new int[2];

        //
        // Constructors
        //

        public ChildrenList () {}

    } // class ChildrenList

    //
    // Classes
    //

    /**
     * A simple Hashtable implementation that takes a tuple (String, String)
     * as the key and a int as value.
     *
     * @xerces.internal
     *
     * @author Eric Ye, IBM
     * @author Andy Clark, IBM
     */
    protected static final class QNameHashtable {

        //
        // Constants
        //

        /** 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(String key, int value) {

            int hash = (key.hashCode() & 0x7FFFFFFF) % HASHTABLE_SIZE;
            Object[] bucket = fHashTable[hash];

            if (bucket == null) {
                bucket = new Object[1 + 2*INITIAL_BUCKET_SIZE];
                bucket[0] = new int[]{1};
                bucket[1] = key;
                bucket[2] = new int[]{value};
                fHashTable[hash] = bucket;
            } else {
                int count = ((int[])bucket[0])[0];
                int offset = 1 + 2*count;
                if (offset == bucket.length) {
                    int newSize = count + INITIAL_BUCKET_SIZE;
                    Object[] newBucket = new Object[1 + 2*newSize];
                    System.arraycopy(bucket, 0, newBucket, 0, offset);
                    bucket = newBucket;
                    fHashTable[hash] = bucket;
                }
                boolean found = false;
                int j=1;
                for (int i=0; i<count; i++){
                    if ((String)bucket[j] == key) {
                        ((int[])bucket[j+1])[0] = value;
                        found = true;
                        break;
                    }
                    j += 2;
                }
                if (! found) {
                    bucket[offset++] = key;
                    bucket[offset]= new int[]{value};
                    ((int[])bucket[0])[0] = ++count;
                }

            }
            //System.out.println("put("+key+" -> "+value+')');
            //System.out.println("get("+key+") -> "+get(key));

        } // put(int,String,String,int)

        /** Returns the value associated with the specified key tuple. */
        public int get(String key) {
            int hash = (key.hashCode() & 0x7FFFFFFF) % HASHTABLE_SIZE;
            Object[] bucket = fHashTable[hash];

            if (bucket == null) {
                return -1;
            }
            int count = ((int[])bucket[0])[0];

            int j=1;
            for (int i=0; i<count; i++){
                if ((String)bucket[j] == key) {
                    return ((int[])bucket[j+1])[0];
                }
                j += 2;
            }
            return -1;

        } // get(int,String,String)

    }  // class QNameHashtable

    //
    // EntityState methods
    //
    public boolean isEntityDeclared (String name){
        return (getEntityDeclIndex(name)!=-1)?true:false;
    }

    public boolean isEntityUnparsed (String name){
        int entityIndex = getEntityDeclIndex(name);
        if (entityIndex >-1) {
            int chunk = entityIndex >> CHUNK_SHIFT;
            int index = entityIndex & CHUNK_MASK;
            //for unparsed entity notation!=null
            return (fEntityNotation[chunk][index]!=null)?true:false;
        }
        return false;
    }
} // class DTDGrammar
