/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000 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 org.apache.xerces.validators.dtd;

import org.apache.xerces.dom.DocumentImpl;
import org.apache.xerces.framework.XMLContentSpec;
import org.apache.xerces.framework.XMLDTDScanner;
import org.apache.xerces.readers.XMLEntityHandler;
import org.apache.xerces.utils.QName;
import org.apache.xerces.utils.StringPool;
import org.apache.xerces.validators.common.Grammar;
import org.apache.xerces.validators.common.XMLAttributeDecl;
import org.apache.xerces.validators.common.XMLElementDecl;
import org.apache.xerces.validators.datatype.DatatypeValidatorFactoryImpl;
import org.apache.xerces.validators.schema.XUtil;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;

/**
 * A DTD grammar. This class is an EventHandler to receive callbacks from
 * the XMLDTDScanner. When the callbacks are received, the grammar structures
 * are directly populated from the callback information.
 * <p>
 * In addition to being a recipient of scanner callbacks, the DTD grammar
 * class can act as a pass-through filter for the DTD events. This is useful
 * for parsers that must expose the DTD information to the application. (e.g.
 * SAX2 DeclHandler callbacks.)
 *
 * @author Andy Clark
 * @version $Id$
 */
public class DTDGrammar
    extends Grammar 
    implements XMLDTDScanner.EventHandler {

    // REVISIT: The grammar access currently implemented in this grammar
    //          instance is a draft implementation and should be revisited
    //          in order to design a proper DTD for the this grammar
    //          representation. -Ac

    //
    // Constants
    //

    /** Chunk shift. */
    private static final int CHUNK_SHIFT = 8; // 2^8 = 256

    /** Chunk size. */
    private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);

    /** Chunk mask. */
    private static final int CHUNK_MASK = CHUNK_SIZE - 1;

    /** Initial chunk count. */
    private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k

    //
    // Data
    //

    // string pool

    /** String pool. */
    private StringPool fStringPool;

    // "compiled" information structures

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

    /** Attribute declaration. */
    private XMLAttributeDecl fAttributeDecl = new XMLAttributeDecl();

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

    // grammar document

    /** Grammar document. */
    private Document fGrammarDocument;

    /** Root element. */
    private Element fRootElement;

    private QName fRootElementQName = new QName();

    /** Current element. */
    private Element fCurrentElement;

    // pass-through

    /** flag if the elementDecl is External. */
    private int fElementDeclIsExternal[][] = new int[INITIAL_CHUNK_COUNT][];
    /** Mapping for element declarations. */
    private int fElementDeclMap[][] = new int[INITIAL_CHUNK_COUNT][];

    /** flag if the AttributeDecl is External. */
    private int fAttributeDeclIsExternal[][] = new int[INITIAL_CHUNK_COUNT][];
    /** Mapping for attribute declarations. */
    private int fAttributeDeclMap[][] = new int[INITIAL_CHUNK_COUNT][];

    /** Mapping for content spec nodes. */
    private int fContentSpecMap[][] = new int[INITIAL_CHUNK_COUNT][];

    // temp vars

    private QName fQName = new QName();

    //
    // Constructors
    //

    /** Default constructor. */
    public DTDGrammar(StringPool stringPool) {
        reset(stringPool);
    }

    //
    // Public methods
    //

    /** Resets the DTD grammar. */
    public void reset(StringPool stringPool) {
        fStringPool = stringPool;
    }

    //
    // XMLDTDScanner.EventHandler methods
    //

    /** Start of DTD. */
    public void callStartDTD() throws Exception {
        
        // setup grammar document
        setGrammarDocument(null);
        fGrammarDocument = new DocumentImpl();
        fRootElement = fGrammarDocument.createElement("dtd");
        fCurrentElement = fRootElement;

    } // callStartDTD()

    /** End of DTD. */
    public void callEndDTD() throws Exception {

        // set grammar document
        setGrammarDocument(fGrammarDocument);

    } // callEndDTD()

    /**
     * Signal the Text declaration of an external entity.
     *
     * @param version the handle in the string pool for the version number
     * @param encoding the handle in the string pool for the encoding
     * @exception java.lang.Exception
     */
    public void callTextDecl(int version, int encoding) throws Exception {

        // create text decl
        Element textDecl = fGrammarDocument.createElement("textDecl");
        textDecl.setAttribute("version", fStringPool.toString(version));
        textDecl.setAttribute("encoding", fStringPool.toString(encoding));
        fCurrentElement.appendChild(textDecl);

    } // callTextDecl(int,int)

    /**
     * Called when the doctype decl is scanned
     *
     * @param rootElementType handle of the rootElement
     * @param publicId StringPool handle of the public id
     * @param systemId StringPool handle of the system id
     * @exception java.lang.Exception
     */
    public void doctypeDecl(QName rootElement, int publicId, int systemId) 
        throws Exception {

        // create doctype decl
        Element doctypeDecl = fGrammarDocument.createElement("doctypeDecl");
        doctypeDecl.setAttribute("name", fStringPool.toString(rootElement.rawname));
        if (rootElement.uri != -1) {
            doctypeDecl.setAttribute("xmlns:"+fStringPool.toString(rootElement.prefix),
                                     fStringPool.toString(rootElement.uri));
        }
        doctypeDecl.setAttribute("publicId", fStringPool.toString(publicId));
        doctypeDecl.setAttribute("systemId", fStringPool.toString(systemId));
        fCurrentElement.appendChild(doctypeDecl);

        //fRootElementQName.setValues(-1, rootElement.rawname, -1, -1);
        fRootElementQName.setValues(rootElement);

    } // doctypeDecl(QName,int,int);

    /**
     * Called when the DTDScanner starts reading from the external subset
     *
     * @param publicId StringPool handle of the public id
     * @param systemId StringPool handle of the system id
     * @exception java.lang.Exception
     */
    public void startReadingFromExternalSubset(int publicId, int systemId) 
        throws Exception {

        // create external subset
        Element externalSubset = fGrammarDocument.createElement("external");
        externalSubset.setAttribute("publicId", fStringPool.toString(publicId));
        externalSubset.setAttribute("systemId", fStringPool.toString(systemId));
        fCurrentElement.appendChild(externalSubset);
        fCurrentElement = externalSubset;

    } // startReadingFromExternalSubset(int,int)

    /**
     * Called when the DTDScanner stop reading from the external subset
     *
     * @exception java.lang.Exception
     */
    public void stopReadingFromExternalSubset() throws Exception {

        // get out of external subset
        fCurrentElement = (Element)fCurrentElement.getParentNode();

    } // stopReadingFromExternalSubset()

    /**
     * Add an element declaration (forward reference)
     *
     * @param handle to the name of the element being declared
     * @return handle to the element whose declaration was added
     * @exception java.lang.Exception
     */
    public int addElementDecl(QName elementDecl) throws Exception {

        // create element decl element
        Element elementDeclElement = fGrammarDocument.createElement("elementDecl");
        elementDeclElement.setAttribute("name", fStringPool.toString(elementDecl.localpart));
        if (elementDecl.uri != -1) {
            elementDeclElement.setAttribute("xmlns:"+fStringPool.toString(elementDecl.prefix),
                                            fStringPool.toString(elementDecl.uri));
        }
        fCurrentElement.appendChild(elementDeclElement);

        // create element decl
        int elementDeclIndex = createElementDecl();

        // set element decl values
        fElementDecl.clear();
        fElementDecl.name.setValues(elementDecl);
        setElementDecl(elementDeclIndex, fElementDecl);

        // return index
        return elementDeclIndex;

    } // addElementDecl(QName):int

    /**
     * Add an element declaration
     *
     * @param handle to the name of the element being declared
     * @param contentSpecType handle to the type name of the content spec
     * @param ContentSpec handle to the content spec node for the contentSpecType
     * @return handle to the element declaration that was added 
     * @exception java.lang.Exception
     */
    public int addElementDecl(QName elementDecl, 
                              int contentSpecType, 
                              int contentSpec,
                              boolean isExternal) throws Exception {

        // create element decl element
        Element elementDeclElement = fGrammarDocument.createElement("elementDecl");
        elementDeclElement.setAttribute("name", fStringPool.toString(elementDecl.localpart));
        if (elementDecl.uri != -1) {
            elementDeclElement.setAttribute("xmlns:"+fStringPool.toString(elementDecl.prefix),
                                            fStringPool.toString(elementDecl.uri));
        }
        elementDeclElement.setAttribute("type", fStringPool.toString(contentSpecType));
        // REVISIT: Traverse content spec structure, building content model
        //          description to put into grammar document.
        fCurrentElement.appendChild(elementDeclElement);

        // create element decl
        int elementDeclIndex = createElementDecl();

        // set element decl values
        fElementDecl.clear();
        fElementDecl.name.setValues(elementDecl);
        fElementDecl.type = contentSpecType;
        fElementDecl.contentSpecIndex = contentSpec;
        setElementDecl(elementDeclIndex, fElementDecl);
        
        int chunk = elementDeclIndex >> CHUNK_SHIFT;
        int index = elementDeclIndex & CHUNK_MASK;
        ensureElementDeclCapacity(chunk);
        fElementDeclIsExternal[chunk][index] = isExternal? 1 : 0;

        // return index
        return elementDeclIndex;

    } // addElementDecl(QName,int,int):int

    protected void putElementNameMapping(QName name, int scope,
                                         int elementDeclIndex) {
        fQName.uri = -1;
        fQName.localpart = name.rawname;
        super.putElementNameMapping(fQName, scope, elementDeclIndex);
    }

    /***
    public int getElementDeclIndex(int localpartIndex, int scopeIndex) {
        //System.out.println("getElementDeclIndex: "+localpartIndex+", "+scopeIndex);
        return super.getElementDeclIndex(localpartIndex, scopeIndex);
    }

    public int getElementDeclIndex(int uriIndex, int localpartIndex, int scopeIndex) {
        //System.out.println("!!! getElementDeclIndex: "+uriIndex+", "+localpartIndex+", "+scopeIndex);
        return super.getElementDeclIndex(localpartIndex, -1);
    }
    /***/
    
    public int getElementDeclIndex(QName element, int scopeIndex) {
        //System.out.println("getElementDeclIndex: "+element+", "+scopeIndex);
        return super.getElementDeclIndex(element.rawname, -1);
    }

    public void setElementDeclDTD(int elementDeclIndex, XMLElementDecl elementDecl) {
        super.setElementDecl(elementDeclIndex, elementDecl);
    }

    private XMLContentSpec fTempContentSpec = new XMLContentSpec();

    /***
    public void setContentSpecLeaf(int contentSpecIndex, QName elementName) {
        fTempContentSpec.setValues(XMLContentSpec.CONTENTSPECNODE_LEAF, elementName.rawname, -1);
        super.setContentSpec(contentSpecIndex, fTempContentSpec);
    }
    /***/

    public void setElementDeclIsExternal(int elementDeclIndex, boolean  isExternal) {
        int chunk = elementDeclIndex >> CHUNK_SHIFT;
        int index = elementDeclIndex & CHUNK_MASK;
        ensureElementDeclCapacity(chunk);
        fElementDeclIsExternal[chunk][index] = isExternal? 1 : 0;
    }

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

    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 boolean getRootElementQName(QName root) {
        if (fRootElementQName.rawname == -1) {
            return false;
        }
        root.setValues(fRootElementQName);
        return true;
    }

    /**
     * Add an attribute definition
     *
     * @param handle to the element whose attribute is being declared
     * @param attName StringPool handle to the attribute name being declared
     * @param attType type of the attribute
     * @param enumeration StringPool handle of the attribute's enumeration list (if any)
     * @param attDefaultType an integer value denoting the DefaultDecl value
     * @param attDefaultValue StringPool handle of this attribute's default value
     * @return handle to the attribute definition
     * @exception java.lang.Exception
     */
    public int addAttDef(QName elementDecl, QName attributeDecl, 
                         int attType, boolean attList, int enumeration, 
                         int attDefaultType, int attDefaultValue, boolean isExternal) 
        throws Exception {
        /****
        System.out.println("---add attr--- "+attributeDecl.localpart
                  +","+attType        
                  +","+attDefaultType        
                  +","+isExternal);
         /****/

        // create attribute decl element
        Element attributeDeclElement = fGrammarDocument.createElement("attributeDecl");
        attributeDeclElement.setAttribute("element", fStringPool.toString(elementDecl.localpart));
        attributeDeclElement.setAttribute("name", fStringPool.toString(attributeDecl.localpart));
        if (attributeDecl.uri != -1) {
            attributeDeclElement.setAttribute("xmlns:"+fStringPool.toString(attributeDecl.prefix),
                                              fStringPool.toString(attributeDecl.uri));
        }
        attributeDeclElement.setAttribute("type", fStringPool.toString(attType));
        // REVISIT: Add enumeration information to grammar document.
        // REVISIT: Do the default type, value better.
        attributeDeclElement.setAttribute("defaultType", fStringPool.toString(attDefaultType));
        attributeDeclElement.setAttribute("defaultValue", fStringPool.toString(attDefaultValue));
        fCurrentElement.appendChild(attributeDeclElement);

        // create attribute decl
        int attributeDeclIndex = createAttributeDecl();

        // find the dataTypeValidator associcated with this attType
        String attTypeString = "";
        switch (attType) {
        case XMLAttributeDecl.TYPE_CDATA:
            attTypeString = "string";
        case XMLAttributeDecl.TYPE_ENTITY:
            attTypeString = "ENTITY";;
        case XMLAttributeDecl.TYPE_ENUMERATION:
            attTypeString = "ENUMERATION";;
        case XMLAttributeDecl.TYPE_ID:
            attTypeString = "ID";;
        case XMLAttributeDecl.TYPE_IDREF:
            attTypeString = "IDREF";;
        case XMLAttributeDecl.TYPE_NMTOKEN:
            attTypeString = "NMTOKEN";;
        case XMLAttributeDecl.TYPE_NOTATION:
            attTypeString = "NOTATION";;
        default:
            ;
        }

        // set attribute decl values
        fAttributeDecl.clear();
        fAttributeDecl.name.setValues(attributeDecl);
        fAttributeDecl.type = attType;
        fAttributeDecl.list = attList;
        fAttributeDecl.enumeration = enumeration;
        fAttributeDecl.datatypeValidator = 
            DatatypeValidatorFactoryImpl.getDatatypeRegistry().getDatatypeValidator(attTypeString);
        // REVISIT: Don't forget the enumeration
        fAttributeDecl.defaultType = attDefaultType;
        fAttributeDecl.defaultValue = fStringPool.toString(attDefaultValue);

        int elementDeclIndex = getElementDeclIndex(elementDecl, -1);
        setAttributeDecl(elementDeclIndex, attributeDeclIndex, fAttributeDecl);

        int chunk = attributeDeclIndex >> CHUNK_SHIFT;
        int index = attributeDeclIndex & CHUNK_MASK;
        ensureAttributeDeclCapacity(chunk);
        fAttributeDeclIsExternal[chunk][index] = isExternal ?  1 : 0;

        // return index
        return attributeDeclIndex;

    } // addAttDef(QName,QName,int,int,int,int):int

    /**
     * create an XMLContentSpec for a leaf
     *
     * @param nameIndex StringPool handle to the name (Element) for the node
     * @return handle to the newly create XMLContentSpec
     * @exception java.lang.Exception
     */
    public int addUniqueLeafNode(int nameIndex) throws Exception {

        // create content spec node
        int contentSpecIndex = createContentSpec();

        // set content spec node values
        fContentSpec.setValues(XMLContentSpec.CONTENTSPECNODE_LEAF, 
                               nameIndex, -1);
        setContentSpec(contentSpecIndex, fContentSpec);

        // return index 
        return contentSpecIndex;

    } // addUniqueLeafNode(int):int

    /**
     * Create an XMLContentSpec for a single non-leaf
     * 
     * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_*
     * @param nodeValue handle to an XMLContentSpec
     * @return handle to the newly create XMLContentSpec
     * @exception java.lang.Exception
     */
    public int addContentSpecNode(int nodeType, 
                                  int nodeValue) throws Exception {

        // create content spec node
        int contentSpecIndex = createContentSpec();

        // set content spec node values
        fContentSpec.setValues(nodeType, nodeValue, -1);
        setContentSpec(contentSpecIndex, fContentSpec);

        // return index 
        return contentSpecIndex;

    } // addContentSpecNode(int,int):int

    /**
     * Create an XMLContentSpec for a two child leaf
     *
     * @param nodeType the type of XMLContentSpec to create - from XMLContentSpec.CONTENTSPECNODE_*
     * @param leftNodeIndex handle to an XMLContentSpec
     * @param rightNodeIndex handle to an XMLContentSpec
     * @return handle to the newly create XMLContentSpec
     * @exception java.lang.Exception
     */
    public int addContentSpecNode(int nodeType, 
                                  int leftNodeIndex, 
                                  int rightNodeIndex) throws Exception {

        // create content spec node
        int contentSpecIndex = createContentSpec();

        // set content spec node values
        fContentSpec.setValues(nodeType, 
                               leftNodeIndex, rightNodeIndex);
        setContentSpec(contentSpecIndex, fContentSpec);

        // return index 
        return contentSpecIndex;

    } // addContentSpecNode(int,int,int):int

    /**
     * Create a string representation of an XMLContentSpec tree
     * 
     * @param handle to an XMLContentSpec
     * @return String representation of the content spec tree
     * @exception java.lang.Exception
     */
    public String getContentSpecNodeAsString(int nodeIndex) throws Exception {
        return XMLContentSpec.toString(this, fStringPool, nodeIndex);
    }

    /**
     * Start the scope of an entity declaration.
     *
     * @return <code>true</code> on success; otherwise
     *         <code>false</code> if the entity declaration is recursive.
     * @exception java.lang.Exception
     */
    public boolean startEntityDecl(boolean isPE, int entityName) 
        throws Exception {

        // create entity decl
        Element entityDecl = fGrammarDocument.createElement("entityDecl");
        entityDecl.setAttribute("name", fStringPool.toString(entityName));
        entityDecl.setAttribute("parameter", isPE ? "true" : "false");
        fCurrentElement.appendChild(entityDecl);
        fCurrentElement = entityDecl;

        // success
        return true;

    } // startEntityDecl(boolean,int):boolean

    /**
     * End the scope of an entity declaration.
     * @exception java.lang.Exception
     */
    public void endEntityDecl() throws Exception {

        // get out of entity decl
        fCurrentElement = (Element)fCurrentElement.getParentNode();

    } // endEntityDecl()

    /**
     * Add a declaration for an internal parameter entity
     *
     * @param name StringPool handle of the parameter entity name
     * @param value StringPool handle of the parameter entity value
     * @return handle to the parameter entity declaration
     * @exception java.lang.Exception
     */
    public int addInternalPEDecl(int name, int value) throws Exception {

        // create internal PE decl
        Element internalPEDecl = fGrammarDocument.createElement("internalPEDecl");
        internalPEDecl.setAttribute("name", fStringPool.toString(name));
        internalPEDecl.setAttribute("value", fStringPool.toString(value));
        fCurrentElement.appendChild(internalPEDecl);

        // REVISIT: What is my responsibility for creating a handle?
        int peDeclIndex = -1;

        // return index
        return peDeclIndex;

    } // addInternalPEDecl(int,int):int

    /**
     * Add a declaration for an external parameter entity
     *
     * @param name StringPool handle of the parameter entity name
     * @param publicId StringPool handle of the publicId
     * @param systemId StringPool handle of the systemId
     * @return handle to the parameter entity declaration
     * @exception java.lang.Exception
     */
    public int addExternalPEDecl(int name, 
                                 int publicId, 
                                 int systemId) throws Exception {
        
        // create external PE decl
        Element externalPEDecl = fGrammarDocument.createElement("externalPEDecl");
        externalPEDecl.setAttribute("name", fStringPool.toString(name));
        externalPEDecl.setAttribute("publicId", fStringPool.toString(publicId));
        externalPEDecl.setAttribute("systemId", fStringPool.toString(systemId));
        fCurrentElement.appendChild(externalPEDecl);

        // REVISIT: What is my responsibility for creating a handle?
        int peDeclIndex = -1;

        // return index
        return peDeclIndex;

    } // addExternalPEDecl(int,int,int):int

    /**
     * Add a declaration for an internal entity
     *
     * @param name StringPool handle of the entity name
     * @param value StringPool handle of the entity value
     * @return handle to the entity declaration
     * @exception java.lang.Exception
     */
    public int addInternalEntityDecl(int name, int value) throws Exception {

        // create internal entity decl
        Element internalEntityDecl = fGrammarDocument.createElement("internalEntityDecl");
        internalEntityDecl.setAttribute("name", fStringPool.toString(name));
        internalEntityDecl.setAttribute("value", fStringPool.toString(value));
        fCurrentElement.appendChild(internalEntityDecl);
            
        // REVISIT: What is my responsibility for creating a handle?
        int internalEntityDeclIndex = -1;

        // return index
        return internalEntityDeclIndex;

    } // addInternalEntityDecl(int,int):int

    /**
     * Add a declaration for an entity
     *
     * @param name StringPool handle of the entity name
     * @param publicId StringPool handle of the publicId
     * @param systemId StringPool handle of the systemId
     * @return handle to the entity declaration
     * @exception java.lang.Exception
     */
    public int addExternalEntityDecl(int name, 
                                     int publicId, 
                                     int systemId) throws Exception {

        // create external entity decl
        Element externalEntityDecl = fGrammarDocument.createElement("externalEntityDecl");
        externalEntityDecl.setAttribute("name", fStringPool.toString(name));
        externalEntityDecl.setAttribute("publicId", fStringPool.toString(publicId));
        externalEntityDecl.setAttribute("systemId", fStringPool.toString(systemId));
        fCurrentElement.appendChild(externalEntityDecl);
            
        // REVISIT: What is my responsibility for creating a handle?
        int externalEntityDeclIndex = -1;

        // return index
        return externalEntityDeclIndex;

    } // addExternalEntityDecl(int,int,int):int

    /**
     * Add a declaration for an unparsed entity
     *
     * @param name StringPool handle of the entity name
     * @param publicId StringPool handle of the publicId
     * @param systemId StringPool handle of the systemId
     * @param notationName StringPool handle of the notationName
     * @return handle to the entity declaration
     * @exception java.lang.Exception
     */
    public int addUnparsedEntityDecl(int name, 
                                     int publicId, int systemId, 
                                     int notationName) throws Exception {

        // create external entity decl
        Element unparsedEntityDecl = fGrammarDocument.createElement("unparsedEntityDecl");
        unparsedEntityDecl.setAttribute("name", fStringPool.toString(name));
        unparsedEntityDecl.setAttribute("publicId", fStringPool.toString(publicId));
        unparsedEntityDecl.setAttribute("systemId", fStringPool.toString(systemId));
        unparsedEntityDecl.setAttribute("notation", fStringPool.toString(notationName));
        fCurrentElement.appendChild(unparsedEntityDecl);
            
        // REVISIT: What is my responsibility for creating a handle?
        int unparsedEntityDeclIndex = -1;

        // return index
        return unparsedEntityDeclIndex;

    } // addUnparsedEntityDecl(int,int,int,int):int

    /**
     * Called when the scanner start scanning an enumeration
     * @return StringPool handle to a string list that will hold the enumeration names
     * @exception java.lang.Exception
     */
    public int startEnumeration() throws Exception {
            
        // create enumeration
        Element enumeration = fGrammarDocument.createElement("enumeration");
        fCurrentElement.appendChild(enumeration);
        fCurrentElement = enumeration;

        // REVISIT: What is my responsibility for creating a handle?
        //int enumIndex = -1;    
        int enumIndex = fStringPool.startStringList();

        // return index
        return enumIndex;

    } // startEnumeration():int

    /**
     * Add a name to an enumeration
     * @param enumIndex StringPool handle to the string list for the enumeration
     * @param elementType handle to the element that owns the attribute with the enumeration
     * @param attrName StringPool handle to the name of the attribut with the enumeration
     * @param nameIndex StringPool handle to the name to be added to the enumeration
     * @param isNotationType true if the enumeration is an enumeration of NOTATION names
     * @exception java.lang.Exception
     */
    public void addNameToEnumeration(int enumIndex, 
                                     int elementType, int attrName, 
                                     int nameIndex, 
                                     boolean isNotationType) throws Exception {
        
        // create enumeration literal
        Element literal = fGrammarDocument.createElement("literal");
        // REVISIT: How is this literal (and its parent enumeration)
        //          associated to an element and attribute name? This
        //          should be done better.
        literal.setAttribute("element", fStringPool.toString(elementType));
        literal.setAttribute("attribute", fStringPool.toString(attrName));
        literal.setAttribute("name", fStringPool.toString(nameIndex));
        literal.setAttribute("notation", isNotationType ? "true" : "false");
        fCurrentElement.appendChild(literal);

        //add the name to the stringList 
        fStringPool.addStringToList(enumIndex, nameIndex);

    } // addNameToEnumeration(int,int,int,int,boolean)

    /**
     * Finish processing an enumeration
     *
     * @param enumIndex handle to the string list which holds the enumeration to be finshed.
     * @exception java.lang.Exception
     */
    public void endEnumeration(int enumIndex) throws Exception {

        // get out of enumeration
        fCurrentElement = (Element)fCurrentElement.getParentNode();
        
        //finish the enumeration stringlist int the fStringPool
        fStringPool.finishStringList(enumIndex);

    } // endEnumeration(int)

    /**
     * Add a declaration for a notation
     *
     * @param notationName
     * @param publicId
     * @param systemId
     * @return handle to the notation declaration
     * @exception java.lang.Exception
     */
    public int addNotationDecl(int notationName, 
                               int publicId, int systemId) throws Exception {

        // create notation decl
        Element notationDecl = fGrammarDocument.createElement("notationDecl");
        notationDecl.setAttribute("name", fStringPool.toString(notationName));
        notationDecl.setAttribute("publicId", fStringPool.toString(publicId));
        notationDecl.setAttribute("systemId", fStringPool.toString(systemId));
        fCurrentElement.appendChild(notationDecl);

        // REVISIT: What is my responsibility for creating a handle?
        int notationDeclIndex = -1;

        // return index
        return notationDeclIndex;

    } // addNotationdecl(int,int,int):int

    /**
     * Called when a comment has been scanned
     *
     * @param data StringPool handle of the comment text
     * @exception java.lang.Exception
     */
    public void callComment(int data) throws Exception {
    }

    /**
     * Called when a processing instruction has been scanned
     * @param piTarget StringPool handle of the PI target
     * @param piData StringPool handle of the PI data
     * @exception java.lang.Exception
     */
    public void callProcessingInstruction(int piTarget, int piData) 
        throws Exception {

        // create pi
        ProcessingInstruction pi = 
            fGrammarDocument.createProcessingInstruction(fStringPool.toString(piTarget),
                                                         fStringPool.toString(piData));
        fCurrentElement.appendChild(pi);

    } // callProcessingInstruction(int,int)

    // deprecated -- removed from DOM Level 2

    /**
     * Supports DOM Level 2 internalSubset additions.
     * Called when the internal subset is completely scanned.
     */
    public void internalSubset(int internalSubset) throws Exception {
    }

    protected boolean isDTD() {
        return true;
    }

    //
    // Private methods
    //

    // ensure capacity

    /** Ensures storage for element declaration mappings. */
    private boolean ensureElementDeclCapacity(int chunk) {
        try {
            return fElementDeclMap[chunk][0] == 0;
        } catch (ArrayIndexOutOfBoundsException ex) {
            fElementDeclMap = resize(fElementDeclMap, 
                                     fElementDeclMap.length * 2);
            fElementDeclIsExternal = resize(fElementDeclIsExternal, 
                                     fElementDeclIsExternal.length * 2);
        } catch (NullPointerException ex) {
            // ignore
        }
        fElementDeclMap[chunk] = new int[CHUNK_SIZE];
        fElementDeclIsExternal[chunk] = new int[CHUNK_SIZE];
        return true;
    }

    /** Ensures storage for attribute declaration mappings. */
    private boolean ensureAttributeDeclCapacity(int chunk) {
        try {
            return fAttributeDeclMap[chunk][0] == 0;
        } catch (ArrayIndexOutOfBoundsException ex) {
            fAttributeDeclMap = resize(fAttributeDeclMap, 
                                       fAttributeDeclMap.length * 2);
            fAttributeDeclIsExternal = resize(fAttributeDeclIsExternal, 
                                       fAttributeDeclIsExternal.length * 2);
        } catch (NullPointerException ex) {
            // ignore
        }
        fAttributeDeclMap[chunk] = new int[CHUNK_SIZE];
        fAttributeDeclIsExternal[chunk] = new int[CHUNK_SIZE];
        return true;
    }

    /** Ensures storage for content spec mappings. */
    private boolean ensureContentSpecCapacity(int chunk) {
        try {
            return fContentSpecMap[chunk][0] == 0;
        } catch (ArrayIndexOutOfBoundsException ex) {
            fContentSpecMap = resize(fContentSpecMap, 
                                     fContentSpecMap.length * 2);
        } catch (NullPointerException ex) {
            // ignore
        }
        fContentSpecMap[chunk] = new int[CHUNK_SIZE];
        return true;
    }

    // resize initial chunk

    /** Resizes chunked integer arrays. */
    private int[][] resize(int array[][], int newsize) {
        int newarray[][] = new int[newsize][];
        System.arraycopy(array, 0, newarray, 0, array.length);
        return newarray;
    }

} // class DTDGrammar
