/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999,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.parsers;

import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.StringTokenizer;

import org.apache.xerces.dom.TextImpl;
import org.apache.xerces.framework.XMLAttrList;
import org.apache.xerces.framework.XMLContentSpec;
import org.apache.xerces.framework.XMLDocumentHandler;
import org.apache.xerces.framework.XMLParser;
import org.apache.xerces.readers.XMLEntityHandler;
import org.apache.xerces.utils.QName;
import org.apache.xerces.utils.StringPool;
import org.apache.xerces.validators.common.XMLAttributeDecl;
import org.apache.xerces.validators.common.XMLElementDecl;
import org.apache.xerces.validators.schema.XUtil;

import org.apache.xerces.dom.DeferredDocumentImpl;
import org.apache.xerces.dom.DocumentImpl;
import org.apache.xerces.dom.DocumentTypeImpl;
import org.apache.xerces.dom.NodeImpl;
import org.apache.xerces.dom.EntityImpl;
import org.apache.xerces.dom.NotationImpl;
import org.apache.xerces.dom.ElementDefinitionImpl;
import org.apache.xerces.dom.AttrImpl;
import org.apache.xerces.dom.TextImpl;
import org.apache.xerces.dom.ElementImpl;
import org.apache.xerces.dom.EntityImpl;
import org.apache.xerces.dom.EntityReferenceImpl;

import org.w3c.dom.Attr;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Entity;
import org.w3c.dom.EntityReference;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;

import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;

/**
 * DOMParser provides a parser which produces a W3C DOM tree as its output
 *
 * 
 * @version $Id$
 */
