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

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