public class DOMParser
    extends XMLParser
    implements XMLDocumentHandler
    {

    //
    // Constants
    //

    // public

    /** Default programmatic document class name (org.apache.xerces.dom.DocumentImpl). */
    public static final String DEFAULT_DOCUMENT_CLASS_NAME = "org.apache.xerces.dom.DocumentImpl";

    /** Default deferred document class name (org.apache.xerces.dom.DeferredDocumentImpl). */
    public static final String DEFAULT_DEFERRED_DOCUMENT_CLASS_NAME = "org.apache.xerces.dom.DeferredDocumentImpl";

    // debugging

    /** Set to true to debug attribute list declaration calls. */
    private static final boolean DEBUG_ATTLIST_DECL = false;

    // features and properties

    /** Features recognized by this parser. */
    private static final String RECOGNIZED_FEATURES[] = {
        // SAX2 core features
        // Xerces features
        "http://apache.org/xml/features/dom/defer-node-expansion",
        "http://apache.org/xml/features/dom/create-entity-ref-nodes",
        "http://apache.org/xml/features/dom/include-ignorable-whitespace",
        // Experimental features
        "http://apache.org/xml/features/domx/grammar-access",
    };

    /** Properties recognized by this parser. */
    private static final String RECOGNIZED_PROPERTIES[] = {
        // SAX2 core properties
        // Xerces properties
        "http://apache.org/xml/properties/dom/document-class-name",
        "http://apache.org/xml/properties/dom/current-element-node",
    };

    //
    // Data
    //

    // common data

    protected Document fDocument;

    // deferred expansion data

    protected DeferredDocumentImpl fDeferredDocumentImpl;
    protected int                  fDocumentIndex;
    protected int                  fDocumentTypeIndex;
    protected int                  fCurrentNodeIndex;

    // full expansion data

    protected DocumentImpl fDocumentImpl;
    protected DocumentType fDocumentType;
    protected Node         fCurrentElementNode;

    // state

    protected boolean fInDTD;
    protected boolean fWithinElement;
    protected boolean fInCDATA;

    // features
    private boolean fGrammarAccess;

    // properties

    // REVISIT: Even though these have setters and getters, should they
    //          be protected visibility? -Ac
    private String  fDocumentClassName;
    private boolean fDeferNodeExpansion;
    private boolean fCreateEntityReferenceNodes;
    private boolean fIncludeIgnorableWhitespace;

    // built-in entities

    protected int fAmpIndex;
    protected int fLtIndex;
    protected int fGtIndex;
    protected int fAposIndex;
    protected int fQuotIndex;

    private boolean fSeenRootElement;

    private boolean fStringPoolInUse;

    private XMLAttrList fAttrList;

    //
    // Constructors
    //

    /** Default constructor. */
    public DOMParser() {

        initHandlers(false, this, this);

        // setup parser state
        init();

        // set default values
        try {
            setDocumentClassName(DEFAULT_DOCUMENT_CLASS_NAME);
            setCreateEntityReferenceNodes(true);
            setDeferNodeExpansion(true);
            setIncludeIgnorableWhitespace(true);
        } catch (SAXException e) {
            throw new RuntimeException("PAR001 Fatal error constructing DOMParser.");
        }

    } // <init>()

    //
    // Public methods
    //

    // document

    /** Returns the document. */
    public Document getDocument() {
        if (fDocumentImpl != null) {
            fDocumentImpl.setErrorChecking(true);
        }
        return fDocument;
    }

    // features and properties

    /**
     * Returns a list of features that this parser recognizes.
     * This method will never return null; if no features are
     * recognized, this method will return a zero length array.
     *
     * @see #isFeatureRecognized
     * @see #setFeature
     * @see #getFeature
     */
    public String[] getFeaturesRecognized() {

        // get features that super/this recognizes
        String superRecognized[] = super.getFeaturesRecognized();
        String thisRecognized[] = RECOGNIZED_FEATURES;

        // is one or the other the empty set?
        int thisLength = thisRecognized.length;
        if (thisLength == 0) {
            return superRecognized;
        }
        int superLength = superRecognized.length;
        if (superLength == 0) {
            return thisRecognized;
        }

        // combine the two lists and return
        String recognized[] = new String[superLength + thisLength];
        System.arraycopy(superRecognized, 0, recognized, 0, superLength);
        System.arraycopy(thisRecognized, 0, recognized, superLength, thisLength);
        return recognized;

    } // getFeaturesRecognized():String[]

    /**
     * Returns a list of properties that this parser recognizes.
     * This method will never return null; if no properties are
     * recognized, this method will return a zero length array.
     *
     * @see #isPropertyRecognized
     * @see #setProperty
     * @see #getProperty
     */
    public String[] getPropertiesRecognized() {

        // get properties that super/this recognizes
        String superRecognized[] = super.getPropertiesRecognized();
        String thisRecognized[] = RECOGNIZED_PROPERTIES;

        // is one or the other the empty set?
        int thisLength = thisRecognized.length;
        if (thisLength == 0) {
            return superRecognized;
        }
        int superLength = superRecognized.length;
        if (superLength == 0) {
            return thisRecognized;
        }

        // combine the two lists and return
        String recognized[] = new String[superLength + thisLength];
        System.arraycopy(superRecognized, 0, recognized, 0, superLength);
        System.arraycopy(thisRecognized, 0, recognized, superLength, thisLength);
        return recognized;

    }

    // resetting

    /** Resets the parser. */
    public void reset() throws Exception {
        if (fStringPoolInUse) {
            // we can't reuse the string pool, let's create another one
            fStringPool = new StringPool();
            fStringPoolInUse = false;
        }
        super.reset();
        init();
    }

    /** Resets or copies the parser. */
    public void resetOrCopy() throws Exception {
        super.resetOrCopy();
        init();
    }

    //
    // Protected methods
    //

    // initialization

    /**
     * Initializes the parser to a pre-parse state. This method is
     * called between calls to <code>parse()</code>.
     */
    protected void init() {

        // init common
        fDocument = null;

        // init deferred expansion
        fDeferredDocumentImpl = null;
        fDocumentIndex = -1;
        fDocumentTypeIndex = -1;
        fCurrentNodeIndex = -1;

        // init full expansion
        fDocumentImpl = null;
        fDocumentType = null;
        fCurrentElementNode = null;

        // state
        fInDTD = false;
        fWithinElement = false;
        fInCDATA = false;

        // built-in entities
        fAmpIndex = fStringPool.addSymbol("amp");
        fLtIndex = fStringPool.addSymbol("lt");
        fGtIndex = fStringPool.addSymbol("gt");
        fAposIndex = fStringPool.addSymbol("apos");
        fQuotIndex = fStringPool.addSymbol("quot");

        fSeenRootElement = false;
        fStringPoolInUse = false;

        fAttrList = new XMLAttrList(fStringPool);

    } // init()

    // features

    /**
     * This method sets whether the expansion of the nodes in the default
     * DOM implementation are deferred.
     *
     * @see #getDeferNodeExpansion
     * @see #setDocumentClassName
     */
    protected void setDeferNodeExpansion(boolean deferNodeExpansion) 
        throws SAXNotRecognizedException, SAXNotSupportedException {
        fDeferNodeExpansion = deferNodeExpansion;
    }

    /**
     * Returns true if the expansion of the nodes in the default DOM
     * implementation are deferred.
     *
     * @see #setDeferNodeExpansion
     */
    protected boolean getDeferNodeExpansion() 
        throws SAXNotRecognizedException, SAXNotSupportedException {
        return fDeferNodeExpansion;
    }

    /**
     * This feature determines whether entity references within
     * the document are included in the document tree as
     * EntityReference nodes.
     * <p>
     * Note: The children of the entity reference are always
     * added to the document. This feature only affects
     * whether an EntityReference node is also included
     * as the parent of the entity reference children.
     *
     * @param create True to create entity reference nodes; false
     *               to only insert the entity reference children.
     *
     * @see #getCreateEntityReferenceNodes
     */
    protected void setCreateEntityReferenceNodes(boolean create) 
        throws SAXNotRecognizedException, SAXNotSupportedException {
        fCreateEntityReferenceNodes = create;
    }

    /**
     * Returns true if entity references within the document are
     * included in the document tree as EntityReference nodes.
     *
     * @see #setCreateEntityReferenceNodes
     */
    public boolean getCreateEntityReferenceNodes() 
        throws SAXNotRecognizedException, SAXNotSupportedException {
        return fCreateEntityReferenceNodes;
    }

    /**
     * This feature determines whether text nodes that can be
     * considered "ignorable whitespace" are included in the DOM
     * tree.
     * <p>
     * Note: The only way that the parser can determine if text
     * is ignorable is by reading the associated grammar
     * and having a content model for the document. When
     * ignorable whitespace text nodes *are* included in
     * the DOM tree, they will be flagged as ignorable.
     * The ignorable flag can be queried by calling the
     * TextImpl#isIgnorableWhitespace():boolean method.
     *
     * @param include True to include ignorable whitespace text nodes;
     *                false to not include ignorable whitespace text
     *                nodes.
     *
     * @see #getIncludeIgnorableWhitespace
     */
    public void setIncludeIgnorableWhitespace(boolean include) 
        throws SAXNotRecognizedException, SAXNotSupportedException {
        fIncludeIgnorableWhitespace = include;
    }

    /**
     * Returns true if ignorable whitespace text nodes are included
     * in the DOM tree.
     *
     * @see #setIncludeIgnorableWhitespace
     */
    public boolean getIncludeIgnorableWhitespace() 
        throws SAXNotRecognizedException, SAXNotSupportedException {
        return fIncludeIgnorableWhitespace;
    }
    
    // properties

    /**
     * This method allows the programmer to decide which document
     * factory to use when constructing the DOM tree. However, doing
     * so will lose the functionality of the default factory. Also,
     * a document class other than the default will lose the ability
     * to defer node expansion on the DOM tree produced.
     *
     * @param documentClassName The fully qualified class name of the
     *                      document factory to use when constructing
     *                      the DOM tree.
     *
     * @see #getDocumentClassName
     * @see #setDeferNodeExpansion
     * @see #DEFAULT_DOCUMENT_CLASS_NAME
     */
    protected void setDocumentClassName(String documentClassName) 
        throws SAXNotRecognizedException, SAXNotSupportedException {

        // normalize class name
        if (documentClassName == null) {
            documentClassName = DEFAULT_DOCUMENT_CLASS_NAME;
        }

        // verify that this class exists and is of the right type
        try {
            Class _class = Class.forName(documentClassName);
            //if (!_class.isAssignableFrom(Document.class)) {
            if (!Document.class.isAssignableFrom(_class)) {
                throw new IllegalArgumentException("PAR002 Class, \""+documentClassName+"\", is not of type org.w3c.dom.Document."+"\n"+documentClassName);
            }
        }
        catch (ClassNotFoundException e) {
            throw new IllegalArgumentException("PAR003 Class, \""+documentClassName+"\", not found."+"\n"+documentClassName);
        }

        // set document class name
        fDocumentClassName = documentClassName;
        if (!documentClassName.equals(DEFAULT_DOCUMENT_CLASS_NAME)) {
            setDeferNodeExpansion(false);
        }

    } // setDocumentClassName(String)

    /**
     * Returns the fully qualified class name of the document factory
     * used when constructing the DOM tree.
     *
     * @see #setDocumentClassName
     */
    protected String getDocumentClassName() 
        throws SAXNotRecognizedException, SAXNotSupportedException {
        return fDocumentClassName;
    }

    /**
     * Returns the current element node.
     * <p>
     * Note: This method is not supported when the "deferNodeExpansion"
     *       property is set to true and the document factory is set to
     *       the default factory.
     */
    protected Element getCurrentElementNode() 
        throws SAXNotRecognizedException, SAXNotSupportedException {

        if (fCurrentElementNode != null &&
            fCurrentElementNode.getNodeType() == Node.ELEMENT_NODE) {
            return (Element)fCurrentElementNode;
        }
        return null;

    } // getCurrentElementNode():Element

    //
    // Configurable methods
    //

    /**
     * Set the state of any feature in a SAX2 parser.  The parser
     * might not recognize the feature, and if it does recognize
     * it, it might not be able to fulfill the request.
     *
     * @param featureId The unique identifier (URI) of the feature.
     * @param state The requested state of the feature (true or false).
     *
     * @exception SAXNotRecognizedException If the requested feature is
     *                                      not known.
     * @exception SAXNotSupportedException If the requested feature is
     *                                     known, but the requested state
     *                                     is not supported.
     */
    public void setFeature(String featureId, boolean state)
        throws SAXNotRecognizedException, SAXNotSupportedException {

        //
        // SAX2 core features
        //

        if (featureId.startsWith(SAX2_FEATURES_PREFIX)) {
            //
            // No additional SAX properties defined for DOMParser.
            // Pass request off to XMLParser for the common cases.
            //
        }

        //
        // Xerces features
        //

        else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) {
            String feature = featureId.substring(XERCES_FEATURES_PREFIX.length());
            //
            // http://apache.org/xml/features/dom/defer-node-expansion
            //   Allows the document tree returned by getDocument()
            //   to be constructed lazily. In other words, the DOM
            //   nodes are constructed as the tree is traversed.
            //   This allows the document to be returned sooner with
            //   the expense of holding all of the blocks of character
            //   data held in memory. Then again, lots of DOM nodes
            //   use a lot of memory as well.
            //
            if (feature.equals("dom/defer-node-expansion")) {
                if (fParseInProgress) {
                    throw new SAXNotSupportedException("PAR004 Cannot setFeature("+featureId + "): parse is in progress."+"\n"+featureId);
                }
                setDeferNodeExpansion(state);
                return;
            }
            //
            // http://apache.org/xml/features/dom/create-entity-ref-nodes
            //   This feature determines whether entity references within
            //   the document are included in the document tree as
            //   EntityReference nodes.
            //   Note: The children of the entity reference are always
            //         added to the document. This feature only affects
            //         whether an EntityReference node is also included
            //         as the parent of the entity reference children.
            //
            if (feature.equals("dom/create-entity-ref-nodes")) {
                setCreateEntityReferenceNodes(state);
                return;
            }

            //
            // http://apache.org/xml/features/dom/include-ignorable-whitespace
            //   This feature determines whether text nodes that can be
            //   considered "ignorable whitespace" are included in the DOM
            //   tree.
            //   Note: The only way that the parser can determine if text
            //         is ignorable is by reading the associated grammar
            //         and having a content model for the document. When
            //         ignorable whitespace text nodes *are* included in
            //         the DOM tree, they will be flagged as ignorable.
            //         The ignorable flag can be queried by calling the
            //         TextImpl#isIgnorableWhitespace():boolean method.
            //
            if (feature.equals("dom/include-ignorable-whitespace")) {
                setIncludeIgnorableWhitespace(state);
                return;
            }
            
            //
            // Experimental features
            //

            //
            // http://apache.org/xml/features/domx/grammar-access
            //   Allows grammar access in the DOM tree. Currently, this
            //   means that there is an XML Schema document tree as a
            //   child of the Doctype node.
            //
            if (feature.equals("domx/grammar-access")) {
                fGrammarAccess = state;
                return;
            }

            //
            // Pass request off to XMLParser for the common cases.
            //
        }

        //
        // Pass request off to XMLParser for the common cases.
        //
        super.setFeature(featureId, state);

    } // setFeature(String,boolean)

    /**
     * Query the current state of any feature in a SAX2 parser.  The
     * parser might not recognize the feature.
     *
     * @param featureId The unique identifier (URI) of the feature
     *                  being set.
     *
     * @return The current state of the feature.
     *
     * @exception SAXNotRecognizedException If the requested feature is
     *                                      not known.
     */
    public boolean getFeature(String featureId) 
        throws SAXNotRecognizedException, SAXNotSupportedException {

        //
        // SAX2 core features
        //

        if (featureId.startsWith(SAX2_FEATURES_PREFIX)) {
            //
            // No additional SAX properties defined for DOMParser.
            // Pass request off to XMLParser for the common cases.
            //
        }

        //
        // Xerces features
        //

        else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) {
            String feature = featureId.substring(XERCES_FEATURES_PREFIX.length());
            //
            // http://apache.org/xml/features/dom/defer-node-expansion
            //   Allows the document tree returned by getDocument()
            //   to be constructed lazily. In other words, the DOM
            //   nodes are constructed as the tree is traversed.
            //   This allows the document to be returned sooner with
            //   the expense of holding all of the blocks of character
            //   data held in memory. Then again, lots of DOM nodes
            //   use a lot of memory as well.
            //
            if (feature.equals("dom/defer-node-expansion")) {
                return getDeferNodeExpansion();
            }
            //
            // http://apache.org/xml/features/dom/create-entity-ref-nodes
            //   This feature determines whether entity references within
            //   the document are included in the document tree as
            //   EntityReference nodes.
            //   Note: The children of the entity reference are always
            //         added to the document. This feature only affects
            //         whether an EntityReference node is also included
            //         as the parent of the entity reference children.
            //
            else if (feature.equals("dom/create-entity-ref-nodes")) {
                return getCreateEntityReferenceNodes();
            }

            //
            // http://apache.org/xml/features/dom/include-ignorable-whitespace
            //   This feature determines whether text nodes that can be
            //   considered "ignorable whitespace" are included in the DOM
            //   tree.
            //   Note: The only way that the parser can determine if text
            //         is ignorable is by reading the associated grammar
            //         and having a content model for the document. When
            //         ignorable whitespace text nodes *are* included in
            //         the DOM tree, they will be flagged as ignorable.
            //         The ignorable flag can be queried by calling the
            //         TextImpl#isIgnorableWhitespace():boolean method.
            //
            if (feature.equals("dom/include-ignorable-whitespace")) {
                return getIncludeIgnorableWhitespace();
            }

            //
            // Experimental features
            //

            //
            // http://apache.org/xml/features/domx/grammar-access
            //   Allows grammar access in the DOM tree. Currently, this
            //   means that there is an XML Schema document tree as a
            //   child of the Doctype node.
            //
            if (feature.equals("domx/grammar-access")) {
                return fGrammarAccess;
            }

            //
            // Pass request off to XMLParser for the common cases.
            //
        }

        //
        // Pass request off to XMLParser for the common cases.
        //
        return super.getFeature(featureId);

    } // getFeature(String):boolean

    /**
     * Set the value of any property in a SAX2 parser.  The parser
     * might not recognize the property, and if it does recognize
     * it, it might not support the requested value.
     *
     * @param propertyId The unique identifier (URI) of the property
     *                   being set.
     * @param Object The value to which the property is being set.
     *
     * @exception SAXNotRecognizedException If the requested property is
     *                                      not known.
     * @exception SAXNotSupportedException If the requested property is
     *                                     known, but the requested
     *                                     value is not supported.
     */
    public void setProperty(String propertyId, Object value)
        throws SAXNotRecognizedException, SAXNotSupportedException {

        //
        // Xerces properties
        //

        if (propertyId.startsWith(XERCES_PROPERTIES_PREFIX)) {
            String property = propertyId.substring(XERCES_PROPERTIES_PREFIX.length());
            //
            // http://apache.org/xml/properties/dom/current-element-node
            //   Returns the current element node as the DOM Parser is
            //   parsing. This property is useful for determining the
            //   relative location of the document when an error is
            //   encountered. Note that this feature does *not* work
            //   when the http://apache.org/xml/features/dom/defer-node-expansion
            //   is set to true.
            //
            if (property.equals("dom/current-element-node")) {
                throw new SAXNotSupportedException("PAR005 Property, \""+propertyId+"\" is read-only.\n"+propertyId);
            }
            //
            // http://apache.org/xml/properties/dom/document-class-name
            //   This property can be used to set/query the name of the
            //   document factory.
            //
            else if (property.equals("dom/document-class-name")) {
                if (value != null && !(value instanceof String)) {
                    throw new SAXNotSupportedException("PAR006 Property value must be of type java.lang.String.");
                }
                setDocumentClassName((String)value);
                return;
            }
        }

        //
        // Pass request off to XMLParser for the common cases.
        //
        super.setProperty(propertyId, value);

    } // setProperty(String,Object)

    /**
     * Return the current value of a property in a SAX2 parser.
     * The parser might not recognize the property.
     *
     * @param propertyId The unique identifier (URI) of the property
     *                   being set.
     *
     * @return The current value of the property.
     *
     * @exception SAXNotRecognizedException If the requested property is
     *                                      not known.
     *
     * @see Configurable#getProperty
     */
    public Object getProperty(String propertyId) 
        throws SAXNotRecognizedException, SAXNotSupportedException {

        //
        // Xerces properties
        //

        if (propertyId.startsWith(XERCES_PROPERTIES_PREFIX)) {
            String property = propertyId.substring(XERCES_PROPERTIES_PREFIX.length());
            //
            // http://apache.org/xml/properties/dom/current-element-node
            //   Returns the current element node as the DOM Parser is
            //   parsing. This property is useful for determining the
            //   relative location of the document when an error is
            //   encountered. Note that this feature does *not* work
            //   when the http://apache.org/xml/features/dom/defer-node-expansion
            //   is set to true.
            //
            if (property.equals("dom/current-element-node")) {
                boolean throwException = false;
                try {
                    throwException = getFeature(XERCES_FEATURES_PREFIX+"dom/defer-node-expansion");
                }
                catch (SAXNotSupportedException e) {
                    // ignore
                }
                catch (SAXNotRecognizedException e) {
                    // ignore
                }
                if (throwException) {
                    throw new SAXNotSupportedException("PAR007 Current element node cannot be queried when node expansion is deferred.");
                }
                return getCurrentElementNode();
            }
            //
            // http://apache.org/xml/properties/dom/document-class-name
            //   This property can be used to set/query the name of the
            //   document factory.
            //
            else if (property.equals("dom/document-class-name")) {
                return getDocumentClassName();
            }
        }

        //
        // Pass request off to XMLParser for the common cases.
        //
        return super.getProperty(propertyId);

    } // getProperty(String):Object

    //
    // XMLParser methods
    //

    /** Start document. */
    public void startDocument() {

        // deferred expansion
        String documentClassName = null;
        try {
            documentClassName = getDocumentClassName();
        } catch (SAXException e) {
            throw new RuntimeException("PAR008 Fatal error getting document factory.");
        }
        boolean deferNodeExpansion = true;
        try {
            deferNodeExpansion = getDeferNodeExpansion();
        } catch (SAXException e) {
            throw new RuntimeException("PAR009 Fatal error reading expansion mode.");
        }
        try {
            boolean isDocumentImpl = fDocumentClassName.equals(DEFAULT_DOCUMENT_CLASS_NAME);
            boolean isDeferredImpl = fDocumentClassName.equals(DEFAULT_DEFERRED_DOCUMENT_CLASS_NAME);
            if (deferNodeExpansion && (isDocumentImpl || isDeferredImpl)) {
                boolean nsEnabled = false;
                try { nsEnabled = getNamespaces(); }
                catch (SAXException s) {}
                fDeferredDocumentImpl = new DeferredDocumentImpl(fStringPool, nsEnabled, fGrammarAccess);
                fStringPoolInUse = true;
                fDocument = fDeferredDocumentImpl;
                fDocumentIndex = fDeferredDocumentImpl.createDocument();
                fCurrentNodeIndex = fDocumentIndex;
            }

            // full expansion
            else {
                Class docClass = Class.forName(documentClassName);
                Class defaultDocClass = Class.forName(DEFAULT_DOCUMENT_CLASS_NAME);
                if (isDocumentImpl) {
                    fDocument = new DocumentImpl(fGrammarAccess);
                }
                else {
                    try {
                        Class documentClass = Class.forName(documentClassName);
                        fDocument = (Document)documentClass.newInstance();
                    }
                    catch (Exception e) {
                        // REVISIT: We've already checked the type of the factory
                        //          in the setDocumentClassName() method. The only
                        //          exception that can occur here is if the class
                        //          doesn't have a zero-arg constructor. -Ac
                    }
                }
                if (docClass.isAssignableFrom(defaultDocClass)) {
                    fDocumentImpl = (DocumentImpl)fDocument;
                    fDocumentImpl.setErrorChecking(false);
                }

                fCurrentElementNode = fDocument;
            }
        }
        catch (ClassNotFoundException e) {
            // REVISIT: Localize this message.
            throw new RuntimeException(documentClassName);
        }

    } // startDocument()

    /** End document. */
    public void endDocument() throws Exception {}

    /** XML declaration. */
    public void xmlDecl(int versionIndex, int encodingIndex, int standaloneIndex) throws Exception {

        // release strings
        fStringPool.releaseString(versionIndex);
        fStringPool.releaseString(encodingIndex);
        fStringPool.releaseString(standaloneIndex);
    }

    /** Text declaration. */
    public void textDecl(int versionIndex, int encodingIndex) throws Exception {

        // release strings
        fStringPool.releaseString(versionIndex);
        fStringPool.releaseString(encodingIndex);
    }

    /** Report the start of the scope of a namespace declaration. */
    public void startNamespaceDeclScope(int prefix, int uri) throws Exception {}

    /** Report the end of the scope of a namespace declaration. */
    public void endNamespaceDeclScope(int prefix) throws Exception {}
    
    

    /** Start element. */
    public void startElement(QName elementQName,
                             XMLAttrList xmlAttrList, int attrListIndex)
        throws Exception {

        // deferred expansion
        if (fDeferredDocumentImpl != null) {

            int element =
                fDeferredDocumentImpl.createElement(elementQName.rawname,
                                                    elementQName.uri,
                                                    xmlAttrList,
                                                    attrListIndex);
            fDeferredDocumentImpl.appendChild(fCurrentNodeIndex, element);
            fCurrentNodeIndex = element;
            fWithinElement = true;

            // identifier registration
            int index = xmlAttrList.getFirstAttr(attrListIndex);
            while (index != -1) {
                if (xmlAttrList.getAttType(index) == fStringPool.addSymbol("ID")) {
                    int nameIndex = xmlAttrList.getAttValue(index);
                    fDeferredDocumentImpl.putIdentifier(nameIndex, element);
                }
                index = xmlAttrList.getNextAttr(index);
            }

            // copy schema grammar, if needed
            if (!fSeenRootElement) {
                fSeenRootElement = true;
                if (fDocumentTypeIndex == -1) {
                    fDocumentTypeIndex = fDeferredDocumentImpl.createDocumentType(elementQName.rawname, -1, -1);
                    fDeferredDocumentImpl.appendChild(0, fDocumentTypeIndex);
                }
                if (fGrammarAccess) {
                    // REVISIT: How do we know which grammar is in use?
                    //Document schemaDocument = fValidator.getSchemaDocument();
                    int size = fGrammarResolver.size();
                    if (size > 0) {
                        Enumeration schemas = fGrammarResolver.nameSpaceKeys();
                        Document schemaDocument = fGrammarResolver.getGrammar((String)schemas.nextElement()).getGrammarDocument();
                        if (schemaDocument != null) {
                            Element schema = schemaDocument.getDocumentElement();
                            copyInto(schema, fDocumentTypeIndex);
                        }
                    }
                }
            }
        }

        // full expansion
        else {

            boolean nsEnabled = false;
            try { nsEnabled = getNamespaces(); }
            catch (SAXException s) {}

            String elementName = fStringPool.toString(elementQName.rawname);
            Element e;
            if (nsEnabled) {
                e = fDocument.createElementNS(
                        // REVISIT: Make sure uri is filled in by caller.
                        fStringPool.toString(elementQName.uri),
                        fStringPool.toString(elementQName.localpart)
                    );
            } else {
                e = fDocument.createElement(elementName);
            }
            int attrHandle = xmlAttrList.getFirstAttr(attrListIndex);
            while (attrHandle != -1) {
                int attName = xmlAttrList.getAttrName(attrHandle);
                String attrName = fStringPool.toString(attName);
                String attrValue =
                    fStringPool.toString(xmlAttrList.getAttValue(attrHandle));
                if (nsEnabled) {
		    int nsURIIndex = xmlAttrList.getAttrURI(attrHandle);
		    String namespaceURI = fStringPool.toString(nsURIIndex);
		    // DOM Level 2 wants all namespace declaration attributes
		    // to be bound to "http://www.w3.org/2000/xmlns/"
		    // So as long as the XML parser doesn't do it, it needs to
		    // done here.
		    int prefixIndex = xmlAttrList.getAttrPrefix(attrHandle);
		    String prefix = fStringPool.toString(prefixIndex);
		    if (namespaceURI == null) {
			if (prefix != null) {
			    if (prefix.equals("xmlns")) {
				namespaceURI = "http://www.w3.org/2000/xmlns/";
			    }
			} else if (attrName.equals("xmlns")) {
			    namespaceURI = "http://www.w3.org/2000/xmlns/";
			}
		    }
                    e.setAttributeNS(namespaceURI, attrName, attrValue);
                } else {
                    e.setAttribute(attrName, attrValue);
                }
                if (!xmlAttrList.isSpecified(attrHandle)) {
                    ((AttrImpl)e.getAttributeNode(attrName))
                        .setSpecified(false);
                }
                attrHandle = xmlAttrList.getNextAttr(attrHandle);
            }
            fCurrentElementNode.appendChild(e);
            fCurrentElementNode = e;
            fWithinElement = true;

            // identifier registration
            if (fDocumentImpl != null) {
                int index = xmlAttrList.getFirstAttr(attrListIndex);
                while (index != -1) {
                    if (xmlAttrList.getAttType(index) == fStringPool.addSymbol("ID")) {
                        String name = fStringPool.toString(xmlAttrList.getAttValue(index));
                        fDocumentImpl.putIdentifier(name, e);
                    }
                    index = xmlAttrList.getNextAttr(index);
                }
            }

            xmlAttrList.releaseAttrList(attrListIndex);

            // copy schema grammar, if needed
            if (!fSeenRootElement) {
                fSeenRootElement = true;
                if (fDocumentImpl != null
                    && fGrammarAccess && fGrammarResolver.size() > 0) {
                    if (fDocumentType == null) {
                        String rootName = elementName;
                        String systemId = ""; // REVISIT: How do we get this value? -Ac
                        String publicId = ""; // REVISIT: How do we get this value? -Ac
                        fDocumentType = fDocumentImpl.createDocumentType(rootName, publicId, systemId);
                        fDocument.appendChild(fDocumentType);
                        // REVISIT: We could use introspection to get the
                        //          DOMImplementation#createDocumentType method
                        //          for DOM Level 2 implementations. The only
                        //          problem is that the owner document for the
                        //          node created is null. How does it get set
                        //          for document when appended? A cursory look
                        //          at the DOM Level 2 CR didn't yield any
                        //          information. -Ac
                    }
                    Enumeration schemas = fGrammarResolver.nameSpaceKeys();
                    Document schemaDocument = fGrammarResolver.getGrammar((String)schemas.nextElement()).getGrammarDocument();
                    if (schemaDocument != null) {
                        Element schema = schemaDocument.getDocumentElement();
                        XUtil.copyInto(schema, fDocumentType);
                    }
                }
            }
        }

    } // startElement(QName,XMLAttrList,int)

    /** End element. */
    public void endElement(QName elementQName)
        throws Exception {

        // deferred node expansion
        if (fDeferredDocumentImpl != null) {
            fCurrentNodeIndex = fDeferredDocumentImpl.getParentNode(fCurrentNodeIndex, false);
            fWithinElement = false;
        }

        // full node expansion
        else {
            fCurrentElementNode = fCurrentElementNode.getParentNode();
            fWithinElement = false;
            if (fDocumentImpl != null) {
                ((NodeImpl)fCurrentElementNode).reduceWaste();
            }
        }

    } // endElement(QName)

    /** Characters. */
    public void characters(int dataIndex)
        throws Exception {

        // deferred node expansion
        if (fDeferredDocumentImpl != null) {

            int text;

            if (fInCDATA) {
                text = fDeferredDocumentImpl.createCDATASection(dataIndex, false);
            } else {
                // The Text normalization is taken care of within the Text Node
                // in the DEFERRED case.
                text = fDeferredDocumentImpl.createTextNode(dataIndex, false);
            }
            fDeferredDocumentImpl.appendChild(fCurrentNodeIndex, text);
        }

        // full node expansion
        else {

            Text text;

            if (fInCDATA) {
                text = fDocument.createCDATASection(fStringPool.orphanString(dataIndex));
            }
            else {

                if (fWithinElement && fCurrentElementNode.getNodeType() == Node.ELEMENT_NODE) {
                    Node lastChild = fCurrentElementNode.getLastChild();
                    if (lastChild != null
                        && lastChild.getNodeType() == Node.TEXT_NODE) {
                        // Normalization of Text Nodes - append rather than create.
                        ((Text)lastChild).appendData(fStringPool.orphanString(dataIndex));
                        return;
                    }
                }
                text = fDocument.createTextNode(fStringPool.orphanString(dataIndex));
            }

            fCurrentElementNode.appendChild(text);

        }

    } // characters(int)

    /** Ignorable whitespace. */
    public void ignorableWhitespace(int dataIndex) throws Exception {

        // ignore the whitespace
        if (!fIncludeIgnorableWhitespace) {
            fStringPool.orphanString(dataIndex);
            return;
        }

        // deferred node expansion
        if (fDeferredDocumentImpl != null) {

            int text;

            if (fInCDATA) {
                text = fDeferredDocumentImpl.createCDATASection(dataIndex, true);
            } else {
                // The Text normalization is taken care of within the Text Node
                // in the DEFERRED case.
                text = fDeferredDocumentImpl.createTextNode(dataIndex, true);
            }
            fDeferredDocumentImpl.appendChild(fCurrentNodeIndex, text);
        }

        // full node expansion
        else {

            Text text;

            if (fInCDATA) {
                text = fDocument.createCDATASection(fStringPool.orphanString(dataIndex));
            }
            else {

                if (fWithinElement && fCurrentElementNode.getNodeType() == Node.ELEMENT_NODE) {
                    Node lastChild = fCurrentElementNode.getLastChild();
                    if (lastChild != null
                        && lastChild.getNodeType() == Node.TEXT_NODE) {
                        // Normalization of Text Nodes - append rather than create.
                        ((Text)lastChild).appendData(fStringPool.orphanString(dataIndex));
                        return;
                    }
                }
                text = fDocument.createTextNode(fStringPool.orphanString(dataIndex));
            }

            if (fDocumentImpl != null) {
                ((TextImpl)text).setIgnorableWhitespace(true);
            }

            fCurrentElementNode.appendChild(text);

        }

    } // ignorableWhitespace(int)

    /** Processing instruction. */
    public void processingInstruction(int targetIndex, int dataIndex)
        throws Exception {

        // deferred node expansion
        if (fDeferredDocumentImpl != null) {
            int pi = fDeferredDocumentImpl.createProcessingInstruction(targetIndex, dataIndex);
            fDeferredDocumentImpl.appendChild(fCurrentNodeIndex, pi);
        }

        // full node expansion
        else {
            String target = fStringPool.orphanString(targetIndex);
            String data = fStringPool.orphanString(dataIndex);
            ProcessingInstruction pi = fDocument.createProcessingInstruction(target, data);
            fCurrentElementNode.appendChild(pi);
        }

    } // processingInstruction(int,int)

    /** Comment. */
    public void comment(int dataIndex) throws Exception {

        if (fInDTD && !fGrammarAccess) {
            fStringPool.orphanString(dataIndex);
        }
        else {
            // deferred node expansion
            if (fDeferredDocumentImpl != null) {
                int comment = fDeferredDocumentImpl.createComment(dataIndex);
                fDeferredDocumentImpl.appendChild(fCurrentNodeIndex, comment);
            }

            // full node expansion
            else {
                Comment comment = fDocument.createComment(fStringPool.orphanString(dataIndex));
                fCurrentElementNode.appendChild(comment);
            }
        }

    } // comment(int)

    /** Not called. */
    public void characters(char ch[], int start, int length) throws Exception {}

    /** Not called. */
    public void ignorableWhitespace(char ch[], int start, int length) throws Exception {}

    //
    // XMLDocumentScanner methods
    //

    /** Start CDATA section. */
    public void startCDATA() throws Exception {
        fInCDATA = true;
    }

    /** End CDATA section. */
    public void endCDATA() throws Exception {
        fInCDATA = false;
    }

    //
    // XMLEntityHandler methods
    //

    /** Start entity reference. */
    public void startEntityReference(int entityName, int entityType,
                                     int entityContext) throws Exception {

        // are we ignoring entity reference nodes?
        if (!fCreateEntityReferenceNodes) {
            return;
        }

        // ignore built-in entities
        if (entityName == fAmpIndex ||
            entityName == fGtIndex ||
            entityName == fLtIndex ||
            entityName == fAposIndex ||
            entityName == fQuotIndex) {
            return;
        }

        // we only support one context for entity references right now...
        if (entityContext != XMLEntityHandler.ENTITYREF_IN_CONTENT) {
            return;
        }

        // deferred node expansion
        if (fDeferredDocumentImpl != null) {

            int entityRefIndex = fDeferredDocumentImpl.createEntityReference(entityName);
            fDeferredDocumentImpl.appendChild(fCurrentNodeIndex, entityRefIndex);

            fCurrentNodeIndex = entityRefIndex;
        }

        // full node expansion
        else {

            EntityReference er =
             fDocument.createEntityReference(fStringPool.toString(entityName));

            fCurrentElementNode.appendChild(er);
            fCurrentElementNode = er;
            try {
                EntityReferenceImpl xer = (EntityReferenceImpl) er;
                xer.setReadOnly(false, false);
            } catch (Exception e) {
                // we aren't building against Xerces - do nothing
            }
        }

    } // startEntityReference(int,int,int)

    /** End entity reference. */
    public void endEntityReference(int entityName, int entityType,
                                   int entityContext) throws Exception {

        // are we ignoring entity reference nodes?
        if (!fCreateEntityReferenceNodes) {
            return;
        }

        // ignore built-in entities
        if (entityName == fAmpIndex ||
            entityName == fGtIndex ||
            entityName == fLtIndex ||
            entityName == fAposIndex ||
            entityName == fQuotIndex) {
            return;
        }

        // we only support one context for entity references right now...
        if (entityContext != XMLEntityHandler.ENTITYREF_IN_CONTENT) {
            return;
        }

        // deferred node expansion
        if (fDeferredDocumentImpl != null) {

            String name = fStringPool.toString(entityName);

            int erChild = fCurrentNodeIndex;
            fCurrentNodeIndex = fDeferredDocumentImpl.getParentNode(erChild, false);

            // should never be true - we should not return here.
            if (fDeferredDocumentImpl.getNodeType(erChild, false) != Node.ENTITY_REFERENCE_NODE)  return;

            erChild = fDeferredDocumentImpl.getLastChild(erChild, false); // first Child of EntityReference

            if (fDocumentTypeIndex != -1) {
                // find Entity decl for this EntityReference.
                int entityDecl = fDeferredDocumentImpl.getLastChild(fDocumentTypeIndex, false);
                while (entityDecl != -1) {
                    if (fDeferredDocumentImpl.getNodeType(entityDecl, false) == Node.ENTITY_NODE
                    && fDeferredDocumentImpl.getNodeNameString(entityDecl, false).equals(name)) // string compare...
                    {
                        break;
                    }
                    entityDecl = fDeferredDocumentImpl.getPrevSibling(entityDecl, false);
                }

                if (entityDecl != -1
                    && fDeferredDocumentImpl.getLastChild(entityDecl, false) == -1) {
                    // found entityDecl with same name as this reference
                    // AND it doesn't have any children.

                    // we don't need to iterate, because the whole structure
                    // should already be connected to the 1st child.
                    fDeferredDocumentImpl.setAsLastChild(entityDecl, erChild);
                }
            }

        }

        // full node expansion
        else {

            Node erNode = fCurrentElementNode;//fCurrentElementNode.getParentNode();
            fCurrentElementNode = erNode.getParentNode();

            try {
                EntityReferenceImpl xer = (EntityReferenceImpl) erNode;
                xer.setReadOnly(false, false);

                // if necessary populate the related entity now
                if (fDocumentImpl != null) {

                    NamedNodeMap entities = fDocumentType.getEntities();
                    String name = fStringPool.toString(entityName);
                    Node entityNode = entities.getNamedItem(name);

                    // We could simply return here if there is no entity for
                    // the reference or if the entity is already populated.
                    if (entityNode == null || entityNode.hasChildNodes()) {
                        return;
                    }

                    EntityImpl entity = (EntityImpl) entityNode;
                    entity.setReadOnly(false, false);
                    for (Node child = erNode.getFirstChild();
                         child != null;
                         child = child.getNextSibling()) {
                        Node childClone = child.cloneNode(true);
                        entity.appendChild(childClone);
                    }
                    entity.setReadOnly(true, true);
                }
            } catch (Exception e) {
                // we aren't building against Xerces - do nothing
            }
        }

    } // endEntityReference(int,int,int)

    //
    // DTDValidator.EventHandler methods
    //

    /**
     *  This function will be called when a &lt;!DOCTYPE...&gt; declaration is
     *  encountered.
     */
    public void startDTD(QName rootElement, int publicId, int systemId)
        throws Exception {

        fInDTD = true;

        // full expansion
        if (fDocumentImpl != null) {
            String rootElementName = fStringPool.toString(rootElement.rawname);
            String publicString = fStringPool.toString(publicId);
            String systemString = fStringPool.toString(systemId);
            fDocumentType = fDocumentImpl.
                createDocumentType(rootElementName, publicString, systemString);
            fDocumentImpl.appendChild(fDocumentType);

            if (fGrammarAccess) {
                Element schema = fDocument.createElement("schema");
                // REVISIT: What should the namespace be? -Ac
                schema.setAttribute("xmlns", "http://www.w3.org/1999/XMLSchema");
                ((AttrImpl)schema.getAttributeNode("xmlns")).setSpecified(false);
                schema.setAttribute("finalDefault", "");
                ((AttrImpl)schema.getAttributeNode("finalDefault")).setSpecified(false);
                schema.setAttribute("exactDefault", "");
                ((AttrImpl)schema.getAttributeNode("exactDefault")).setSpecified(false);
                fDocumentType.appendChild(schema);
                fCurrentElementNode = schema;
            }
        }

        // deferred expansion
        else if (fDeferredDocumentImpl != null) {
            fDocumentTypeIndex =
                fDeferredDocumentImpl.
                    createDocumentType(rootElement.rawname, publicId, systemId);
            fDeferredDocumentImpl.appendChild(fDocumentIndex, fDocumentTypeIndex);

            if (fGrammarAccess) {
                int handle = fAttrList.startAttrList();
                fAttrList.addAttr(
                    fStringPool.addSymbol("xmlns"),
                    fStringPool.addString("http://www.w3.org/1999/XMLSchema"),
                    fStringPool.addSymbol("CDATA"),
                    false,
                    false); // search
                fAttrList.addAttr(
                    fStringPool.addSymbol("finalDefault"),
                    fStringPool.addString(""),
                    fStringPool.addSymbol("CDATA"),
                    false,
                    false); // search
                fAttrList.addAttr(
                    fStringPool.addSymbol("exactDefault"),
                    fStringPool.addString(""),
                    fStringPool.addSymbol("CDATA"),
                    false,
                    false); // search
                fAttrList.endAttrList();
                int schemaIndex = fDeferredDocumentImpl.createElement(fStringPool.addSymbol("schema"), fAttrList, handle);
                // REVISIT: What should the namespace be? -Ac
                fDeferredDocumentImpl.appendChild(fDocumentTypeIndex, schemaIndex);
                fCurrentNodeIndex = schemaIndex;
            }
        }

    } // startDTD(int,int,int)
    
    /**
     * Supports DOM Level 2 internalSubset additions.
     * Called when the internal subset is completely scanned.
     */
    public  void internalSubset(int internalSubset) {
        
        //System.out.println("internalSubset callback:"+fStringPool.toString(internalSubset));
        
        // full expansion
        if (fDocumentImpl != null && fDocumentType != null) {
            ((DocumentTypeImpl)fDocumentType).setInternalSubset(fStringPool.toString(internalSubset));
        }

        // deferred expansion
        else if (fDeferredDocumentImpl != null) {
            fDeferredDocumentImpl.setInternalSubset(fDocumentTypeIndex, internalSubset);
        }
        
    }
    

    /**
     *  This function will be called at the end of the DTD.
     */
    public void endDTD() throws Exception {

        fInDTD = false;

        if (fGrammarAccess) {
            if (fDocumentImpl != null) {
                fCurrentElementNode = fDocumentImpl;
            }
            else if (fDeferredDocumentImpl != null) {
                fCurrentNodeIndex = 0;
            }
        }

    } // endDTD()

    /**
     * &lt;!ELEMENT Name contentspec&gt;
     */
    public void elementDecl(QName elementDecl, 
                            int contentSpecType, 
                            int contentSpecIndex,
                            XMLContentSpec.Provider contentSpecProvider) throws Exception {

        if (DEBUG_ATTLIST_DECL) {
            String contentModel = XMLContentSpec.toString(contentSpecProvider, fStringPool, contentSpecIndex);
            System.out.println("elementDecl(" + fStringPool.toString(elementDecl.rawname) + ", " +
                                                contentModel + ")");
        }

        //
        // Create element declaration
        //
        if (fGrammarAccess) {

            if (fDeferredDocumentImpl != null) {

                //
                // Build element
                //

                // get element declaration; create if necessary
                int schemaIndex = getLastChildElement(fDocumentTypeIndex, "schema");
                String elementName = fStringPool.toString(elementDecl.rawname);
                int elementIndex = getLastChildElement(schemaIndex, "element", "name", elementName);
                if (elementIndex == -1) {
                    int handle = fAttrList.startAttrList();
                    fAttrList.addAttr(
                        fStringPool.addSymbol("name"),
                        fStringPool.addString(elementName),
                        fStringPool.addSymbol("NMTOKEN"),
                        true,
                        false); // search
                    fAttrList.addAttr(
                        fStringPool.addSymbol("minOccurs"), // name
                        fStringPool.addString("1"), // value
                        fStringPool.addSymbol("NMTOKEN"), // type
                        false, // specified
                        false); // search
                    fAttrList.addAttr(
                        fStringPool.addSymbol("nullable"), // name
                        fStringPool.addString("false"), // value
                        fStringPool.addSymbol("ENUMERATION"), // type
                        false, // specified
                        false); // search
                    fAttrList.addAttr(
                        fStringPool.addSymbol("abstract"), // name
                        fStringPool.addString("false"), // value
                        fStringPool.addSymbol("ENUMERATION"), // type
                        false, // specified
                        false); // search
                    fAttrList.addAttr(
                        fStringPool.addSymbol("final"), // name
                        fStringPool.addString("false"), // value
                        fStringPool.addSymbol("ENUMERATION"), // type
                        false, // specified
                        false); // search
                    fAttrList.endAttrList();
                    elementIndex = fDeferredDocumentImpl.createElement(fStringPool.addSymbol("element"), fAttrList, handle);
                    fDeferredDocumentImpl.appendChild(schemaIndex, elementIndex);
                }

                //
                // Build content model
                //

                // get type element; create if necessary
                int typeIndex = getLastChildElement(elementIndex, "complexType");
                if (typeIndex == -1 && contentSpecType != XMLElementDecl.TYPE_MIXED) {
                    typeIndex = fDeferredDocumentImpl.createElement(fStringPool.addSymbol("complexType"), null, -1);
                    // REVISIT: Check for type redeclaration? -Ac
                    fDeferredDocumentImpl.insertBefore(elementIndex, typeIndex, getFirstChildElement(elementIndex));
                }

                // create models
                switch (contentSpecType) {
                    case XMLElementDecl.TYPE_EMPTY: {
                        int attributeIndex = fDeferredDocumentImpl.createAttribute(fStringPool.addSymbol("content"), fStringPool.addString("empty"), true);
                        fDeferredDocumentImpl.setAttributeNode(typeIndex, attributeIndex);
                        break;
                    }
                    case XMLElementDecl.TYPE_ANY: {
                        int anyIndex = fDeferredDocumentImpl.createElement(fStringPool.addSymbol("any"), null, -1);
                        fDeferredDocumentImpl.insertBefore(typeIndex, anyIndex, getFirstChildElement(typeIndex));
                        break;
                    }
                    case XMLElementDecl.TYPE_MIXED: {
                        XMLContentSpec contentSpec = new XMLContentSpec();
                        contentSpecProvider.getContentSpec(contentSpecIndex, contentSpec);
                        contentSpecIndex = contentSpec.value;
                        if (contentSpecIndex == -1) {
                            int attributeIndex = fDeferredDocumentImpl.createAttribute(fStringPool.addSymbol("type"), fStringPool.addString("string"), true);
                            fDeferredDocumentImpl.setAttributeNode(elementIndex, attributeIndex);
                        }
                        else {
                            if (typeIndex == -1) {
                                typeIndex = fDeferredDocumentImpl.createElement(fStringPool.addSymbol("complexType"), null, -1);
                                // REVISIT: Check for type redeclaration? -Ac
                                fDeferredDocumentImpl.insertBefore(elementIndex, typeIndex, getFirstChildElement(elementIndex));
                            }
                            int attributeIndex = fDeferredDocumentImpl.createAttribute(fStringPool.addSymbol("content"), fStringPool.addString("mixed"), true);
                            fDeferredDocumentImpl.setAttributeNode(typeIndex, attributeIndex);
                            int handle = fAttrList.startAttrList();
                            fAttrList.addAttr(
                                fStringPool.addSymbol("minOccurs"),
                                fStringPool.addString("0"),
                                fStringPool.addSymbol("NMTOKEN"),
                                true,
                                false); // search
                            fAttrList.addAttr(
                                fStringPool.addSymbol("maxOccurs"),
                                fStringPool.addString("unbounded"),
                                fStringPool.addSymbol("CDATA"),
                                true,
                                false); // search
                            fAttrList.endAttrList();
                            int choiceIndex = fDeferredDocumentImpl.createElement(fStringPool.addSymbol("choice"), fAttrList, handle);
                            fDeferredDocumentImpl.appendChild(typeIndex, choiceIndex);
                            while (contentSpecIndex != -1) {

                                // get node
                                contentSpecProvider.getContentSpec(contentSpecIndex, contentSpec);
                                int type  = contentSpec.type;
                                int left  = contentSpec.value;
                                int right = contentSpec.otherValue;

                                // if leaf, skip "#PCDATA" and stop
                                if (type == XMLContentSpec.CONTENTSPECNODE_LEAF) {
                                    break;
                                }

                                // add right hand leaf
                                contentSpecProvider.getContentSpec(right, contentSpec);
                                handle = fAttrList.startAttrList();
                                fAttrList.addAttr(
                                    fStringPool.addSymbol("ref"),
                                    fStringPool.addString(fStringPool.toString(contentSpec.value)),
                                    fStringPool.addSymbol("NMTOKEN"),
                                    true,
                                    false); //search
                                fAttrList.endAttrList();
                                int rightIndex = fDeferredDocumentImpl.createElement(fStringPool.addSymbol("element"), fAttrList, handle);
                                int refIndex = getFirstChildElement(choiceIndex);
                                fDeferredDocumentImpl.insertBefore(choiceIndex, rightIndex, refIndex);

                                // go to next node
                                contentSpecIndex = left;
                            }
                        }
                        break;
                    }
                    case XMLElementDecl.TYPE_CHILDREN: {
                        int attributeIndex = fDeferredDocumentImpl.createAttribute(fStringPool.addSymbol("content"), fStringPool.addString("elementOnly"), true);
                        fDeferredDocumentImpl.setAttributeNode(typeIndex, attributeIndex);
                        int children = createChildren(contentSpecProvider,
                                                      contentSpecIndex,
                                                      new XMLContentSpec(),
                                                      fDeferredDocumentImpl,
                                                      -1);
                        fDeferredDocumentImpl.insertBefore(typeIndex, children, getFirstChildElement(typeIndex));
                        break;
                    }
                }

            } // if defer-node-expansion

            else if (fDocumentImpl != null) {

                //
                // Build element
                //

                // get element declaration; create if necessary
                Element schema = XUtil.getLastChildElement(fDocumentType, "schema");
                String elementName = fStringPool.toString(elementDecl.rawname);
                Element element = XUtil.getLastChildElement(schema, "element", "name", elementName);
                if (element == null) {
                    element = fDocumentImpl.createElement("element");
                    element.setAttribute("name", elementName);
                    element.setAttribute("minOccurs", "1");
                    ((AttrImpl)element.getAttributeNode("minOccurs")).setSpecified(false);
                    element.setAttribute("nullable", "false");
                    ((AttrImpl)element.getAttributeNode("nullable")).setSpecified(false);
                    element.setAttribute("abstract", "false");
                    ((AttrImpl)element.getAttributeNode("abstract")).setSpecified(false);
                    element.setAttribute("final", "false");
                    ((AttrImpl)element.getAttributeNode("final")).setSpecified(false);
                    schema.appendChild(element);
                }

                //
                // Build content model
                //

                // get type element; create if necessary
                Element type = XUtil.getLastChildElement(element, "complexType");
                if (type == null && contentSpecType != XMLElementDecl.TYPE_MIXED) {
                    type = fDocumentImpl.createElement("complexType");
                    // REVISIT: Check for type redeclaration? -Ac
                    element.insertBefore(type, XUtil.getFirstChildElement(element));
                }

                // create models
                switch (contentSpecType) {
                    case XMLElementDecl.TYPE_EMPTY: {
                        type.setAttribute("content", "empty");
                        break;
                    }
                    case XMLElementDecl.TYPE_ANY: {
                        Element any = fDocumentImpl.createElement("any");
                        type.insertBefore(any, XUtil.getFirstChildElement(type));
                        break;
                    }
                    case XMLElementDecl.TYPE_MIXED: {
                        XMLContentSpec contentSpec = new XMLContentSpec();
                        contentSpecProvider.getContentSpec(contentSpecIndex, contentSpec);
                        contentSpecIndex = contentSpec.value;
                        if (contentSpecIndex == -1) {
                            element.setAttribute("type", "string");
                        }
                        else {
                            if (type == null) {
                                type = fDocumentImpl.createElement("complexType");
                                // REVISIT: Check for type redeclaration? -Ac
                                element.insertBefore(type, XUtil.getFirstChildElement(element));
                            }
                            type.setAttribute("content", "mixed");
                            Element choice = fDocumentImpl.createElement("choice");
                            choice.setAttribute("minOccurs", "0");
                            choice.setAttribute("maxOccurs", "unbounded");
                            type.appendChild(choice);
                            while (contentSpecIndex != -1) {

                                // get node
                                contentSpecProvider.getContentSpec(contentSpecIndex, contentSpec);
                                int cstype  = contentSpec.type;
                                int csleft  = contentSpec.value;
                                int csright = contentSpec.otherValue;

                                // if leaf, skip "#PCDATA" and stop
                                if (cstype == XMLContentSpec.CONTENTSPECNODE_LEAF) {
                                    break;
                                }

                                // add right hand leaf
                                contentSpecProvider.getContentSpec(csright, contentSpec);
                                Element right = fDocumentImpl.createElement("element");
                                right.setAttribute("ref", fStringPool.toString(contentSpec.value));
                                Element ref = XUtil.getFirstChildElement(choice);
                                choice.insertBefore(right, ref);

                                // go to next node
                                contentSpecIndex = csleft;
                            }
                        }
                        break;
                    }
                    case XMLElementDecl.TYPE_CHILDREN: {
                        type.setAttribute("content", "elementOnly");
                        Element children = createChildren(contentSpecProvider,
                                                          contentSpecIndex,
                                                          new XMLContentSpec(),
                                                          fDocumentImpl,
                                                          null);
                        type.insertBefore(children, XUtil.getFirstChildElement(type));
                        break;
                    }
                }

            } // if NOT defer-node-expansion

        } // if grammar-access

    } // elementDecl(int,String)

    /**
     * &lt;!ATTLIST Name AttDef&gt;
     */
    public void attlistDecl(QName elementDecl, QName attributeDecl, 
                            int attType, boolean attList, String enumString,
                            int attDefaultType, int attDefaultValue)
        throws Exception {

        if (DEBUG_ATTLIST_DECL) {
            System.out.println("attlistDecl(" + fStringPool.toString(elementDecl.rawname) + ", " +
                                                fStringPool.toString(attributeDecl.rawname) + ", " +
                                                fStringPool.toString(attType) + ", " +
                                                enumString + ", " +
                                                fStringPool.toString(attDefaultType) + ", " +
                                                fStringPool.toString(attDefaultValue) + ")");
        }

        // deferred expansion
        if (fDeferredDocumentImpl != null) {

            // get the default value
            if (attDefaultValue != -1) {
                if (DEBUG_ATTLIST_DECL) {
                    System.out.println("  adding default attribute value: "+
                                       fStringPool.toString(attDefaultValue));
                }

                // get element definition
                int elementDefIndex  = fDeferredDocumentImpl.lookupElementDefinition(elementDecl.rawname);

                // create element definition if not already there
                if (elementDefIndex == -1) {
                    elementDefIndex = fDeferredDocumentImpl.createElementDefinition(elementDecl.rawname);
                    fDeferredDocumentImpl.appendChild(fDocumentTypeIndex, elementDefIndex);
                }

                // add default attribute
                int attrIndex =
                   fDeferredDocumentImpl.createAttribute(attributeDecl.rawname,
                                                         attributeDecl.uri,
                                                         attDefaultValue,
                                                         false);
                fDeferredDocumentImpl.appendChild(elementDefIndex, attrIndex);

            }

            //
            // Create attribute declaration
            //
            if (fGrammarAccess) {

                // get element declaration; create it if necessary
                int schemaIndex = getLastChildElement(fDocumentTypeIndex, "schema");
                String elementName = fStringPool.toString(elementDecl.rawname);
                int elementIndex = getLastChildElement(schemaIndex, "element", "name", elementName);
                if (elementIndex == -1) {
                    int handle = fAttrList.startAttrList();
                    fAttrList.addAttr(
                        fStringPool.addSymbol("name"),
                        fStringPool.addString(elementName),
                        fStringPool.addSymbol("NMTOKEN"),
                        true,
                        false); //search
                    fAttrList.endAttrList();
                    elementIndex = fDeferredDocumentImpl.createElement(fStringPool.addSymbol("element"), fAttrList, handle);
                    fDeferredDocumentImpl.appendChild(schemaIndex, elementIndex);
                }

                // get type element; create it if necessary
                int typeIndex = getLastChildElement(elementIndex, "complexType");
                if (typeIndex == -1) {
                    typeIndex = fDeferredDocumentImpl.createElement(fStringPool.addSymbol("complexType"), null, -1);
                    fDeferredDocumentImpl.insertBefore(elementIndex, typeIndex, getLastChildElement(elementIndex));
                }

                // create attribute and set its attributes
                String attributeName = fStringPool.toString(attributeDecl.rawname);
                int attributeIndex = getLastChildElement(elementIndex, "attribute", "name", attributeName);
                if (attributeIndex == -1) {
                    int handle = fAttrList.startAttrList();
                    fAttrList.addAttr(
                        fStringPool.addSymbol("name"),
                        fStringPool.addString(attributeName),
                        fStringPool.addSymbol("NMTOKEN"),
                        true,
                        false); // search
                    fAttrList.addAttr(
                        fStringPool.addSymbol("maxOccurs"),
                        fStringPool.addString("1"),
                        fStringPool.addSymbol("CDATA"),
                        false,
                        false); // search
                    fAttrList.endAttrList();
                    attributeIndex = fDeferredDocumentImpl.createElement(fStringPool.addSymbol("attribute"), fAttrList, handle);
                    fDeferredDocumentImpl.appendChild(typeIndex, attributeIndex);

                    // attribute type: CDATA, ENTITY, ... , NMTOKENS; ENUMERATION
                    if (attType == XMLAttributeDecl.TYPE_ENUMERATION) {
                        handle = fAttrList.startAttrList();
                        fAttrList.addAttr(
                            fStringPool.addSymbol("base"),
                            fStringPool.addString("NMTOKEN"),
                            fStringPool.addSymbol("NMTOKEN"),
                            true,
                            false); // search
                        fAttrList.endAttrList();
                        int simpleTypeIndex = fDeferredDocumentImpl.createElement(fStringPool.addSymbol("simpleType"), fAttrList, handle);
                        fDeferredDocumentImpl.appendChild(attributeIndex, simpleTypeIndex);
                        String tokenizerString = enumString.substring(1, enumString.length() - 1);
                        StringTokenizer tokenizer = new StringTokenizer(tokenizerString, "|");
                        while (tokenizer.hasMoreTokens()) {
                            handle = fAttrList.startAttrList();
                            fAttrList.addAttr(
                                fStringPool.addSymbol("value"),
                                fStringPool.addString(tokenizer.nextToken()),
                                fStringPool.addSymbol("CDATA"),
                                true,
                                false); // search
                            fAttrList.endAttrList();
                            int enumerationIndex = fDeferredDocumentImpl.createElement(fStringPool.addSymbol("enumeration"), fAttrList, handle);
                            fDeferredDocumentImpl.appendChild(simpleTypeIndex, enumerationIndex);
                        }
                    }
                    else {
                        int typeNameIndex = -1;
                        switch (attType) {
                            case XMLAttributeDecl.TYPE_ENTITY: {
                                typeNameIndex = fStringPool.addString(attList?"ENTITIES":"ENTITY");
                                break;
                            }
                            case XMLAttributeDecl.TYPE_ID: {
                                typeNameIndex = fStringPool.addString("ID");
                                break;
                            }
                            case XMLAttributeDecl.TYPE_IDREF: {
                                typeNameIndex = fStringPool.addString(attList?"IDREFS":"IDREF");
                                break;
                            }
                            case XMLAttributeDecl.TYPE_NMTOKEN: {
                                typeNameIndex = fStringPool.addString(attList?"NMTOKENS":"NMTOKEN");
                                break;
                            }
                            case XMLAttributeDecl.TYPE_NOTATION: {
                                typeNameIndex = fStringPool.addString("NOTATION");
                                break;
                            }
                            case XMLAttributeDecl.TYPE_CDATA: 
                            default: {
                                typeNameIndex = fStringPool.addString("string");
                                break;
                            }
                        }
                        int attrIndex = fDeferredDocumentImpl.createAttribute(fStringPool.addSymbol("type"), typeNameIndex, true);
                        fDeferredDocumentImpl.setAttributeNode(attributeIndex, attrIndex);
                    }

                    // attribute default type: #IMPLIED, #REQUIRED, #FIXED
                    boolean fixed = false;
                    switch (attDefaultType) {
                        case XMLAttributeDecl.DEFAULT_TYPE_REQUIRED: {
                            int useAttrIndex = fDeferredDocumentImpl.createAttribute(fStringPool.addSymbol("use"), fStringPool.addString("required"), true);
                            fDeferredDocumentImpl.setAttributeNode(attributeIndex, useAttrIndex);
                            break;
                        }
                        case XMLAttributeDecl.DEFAULT_TYPE_FIXED: {
                            fixed = true;
                            int useAttrIndex = fDeferredDocumentImpl.createAttribute(fStringPool.addSymbol("use"), fStringPool.addString("fixed"), true);
                            fDeferredDocumentImpl.setAttributeNode(attributeIndex, useAttrIndex);
                            break;
                        }
                    }

                    // attribute default value
                    if (attDefaultValue != -1) {
                        if (!fixed) {
                            int useAttrIndex = fDeferredDocumentImpl.createAttribute(fStringPool.addSymbol("use"), fStringPool.addString("default"), true);
                            fDeferredDocumentImpl.setAttributeNode(attributeIndex, useAttrIndex);
                        }
                        int valueAttrIndex = fDeferredDocumentImpl.createAttribute(fStringPool.addSymbol("value"), attDefaultValue, true);
                        fDeferredDocumentImpl.setAttributeNode(attributeIndex, valueAttrIndex);
                    }
                }
            }
        }

        // full expansion
        else if (fDocumentImpl != null) {

            // get the default value
            if (attDefaultValue != -1) {
                if (DEBUG_ATTLIST_DECL) {
                    System.out.println("  adding default attribute value: "+
                                       fStringPool.toString(attDefaultValue));
                }

                // get element name
                String elementName = fStringPool.toString(elementDecl.rawname);

                // get element definition node
                NamedNodeMap elements = ((DocumentTypeImpl)fDocumentType).getElements();
                ElementDefinitionImpl elementDef = (ElementDefinitionImpl)elements.getNamedItem(elementName);
                if (elementDef == null) {
                    elementDef = fDocumentImpl.createElementDefinition(elementName);
                    ((DocumentTypeImpl)fDocumentType).getElements().setNamedItem(elementDef);
                }

                // REVISIT: Check for uniqueness of element name? -Ac
                // REVISIT: what about default attributes with URI? -ALH

                // get attribute name and value index
                String attrName      = fStringPool.toString(attributeDecl.rawname);
                String attrValue     = fStringPool.toString(attDefaultValue);

                // create attribute and set properties
                AttrImpl attr = (AttrImpl)fDocumentImpl.createAttribute(attrName);
                attr.setValue(attrValue);
                attr.setSpecified(false);

                // add default attribute to element definition
                elementDef.getAttributes().setNamedItem(attr);
            }

            //
            // Create attribute declaration
            //
            try {
            if (fGrammarAccess) {

                // get element declaration; create it if necessary
                Element schema = XUtil.getLastChildElement(fDocumentType, "schema");
                String elementName = fStringPool.toString(elementDecl.rawname);
                Element element = XUtil.getLastChildElement(schema, "element", "name", elementName);
                if (element == null) {
                    element = fDocumentImpl.createElement("element");
                    element.setAttribute("name", elementName);
                    schema.appendChild(element);
                }

                // get type element; create it if necessary
                Element type = XUtil.getLastChildElement(element, "complexType");
                if (type == null) {
                    type = fDocumentImpl.createElement("complexType");
                    element.insertBefore(type, XUtil.getLastChildElement(element));
                }

                // create attribute and set its attributes
                String attributeName = fStringPool.toString(attributeDecl.rawname);
                Element attribute = XUtil.getLastChildElement(element, "attribute", "name", attributeName);
                if (attribute == null) {
                    attribute = fDocumentImpl.createElement("attribute");
                    attribute.setAttribute("name", attributeName);
                    attribute.setAttribute("maxOccurs", "1");
                    ((AttrImpl)attribute.getAttributeNode("maxOccurs")).setSpecified(false);
                    type.appendChild(attribute);

                    // attribute type: CDATA, ENTITY, ... , NMTOKENS; ENUMERATION
                    if (attType == XMLAttributeDecl.TYPE_ENUMERATION) {
                        Element simpleType = fDocumentImpl.createElement("simpleType");
                        simpleType.setAttribute("base", "NMTOKEN");
                        attribute.appendChild(simpleType);
                        String tokenizerString = enumString.substring(1, enumString.length() - 1);
                        StringTokenizer tokenizer = new StringTokenizer(tokenizerString, "|");
                        while (tokenizer.hasMoreTokens()) {
                            Element enumeration = fDocumentImpl.createElement("enumeration");
                            enumeration.setAttribute("value", tokenizer.nextToken());
                            simpleType.appendChild(enumeration);
                        }
                    }
                    else {
                        String typeName = null;
                        switch (attType) {
                            case XMLAttributeDecl.TYPE_ENTITY: {
                                typeName = attList ? "ENTITIES" : "ENTITY";
                                break;
                            }
                            case XMLAttributeDecl.TYPE_ID: {
                                typeName = "ID";
                                break;
                            }
                            case XMLAttributeDecl.TYPE_IDREF: {
                                typeName = attList ? "IDREFS" : "IDREF";
                                break;
                            }
                            case XMLAttributeDecl.TYPE_NMTOKEN: {
                                typeName = attList ? "NMTOKENS" : "NMTOKEN";
                                break;
                            }
                            case XMLAttributeDecl.TYPE_NOTATION: {
                                typeName = "NOTATION";
                                break;
                            }
                            case XMLAttributeDecl.TYPE_CDATA: 
                            default: {
                                typeName = "string";
                                break;
                            }
                        }
                        attribute.setAttribute("type", typeName);
                    }

                    // attribute default type: #IMPLIED, #REQUIRED, #FIXED
                    boolean fixed = false;
                    switch (attDefaultType) {
                        case XMLAttributeDecl.DEFAULT_TYPE_REQUIRED: {
                            attribute.setAttribute("use", "required");
                            break;
                        }
                        case XMLAttributeDecl.DEFAULT_TYPE_FIXED: {
                            attribute.setAttribute("use", "fixed");
                            fixed = true;
                            break;
                        }
                    }

                    // attribute default value
                    if (attDefaultValue != -1) {
                        if (!fixed) {
                            attribute.setAttribute("use", "default");
                        }
                        attribute.setAttribute("value", fStringPool.toString(attDefaultValue));
                    }
                }
            }
            }
            catch (Exception e) {
                e.printStackTrace(System.err);
            }

        } // if NOT defer-node-expansion

    } // attlistDecl(int,int,int,String,int,int)

    /**
     * &lt;!ENTITY % Name EntityValue&gt; (internal)
     */
    public void internalPEDecl(int entityNameIndex, int entityValueIndex) throws Exception {
        if (fDeferredDocumentImpl != null) {
            if (fGrammarAccess) {
                StringBuffer str = new StringBuffer();
                str.append("<!ENTITY % ");
                str.append(fStringPool.toString(entityNameIndex));
                str.append(" \"");
                str.append(fStringPool.toString(entityValueIndex));
                str.append("\">");
                int commentIndex = fStringPool.addString(str.toString());
                int internalPEEntityIndex = fDeferredDocumentImpl.createComment(commentIndex);
                int schemaIndex = getFirstChildElement(fDocumentTypeIndex, "schema");
                fDeferredDocumentImpl.appendChild(schemaIndex, internalPEEntityIndex);
            }
        }
        else if (fDocumentImpl != null) {
            if (fGrammarAccess) {
                StringBuffer str = new StringBuffer();
                str.append("<!ENTITY % ");
                str.append(fStringPool.toString(entityNameIndex));
                str.append(" \"");
                str.append(fStringPool.orphanString(entityValueIndex));
                str.append("\">");
                Node internalPEEntity = fDocumentImpl.createComment(str.toString());
                Node schema = XUtil.getFirstChildElement(fDocumentType, "schema");
                schema.appendChild(internalPEEntity);
            }
        }
        else {
            fStringPool.orphanString(entityValueIndex);
        }
    }

    /**
     * &lt;!ENTITY % Name ExternalID>                (external)
     */
    public void externalPEDecl(int entityNameIndex, int publicIdIndex, int systemIdIndex) throws Exception {
        if (fDeferredDocumentImpl != null) {
            if (fGrammarAccess) {
                StringBuffer str = new StringBuffer();
                str.append("<!ENTITY ");
                str.append(fStringPool.toString(entityNameIndex));
                str.append(' ');
                if (publicIdIndex != -1) {
                    str.append("PUBLIC \"");
                    str.append(fStringPool.toString(publicIdIndex));
                    str.append('"');
                    if (systemIdIndex != -1) {
                        str.append(" \"");
                        str.append(fStringPool.toString(systemIdIndex));
                        str.append('"');
                    }
                }
                else if (systemIdIndex != -1) {
                    str.append("SYSTEM \"");
                    str.append(fStringPool.toString(systemIdIndex));
                    str.append('"');
                }
                str.append('>');
                int commentIndex = fStringPool.addString(str.toString());
                int externalPEEntityIndex = fDeferredDocumentImpl.createComment(commentIndex);
                int schemaIndex = getFirstChildElement(fDocumentTypeIndex, "schema");
                fDeferredDocumentImpl.appendChild(schemaIndex, externalPEEntityIndex);
            }
        }
        else if (fDocumentImpl != null) {
            if (fGrammarAccess) {
                StringBuffer str = new StringBuffer();
                str.append("<!ENTITY ");
                str.append(fStringPool.toString(entityNameIndex));
                str.append(' ');
                if (publicIdIndex != -1) {
                    str.append("PUBLIC \"");
                    str.append(fStringPool.toString(publicIdIndex));
                    str.append('"');
                    if (systemIdIndex != -1) {
                        str.append(" \"");
                        str.append(fStringPool.toString(systemIdIndex));
                        str.append('"');
                    }
                }
                else if (systemIdIndex != -1) {
                    str.append("SYSTEM \"");
                    str.append(fStringPool.toString(systemIdIndex));
                    str.append('"');
                }
                str.append('>');
                Node externalPEEntity = fDocumentImpl.createComment(str.toString());
                Node schema = XUtil.getFirstChildElement(fDocumentType, "schema");
                schema.appendChild(externalPEEntity);
            }
        }
    }

    /**
     * &lt;!ENTITY Name EntityValue&gt; (internal)
     */
    public void internalEntityDecl(int entityNameIndex, int entityValueIndex)
        throws Exception {

        // deferred expansion
        if (fDeferredDocumentImpl != null) {

            if (fDocumentTypeIndex == -1) return; //revisit: should never happen. Exception?

            //revisit: how to check if entity was already declared.
            // XML spec says that 1st Entity decl is binding.

            int newEntityIndex = fDeferredDocumentImpl.createEntity(entityNameIndex, -1, -1, -1);
            fDeferredDocumentImpl.appendChild(fDocumentTypeIndex, newEntityIndex);

            // REVISIT: Entities were removed from latest working draft. -Ac
            // create internal entity declaration
            if (fGrammarAccess) {
                StringBuffer str = new StringBuffer();
                str.append("<!ENTITY ");
                str.append(fStringPool.toString(entityNameIndex));
                str.append(" \"");
                str.append(fStringPool.toString(entityValueIndex));
                str.append("\">");
                int commentIndex = fStringPool.addString(str.toString());
                int textEntityIndex = fDeferredDocumentImpl.createComment(commentIndex);
                int schemaIndex = getFirstChildElement(fDocumentTypeIndex, "schema");
                fDeferredDocumentImpl.appendChild(schemaIndex, textEntityIndex);
            }
        }

        // full expansion
        else if (fDocumentImpl != null) {
            if (fDocumentType == null) return; //revisit: should never happen. Exception?

            //revisit: how to check if entity was already declared.
            // XML spec says that 1st Entity decl is binding.

            String entityName = fStringPool.toString(entityNameIndex);

            Entity entity = fDocumentImpl.createEntity(entityName);
            fDocumentType.getEntities().setNamedItem(entity);

            // REVISIT: Entities were removed from latest working draft. -Ac
            // create internal entity declaration
            if (fGrammarAccess) {
                StringBuffer str = new StringBuffer();
                str.append("<!ENTITY ");
                str.append(fStringPool.toString(entityNameIndex));
                str.append(" \"");
                str.append(fStringPool.toString(entityValueIndex));
                str.append("\">");
                Node textEntity = fDocumentImpl.createComment(str.toString());
                Node schema = XUtil.getFirstChildElement(fDocumentType, "schema");
                schema.appendChild(textEntity);
            }
        }

    } // internalEntityDecl(int,int)

    /**
     * &lt;!ENTITY Name ExternalID>                (external)
     */
    public void externalEntityDecl(int entityNameIndex, int publicIdIndex, int systemIdIndex)
        throws Exception {

        // deferred expansion
        if (fDeferredDocumentImpl != null) {

            //revisit: how to check if entity was already declared.
            // XML spec says that 1st Entity decl is binding.

            int newEntityIndex = fDeferredDocumentImpl.createEntity(entityNameIndex, publicIdIndex, systemIdIndex, -1);

            fDeferredDocumentImpl.appendChild(fDocumentTypeIndex, newEntityIndex);

            // REVISIT: Entities were removed from latest working draft. -Ac
            // create external entity declaration
            if (fGrammarAccess) {
                StringBuffer str = new StringBuffer();
                str.append("<!ENTITY ");
                str.append(fStringPool.toString(entityNameIndex));
                str.append(' ');
                if (publicIdIndex != -1) {
                    str.append("PUBLIC \"");
                    str.append(fStringPool.toString(publicIdIndex));
                    str.append('"');
                    if (systemIdIndex != -1) {
                        str.append(" \"");
                        str.append(fStringPool.toString(systemIdIndex));
                        str.append('"');
                    }
                }
                else if (systemIdIndex != -1) {
                    str.append("SYSTEM \"");
                    str.append(fStringPool.toString(systemIdIndex));
                    str.append('"');
                }
                str.append('>');
                int commentIndex = fStringPool.addString(str.toString());
                int externalEntityIndex = fDeferredDocumentImpl.createComment(commentIndex);
                int schemaIndex = getFirstChildElement(fDocumentTypeIndex, "schema");
                fDeferredDocumentImpl.appendChild(schemaIndex, externalEntityIndex);
            }
        }

        // full expansion
        else if (fDocumentImpl != null) {

            //revisit: how to check if entity was already declared.
            // XML spec says that 1st Entity decl is binding.

            String entityName = fStringPool.toString(entityNameIndex);
            String publicId = fStringPool.toString(publicIdIndex);
            String systemId = fStringPool.toString(systemIdIndex);

            EntityImpl entity = (EntityImpl)fDocumentImpl.createEntity(entityName);
            if (publicIdIndex != -1) {
                entity.setPublicId(publicId);
            }
            entity.setSystemId(systemId);
            fDocumentType.getEntities().setNamedItem(entity);

            // REVISIT: Entities were removed from latest working draft. -Ac
            // create external entity declaration
            if (fGrammarAccess) {
                StringBuffer str = new StringBuffer();
                str.append("<!ENTITY ");
                str.append(fStringPool.toString(entityNameIndex));
                str.append(' ');
                if (publicIdIndex != -1) {
                    str.append("PUBLIC \"");
                    str.append(fStringPool.toString(publicIdIndex));
                    str.append('"');
                    if (systemIdIndex != -1) {
                        str.append(" \"");
                        str.append(fStringPool.toString(systemIdIndex));
                        str.append('"');
                    }
                }
                else if (systemIdIndex != -1) {
                    str.append("SYSTEM \"");
                    str.append(fStringPool.toString(systemIdIndex));
                    str.append('"');
                }
                str.append('>');
                Node externalEntity = fDocumentImpl.createComment(str.toString());
                Node schema = XUtil.getFirstChildElement(fDocumentType, "schema");
                schema.appendChild(externalEntity);
            }
        }

    } // externalEntityDecl(int,int,int)

    /**
     * &lt;!ENTITY Name ExternalID NDataDecl>      (unparsed)
     */
    public void unparsedEntityDecl(int entityNameIndex,
                                   int publicIdIndex, int systemIdIndex,
                                   int notationNameIndex) throws Exception {

        // deferred expansion
        if (fDeferredDocumentImpl != null) {

            //revisit: how to check if entity was already declared.
            // XML spec says that 1st Entity decl is binding.

            int newEntityIndex = fDeferredDocumentImpl.createEntity(entityNameIndex, publicIdIndex, systemIdIndex, notationNameIndex);

            fDeferredDocumentImpl.appendChild(fDocumentTypeIndex, newEntityIndex);

            // REVISIT: Entities were removed from latest working draft. -Ac
            // add unparsed entity declaration
            if (fGrammarAccess) {
                StringBuffer str = new StringBuffer();
                str.append("<!ENTITY ");
                str.append(fStringPool.toString(entityNameIndex));
                str.append(' ');
                if (publicIdIndex != -1) {
                    str.append("PUBLIC \"");
                    str.append(fStringPool.toString(publicIdIndex));
                    str.append('"');
                    if (systemIdIndex != -1) {
                        str.append(" \"");
                        str.append(fStringPool.toString(systemIdIndex));
                        str.append('"');
                    }
                }
                else if (systemIdIndex != -1) {
                    str.append("SYSTEM \"");
                    str.append(fStringPool.toString(systemIdIndex));
                    str.append('"');
                }
                str.append(" NDATA ");
                str.append(fStringPool.toString(notationNameIndex));
                str.append('>');
                int commentIndex = fStringPool.addString(str.toString());
                int unparsedEntityIndex = fDeferredDocumentImpl.createComment(commentIndex);
                int schemaIndex = getFirstChildElement(fDocumentTypeIndex, "schema");
                fDeferredDocumentImpl.appendChild(schemaIndex, unparsedEntityIndex);
            }
        }

        // full expansion
        else if (fDocumentImpl != null) {

            //revisit: how to check if entity was already declared.
            // XML spec says that 1st Entity decl is binding.

            String entityName = fStringPool.toString(entityNameIndex);
            String publicId = fStringPool.toString(publicIdIndex);
            String systemId = fStringPool.toString(systemIdIndex);
            String notationName = fStringPool.toString(notationNameIndex);

            EntityImpl entity = (EntityImpl)fDocumentImpl.createEntity(entityName);
            if (publicIdIndex != -1) {
                entity.setPublicId(publicId);
            }
            entity.setSystemId(systemId);
            entity.setNotationName(notationName);
            fDocumentType.getEntities().setNamedItem(entity);

            // REVISIT: Entities were removed from latest working draft. -Ac
            // add unparsed entity declaration
            if (fGrammarAccess) {
                StringBuffer str = new StringBuffer();
                str.append("<!ENTITY ");
                str.append(fStringPool.toString(entityNameIndex));
                str.append(' ');
                if (publicIdIndex != -1) {
                    str.append("PUBLIC \"");
                    str.append(fStringPool.toString(publicIdIndex));
                    str.append('"');
                    if (systemIdIndex != -1) {
                        str.append(" \"");
                        str.append(fStringPool.toString(systemIdIndex));
                        str.append('"');
                    }
                }
                else if (systemIdIndex != -1) {
                    str.append("SYSTEM \"");
                    str.append(fStringPool.toString(systemIdIndex));
                    str.append('"');
                }
                str.append(" NDATA ");
                str.append(fStringPool.toString(notationNameIndex));
                str.append('>');
                Node unparsedEntity = fDocumentImpl.createComment(str.toString());
                Node schema = XUtil.getFirstChildElement(fDocumentType, "schema");
                schema.appendChild(unparsedEntity);
            }
        }

    } // unparsedEntityDecl(int,int,int,int)

    /**
     * &lt;!NOTATION Name ExternalId>
     */
    public void notationDecl(int notationNameIndex, int publicIdIndex, int systemIdIndex)
        throws Exception {

        // deferred expansion
        if (fDeferredDocumentImpl != null) {

            //revisit: how to check if entity was already declared.
            // XML spec says that 1st Entity decl is binding.

            int newNotationIndex = fDeferredDocumentImpl.createNotation(notationNameIndex, publicIdIndex, systemIdIndex);

            fDeferredDocumentImpl.appendChild(fDocumentTypeIndex, newNotationIndex);

            // create notation declaration
            if (fGrammarAccess) {
                int schemaIndex = getLastChildElement(fDocumentTypeIndex, "schema");
                String notationName = fStringPool.toString(notationNameIndex);
                int notationIndex = getLastChildElement(schemaIndex, "notation", "name", notationName);
                if (notationIndex == -1) {
                    int handle = fAttrList.startAttrList();
                    fAttrList.addAttr(
                        fStringPool.addSymbol("name"),
                        fStringPool.addString(notationName),
                        fStringPool.addSymbol("NMTOKEN"),
                        true,
                        false); // search
                    if (publicIdIndex != -1) {
                        fAttrList.addAttr(
                            fStringPool.addSymbol("public"),
                            publicIdIndex,
                            fStringPool.addSymbol("CDATA"),
                            true,
                            false); // search
                    }
                    if (systemIdIndex != -1) {
                        fAttrList.addAttr(
                            fStringPool.addSymbol("system"),
                            systemIdIndex,
                            fStringPool.addSymbol("CDATA"),
                            true,
                            false); // search
                    }
                    fAttrList.endAttrList();
                    notationIndex = fDeferredDocumentImpl.createElement(fStringPool.addSymbol("notation"), fAttrList, handle);
                    fDeferredDocumentImpl.appendChild(schemaIndex, notationIndex);
                }
            }
        }

        // full expansion
        else if (fDocumentImpl != null) {

            // REVISIT: how to check if entity was already declared.
            // XML spec says that 1st Entity decl is binding.

            String notationName = fStringPool.toString(notationNameIndex);
            String publicId = fStringPool.toString(publicIdIndex);
            String systemId = fStringPool.toString(systemIdIndex);

            NotationImpl notationImpl = (NotationImpl)fDocumentImpl.createNotation(notationName);
            notationImpl.setPublicId(publicId);
            if (systemIdIndex != -1) {
                notationImpl.setSystemId(systemId);
            }

            fDocumentType.getNotations().setNamedItem(notationImpl);

            // create notation declaration
            if (fGrammarAccess) {
                Element schema = XUtil.getFirstChildElement(fDocumentType, "schema");
                Element notation = XUtil.getFirstChildElement(schema, "notation", "name", notationName);
                if (notation == null) {
                    notation = fDocument.createElement("notation");
                    notation.setAttribute("name", notationName);
                    //notation.setAttribute("export", "true");
                    //((AttrImpl)notation.getAttributeNode("export")).setSpecified(false);
                    if (publicId != null) {
                        notation.setAttribute("public", publicId);
                    }
                    if (systemIdIndex != -1) {
                        notation.setAttribute("system", systemId);
                    }
                    schema.appendChild(notation);
                }
            }
        }

    } // notationDecl(int,int,int)

    //
    // Private methods
    //

    /** Returns the first child element of the specified node. */
    private int getFirstChildElement(int nodeIndex) {
        int childIndex = getLastChildElement(nodeIndex);
        while (childIndex != -1) {
            int prevIndex = getPrevSiblingElement(childIndex);
            if (prevIndex == -1) {
                break;
            }
            childIndex = prevIndex;
        }
        return childIndex;
    }

    /** Returns the first child element of the specified node. */
    private int getFirstChildElement(int nodeIndex, String name) {
        int childIndex = getLastChildElement(nodeIndex);
        if (childIndex != -1) {
            int nameIndex = fStringPool.addSymbol(name);
            while (childIndex != -1) {
                if (fDeferredDocumentImpl.getNodeName(childIndex, false) == nameIndex) {
                    break;
                }
                int prevIndex = getPrevSiblingElement(childIndex);
                childIndex = prevIndex;
            }
        }
        return childIndex;
    }

    /** Returns the last child element of the specified node. */
    private int getLastChildElement(int nodeIndex) {
        int childIndex = fDeferredDocumentImpl.getLastChild(nodeIndex, false);
        while (childIndex != -1) {
            if (fDeferredDocumentImpl.getNodeType(childIndex, false) == Node.ELEMENT_NODE) {
                return childIndex;
            }
            childIndex = fDeferredDocumentImpl.getPrevSibling(childIndex, false);
        }
        return -1;
    }

    /** Returns the previous sibling element of the specified node. */
    private int getPrevSiblingElement(int nodeIndex) {
        int siblingIndex = fDeferredDocumentImpl.getPrevSibling(nodeIndex, false);
        while (siblingIndex != -1) {
            if (fDeferredDocumentImpl.getNodeType(siblingIndex, false) == Node.ELEMENT_NODE) {
                return siblingIndex;
            }
            siblingIndex = fDeferredDocumentImpl.getPrevSibling(siblingIndex, false);
        }
        return -1;
    }

    /** Returns the first child element with the given name. */
    private int getLastChildElement(int nodeIndex, String elementName) {
        int childIndex = getLastChildElement(nodeIndex);
        if (childIndex != -1) {
            while (childIndex != -1) {
                String nodeName = fDeferredDocumentImpl.getNodeNameString(childIndex, false);
                if (nodeName.equals(elementName)) {
                    return childIndex;
                }
                childIndex = getPrevSiblingElement(childIndex);
            }
        }
        return -1;
    }

    /** Returns the next sibling element with the given name. */
    private int getPrevSiblingElement(int nodeIndex, String elementName) {
        int siblingIndex = getPrevSiblingElement(nodeIndex);
        if (siblingIndex != -1) {
            while (siblingIndex != -1) {
                String nodeName = fDeferredDocumentImpl.getNodeNameString(siblingIndex, false);
                if (nodeName.equals(elementName)) {
                    return siblingIndex;
                }
                siblingIndex = getPrevSiblingElement(siblingIndex);
            }
        }
        return -1;
    }

    /** Returns the first child element with the given name. */
    private int getLastChildElement(int nodeIndex, String elemName, String attrName, String attrValue) {
        int childIndex = getLastChildElement(nodeIndex, elemName);
        if (childIndex != -1) {
            while (childIndex != -1) {
                int attrIndex = fDeferredDocumentImpl.getNodeValue(childIndex, false);
                while (attrIndex != -1) {
                    String nodeName = fDeferredDocumentImpl.getNodeNameString(attrIndex, false);
                    if (nodeName.equals(attrName)) {
                        // REVISIT: Do we need to normalize the text? -Ac
                        int textIndex = fDeferredDocumentImpl.getLastChild(attrIndex, false);
                        String nodeValue = fDeferredDocumentImpl.getNodeValueString(textIndex, false);
                        if (nodeValue.equals(attrValue)) {
                            return childIndex;
                        }
                    }
                    attrIndex = fDeferredDocumentImpl.getPrevSibling(attrIndex, false);
                }
                childIndex = getPrevSiblingElement(childIndex, elemName);
            }
        }
        return -1;
    }

    /** Returns the next sibling element with the given name and attribute. */
    private int getPrevSiblingElement(int nodeIndex, String elemName, String attrName, String attrValue) {
        int siblingIndex = getPrevSiblingElement(nodeIndex, elemName);
        if (siblingIndex != -1) {
            int attributeNameIndex = fStringPool.addSymbol(attrName);
            while (siblingIndex != -1) {
                int attrIndex = fDeferredDocumentImpl.getNodeValue(siblingIndex, false);
                while (attrIndex != -1) {
                    int attrValueIndex = fDeferredDocumentImpl.getNodeValue(attrIndex, false);
                    if (attrValue.equals(fStringPool.toString(attrValueIndex))) {
                        return siblingIndex;
                    }
                    attrIndex = fDeferredDocumentImpl.getPrevSibling(attrIndex, false);
                }
                siblingIndex = getPrevSiblingElement(siblingIndex, elemName);
            }
        }
        return -1;
    }

    /**
     * Copies the source tree into the specified place in a destination
     * tree. The source node and its children are appended as children
     * of the destination node.
     * <p>
     * <em>Note:</em> This is an iterative implementation.
     */
    private void copyInto(Node src, int destIndex) throws Exception {

        // for ignorable whitespace features
        boolean domimpl = src != null && src instanceof DocumentImpl;

        // placement variables
        Node start  = src;
        Node parent = src;
        Node place  = src;

        // traverse source tree
        while (place != null) {

            // copy this node
            int nodeIndex = -1;
            short type = place.getNodeType();
            switch (type) {
                case Node.CDATA_SECTION_NODE: {
                    boolean ignorable = domimpl && ((TextImpl)place).isIgnorableWhitespace();
                    nodeIndex = fDeferredDocumentImpl.createCDATASection(fStringPool.addString(place.getNodeValue()), ignorable);
                    break;
                }
                case Node.COMMENT_NODE: {
                    nodeIndex = fDeferredDocumentImpl.createComment(fStringPool.addString(place.getNodeValue()));
                    break;
                }
                case Node.ELEMENT_NODE: {
                    XMLAttrList attrList = null;
                    int handle = -1;
                    NamedNodeMap attrs = place.getAttributes();
                    if (attrs != null) {
                        int length = attrs.getLength();
                        if (length > 0) {
                            handle = fAttrList.startAttrList();
                            for (int i = 0; i < length; i++) {
                                Attr attr = (Attr)attrs.item(i);
                                String attrName = attr.getNodeName();
                                String attrValue = attr.getNodeValue();
                                fAttrList.addAttr(
                                    fStringPool.addSymbol(attrName),
                                    fStringPool.addString(attrValue),
                                    fStringPool.addSymbol("CDATA"), // REVISIT
                                    attr.getSpecified(),
                                    false); // search
                            }
                            fAttrList.endAttrList();
                            attrList = fAttrList;
                        }
                    }
                    nodeIndex = fDeferredDocumentImpl.createElement(fStringPool.addSymbol(place.getNodeName()), attrList, handle);
                    break;
                }
                case Node.ENTITY_REFERENCE_NODE: {
                    nodeIndex = fDeferredDocumentImpl.createEntityReference(fStringPool.addSymbol(place.getNodeName()));
                    break;
                }
                case Node.PROCESSING_INSTRUCTION_NODE: {
                    nodeIndex = fDeferredDocumentImpl.createProcessingInstruction(fStringPool.addSymbol(place.getNodeName()), fStringPool.addString(place.getNodeValue()));
                    break;
                }
                case Node.TEXT_NODE: {
                    boolean ignorable = domimpl && ((TextImpl)place).isIgnorableWhitespace();
                    nodeIndex = fDeferredDocumentImpl.createTextNode(fStringPool.addString(place.getNodeValue()), ignorable);
                    break;
                }
                default: {
                    throw new IllegalArgumentException("PAR010 Can't copy node type, "+
                                                       type+" ("+
                                                       place.getNodeName()+')'
                                                       +"\n"+type+"\t"+place.getNodeName());
                }
            }
            fDeferredDocumentImpl.appendChild(destIndex, nodeIndex);

            // iterate over children
            if (place.hasChildNodes()) {
                parent = place;
                place = place.getFirstChild();
                destIndex = nodeIndex;
            }

            // advance
            else {
                place = place.getNextSibling();
                while (place == null && parent != start) {
                    place = parent.getNextSibling();
                    parent = parent.getParentNode();
                    destIndex = fDeferredDocumentImpl.getParentNode(destIndex, false);
                }
            }

        }

    } // copyInto(Node,int)

    /**
     * Sets the appropriate occurrence count attributes on the specified
     * model element.
     */
    private void setOccurrenceCount(Element model, int minOccur, int maxOccur) {

        // min
        model.setAttribute("minOccurs", Integer.toString(minOccur));
        if (minOccur == 1) {
            ((AttrImpl)model.getAttributeNode("minOccurs")).setSpecified(false);
        }

        // max
        if (maxOccur == -1) {
            model.setAttribute("maxOccurs", "*");
        }
        else if (maxOccur != 1) {
            model.setAttribute("maxOccurs", Integer.toString(maxOccur));
        }

    } // setOccurrenceCount(Element,int,int)

    /** Creates the children for the element decl. */
    private Element createChildren(XMLContentSpec.Provider provider, 
                                   int index, XMLContentSpec node,
                                   DocumentImpl factory,
                                   Element parent) throws Exception {

        // get occurrence count
        provider.getContentSpec(index, node);
        int occurs = -1;
        switch (node.type) {
            case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: {
                occurs = '+';
                provider.getContentSpec(node.value, node);
                break;
            }
            case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: {
                occurs = '*';
                provider.getContentSpec(node.value, node);
                break;
            }
            case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: {
                occurs = '?';
                provider.getContentSpec(node.value, node);
                break;
            }
        }

        // flatten model
        int nodeType = node.type;
        switch (nodeType) {

            // CHOICE or SEQUENCE
            case XMLContentSpec.CONTENTSPECNODE_CHOICE:
            case XMLContentSpec.CONTENTSPECNODE_SEQ: {

                // go down left side
                int leftIndex  = node.value;
                int rightIndex = node.otherValue;
                Element left = createChildren(provider, leftIndex, node, 
                                              factory, parent);

                // go down right side
                Element right = createChildren(provider, rightIndex, node, 
                                               factory, null);

                // append left children
                boolean choice = nodeType == XMLContentSpec.CONTENTSPECNODE_CHOICE;
                String type = choice ? "choice" : "sequence";
                Element model = left;
                if (!left.getNodeName().equals(type)) {
                    String minOccurs = left.getAttribute("minOccurs");
                    String maxOccurs = left.getAttribute("maxOccurs");
                    boolean min1 = minOccurs.length() == 0 || minOccurs.equals("1");
                    boolean max1 = maxOccurs.length() == 0 || maxOccurs.equals("1");
                    if (parent == null || (min1 && max1)) {
                        model = factory.createElement(type);
                        model.appendChild(left);
                    }
                    else {
                        model = parent;
                    }
                }

                // set occurrence count
                switch (occurs) {
                    case '+': {
                        model.setAttribute("maxOccurs", "unbounded");
                        break;
                    }
                    case '*': {
                        model.setAttribute("minOccurs", "0");
                        model.setAttribute("maxOccurs", "unbounded");
                        break;
                    }
                    case '?': {
                        model.setAttribute("minOccurs", "0");
                        break;
                    }
                }

                // append right children
                model.appendChild(right);

                // return model
                return model;
            }

            // LEAF
            case XMLContentSpec.CONTENTSPECNODE_LEAF: {
                Element leaf = factory.createElement("element");
                leaf.setAttribute("ref", fStringPool.toString(node.value));
                switch (occurs) {
                    case '+': {
                        leaf.setAttribute("maxOccurs", "unbounded");
                        break;
                    }
                    case '*': {
                        leaf.setAttribute("minOccurs", "0");
                        leaf.setAttribute("maxOccurs", "unbounded");
                        break;
                    }
                    case '?': {
                        leaf.setAttribute("minOccurs", "0");
                        break;
                    }
                }
                return leaf;
            }

        } // switch node type

        // error
        return null;

    } // createChildren(XMLContentSpec.Provider,int,XMLContentSpec,DocumentImpl,Element):Element

    /** Creates the children for the deferred element decl. */
    private int createChildren(XMLContentSpec.Provider provider, 
                               int index, XMLContentSpec node,
                               DeferredDocumentImpl factory,
                               int parent) throws Exception {

        // get occurrence count
        provider.getContentSpec(index, node);
        int occurs = -1;
        switch (node.type) {
            case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: {
                occurs = '+';
                provider.getContentSpec(node.value, node);
                break;
            }
            case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: {
                occurs = '*';
                provider.getContentSpec(node.value, node);
                break;
            }
            case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: {
                occurs = '?';
                provider.getContentSpec(node.value, node);
                break;
            }
        }

        // flatten model
        int nodeType = node.type;
        switch (nodeType) {

            // CHOICE or SEQUENCE
            case XMLContentSpec.CONTENTSPECNODE_CHOICE:
            case XMLContentSpec.CONTENTSPECNODE_SEQ: {

                // go down left side
                int leftIndex  = node.value;
                int rightIndex = node.otherValue;
                int left = createChildren(provider, leftIndex, node, 
                                          factory, parent);

                // go down right side
                int right = createChildren(provider, rightIndex, node, 
                                           factory, -1);

                // append left children
                boolean choice = nodeType == XMLContentSpec.CONTENTSPECNODE_CHOICE;
                int type = fStringPool.addSymbol(choice ? "choice" : "sequence");
                int model = left;
                if (factory.getNodeName(left, false) != type) {
                    int minOccurs = factory.getAttribute(left, fStringPool.addSymbol("minOccurs"));
                    int maxOccurs = factory.getAttribute(left, fStringPool.addSymbol("maxOccurs"));
                    boolean min1 = minOccurs == -1 || fStringPool.toString(minOccurs).equals("1");
                    boolean max1 = maxOccurs == -1 || fStringPool.toString(maxOccurs).equals("1");
                    if (parent == -1 || (min1 && max1)) {
                        model = factory.createElement(type, null, -1);
                        factory.appendChild(model, left);
                    }
                    else {
                        model = parent;
                    }
                }

                // set occurrence count
                switch (occurs) {
                    case '+': {
                        int maxOccurs = factory.createAttribute(fStringPool.addSymbol("maxOccurs"),
                                                                fStringPool.addString("unbounded"),
                                                                true);
                        factory.setAttributeNode(model, maxOccurs);
                        break;
                    }
                    case '*': {
                        int minOccurs = factory.createAttribute(fStringPool.addSymbol("minOccurs"),
                                                                fStringPool.addString("0"),
                                                                true);
                        factory.setAttributeNode(model, minOccurs);
                        int maxOccurs = factory.createAttribute(fStringPool.addSymbol("maxOccurs"),
                                                                fStringPool.addString("unbounded"),
                                                                true);
                        factory.setAttributeNode(model, maxOccurs);
                        break;
                    }
                    case '?': {
                        int minOccurs = factory.createAttribute(fStringPool.addSymbol("minOccurs"),
                                                                fStringPool.addString("0"),
                                                                true);
                        factory.setAttributeNode(model, minOccurs);
                        break;
                    }
                }

                // append right children
                factory.appendChild(model, right);

                // return model
                return model;
            }

            // LEAF
            case XMLContentSpec.CONTENTSPECNODE_LEAF: {
                int handle = fAttrList.startAttrList();
                fAttrList.addAttr(
                    fStringPool.addSymbol("ref"),
                    fStringPool.addString(fStringPool.toString(node.value)),
                    fStringPool.addSymbol("NMTOKEN"),
                    true,
                    false); // search
                switch (occurs) {
                    case '+': {
                        fAttrList.addAttr(
                            fStringPool.addSymbol("maxOccurs"),
                            fStringPool.addString("unbounded"),
                            fStringPool.addSymbol("CDATA"),
                            true,
                            false); // search
                        break;
                    }
                    case '*': {
                        fAttrList.addAttr(
                            fStringPool.addSymbol("minOccurs"),
                            fStringPool.addString("0"),
                            fStringPool.addSymbol("NMTOKEN"),
                            true,
                            false); // search
                        fAttrList.addAttr(
                            fStringPool.addSymbol("maxOccurs"),
                            fStringPool.addString("unbounded"),
                            fStringPool.addSymbol("CDATA"),
                            true,
                            false); // search
                        break;
                    }
                    case '?': {
                        fAttrList.addAttr(
                            fStringPool.addSymbol("minOccurs"),
                            fStringPool.addString("0"),
                            fStringPool.addSymbol("NMTOKEN"),
                            true,
                            false); // search
                        break;
                    }
                }
                fAttrList.endAttrList();
                int leaf = factory.createElement(fStringPool.addSymbol("element"), fAttrList, handle);
                return leaf;
            }

        } // switch node type

        // error
        return -1;

    } // createChildren(XMLContentSpec.Provider,int,XMLContentSpec,DeferredDocumentImpl,int):int

} // class DOMParser
