/*
 * reserved comment block
 * DO NOT REMOVE OR ALTER!
 */
/*
 * Copyright 2001-2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id: SAXImpl.java,v 1.5 2005/09/28 13:48:37 pvedula Exp $
 */

package com.sun.org.apache.xalan.internal.xsltc.dom;

import java.net.URL;
import java.net.MalformedURLException;
import java.util.Enumeration;

import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.DOMEnhancedForDTM;
import com.sun.org.apache.xalan.internal.xsltc.StripFilter;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary;
import com.sun.org.apache.xalan.internal.xsltc.runtime.Hashtable;
import com.sun.org.apache.xml.internal.dtm.DTM;
import com.sun.org.apache.xml.internal.dtm.Axis;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.dtm.DTMManager;
import com.sun.org.apache.xml.internal.dtm.DTMWSFilter;
import com.sun.org.apache.xml.internal.dtm.ref.DTMAxisIterNodeList;
import com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBase;
import com.sun.org.apache.xml.internal.dtm.ref.EmptyIterator;
import com.sun.org.apache.xml.internal.dtm.ref.DTMNodeProxy;
import com.sun.org.apache.xml.internal.dtm.ref.sax2dtm.SAX2DTM2;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler;
import com.sun.org.apache.xml.internal.utils.XMLStringFactory;
import com.sun.org.apache.xml.internal.utils.SystemIDResolver;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Entity;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;


/**
 * SAXImpl is the core model for SAX input source. SAXImpl objects are
 * usually created from an XSLTCDTMManager.
 *
 * <p>DOMSource inputs are handled using DOM2SAX + SAXImpl. SAXImpl has a
 * few specific fields (e.g. _node2Ids, _document) to keep DOM-related
 * information. They are used when the processing behavior between DOM and
 * SAX has to be different. Examples of these include id function and
 * unparsed entity.
 *
 * <p>SAXImpl extends SAX2DTM2 instead of SAX2DTM for better performance.
 * @author Jacek Ambroziak
 * @author Santiago Pericas-Geertsen
 * @author Morten Jorgensen
 * @author Douglas Sellers <douglasjsellers@hotmail.com>
 */
public final class SAXImpl extends SAX2DTM2
                           implements DOMEnhancedForDTM, DOMBuilder
{

    /* ------------------------------------------------------------------- */
    /* DOMBuilder fields BEGIN                                             */
    /* ------------------------------------------------------------------- */

    // Namespace prefix-to-uri mapping stuff
    private int       _uriCount     = 0;
    private int       _prefixCount  = 0;

    // Stack used to keep track of what whitespace text nodes are protected
    // by xml:space="preserve" attributes and which nodes that are not.
    private int[]   _xmlSpaceStack;
    private int     _idx = 1;
    private boolean _preserve = false;

    private static final String XML_STRING = "xml:";
    private static final String XML_PREFIX   = "xml";
    private static final String XMLSPACE_STRING = "xml:space";
    private static final String PRESERVE_STRING = "preserve";
    private static final String XMLNS_PREFIX = "xmlns";
    private static final String XML_URI = "http://www.w3.org/XML/1998/namespace";

    private boolean _escaping = true;
    private boolean _disableEscaping = false;
    private int _textNodeToProcess = DTM.NULL;

    /* ------------------------------------------------------------------- */
    /* DOMBuilder fields END                                               */
    /* ------------------------------------------------------------------- */

    // empty String for null attribute values
    private final static String EMPTYSTRING = "";

    // empty iterator to be returned when there are no children
    private final static DTMAxisIterator EMPTYITERATOR = EmptyIterator.getInstance();
    // The number of expanded names
    private int _namesSize = -1;

    // Namespace related stuff
    private Hashtable _nsIndex = new Hashtable();

    // The initial size of the text buffer
    private int _size = 0;

    // Tracks which textnodes are not escaped
    private BitArray  _dontEscape = null;

    // The URI to this document
    private String    _documentURI = null;
    static private int _documentURIIndex = 0;

    // The owner Document when the input source is DOMSource.
    private Document _document;

    // The hashtable for org.w3c.dom.Node to node id mapping.
    // This is only used when the input is a DOMSource and the
    // buildIdIndex flag is true.
    private Hashtable _node2Ids = null;

    // True if the input source is a DOMSource.
    private boolean _hasDOMSource = false;

    // The DTMManager
    private XSLTCDTMManager _dtmManager;

    // Support for access/navigation through org.w3c.dom API
    private Node[] _nodes;
    private NodeList[] _nodeLists;
    private final static String XML_LANG_ATTRIBUTE =
        "http://www.w3.org/XML/1998/namespace:@lang";

    /**
     * Define the origin of the document from which the tree was built
     */
    public void setDocumentURI(String uri) {
        if (uri != null) {
            setDocumentBaseURI(SystemIDResolver.getAbsoluteURI(uri));
        }
    }

    /**
     * Returns the origin of the document from which the tree was built
     */
    public String getDocumentURI() {
        String baseURI = getDocumentBaseURI();
        return (baseURI != null) ? baseURI : "rtf" + _documentURIIndex++;
    }

    public String getDocumentURI(int node) {
        return getDocumentURI();
    }

    public void setupMapping(String[] names, String[] urisArray,
                             int[] typesArray, String[] namespaces) {
        // This method only has a function in DOM adapters
    }

    /**
     * Lookup a namespace URI from a prefix starting at node. This method
     * is used in the execution of xsl:element when the prefix is not known
     * at compile time.
     */
    public String lookupNamespace(int node, String prefix)
        throws TransletException
    {
        int anode, nsnode;
        final AncestorIterator ancestors = new AncestorIterator();

        if (isElement(node)) {
            ancestors.includeSelf();
        }

        ancestors.setStartNode(node);
        while ((anode = ancestors.next()) != DTM.NULL) {
            final NamespaceIterator namespaces = new NamespaceIterator();

            namespaces.setStartNode(anode);
            while ((nsnode = namespaces.next()) != DTM.NULL) {
                if (getLocalName(nsnode).equals(prefix)) {
                    return getNodeValue(nsnode);
                }
            }
        }

        BasisLibrary.runTimeError(BasisLibrary.NAMESPACE_PREFIX_ERR, prefix);
        return null;
    }

    /**
     * Returns 'true' if a specific node is an element (of any type)
     */
    public boolean isElement(final int node) {
        return getNodeType(node) == DTM.ELEMENT_NODE;
    }

    /**
     * Returns 'true' if a specific node is an attribute (of any type)
     */
    public boolean isAttribute(final int node) {
        return getNodeType(node) == DTM.ATTRIBUTE_NODE;
    }

    /**
     * Returns the number of nodes in the tree (used for indexing)
     */
    public int getSize() {
        return getNumberOfNodes();
    }

    /**
     * Part of the DOM interface - no function here.
     */
    public void setFilter(StripFilter filter) {
    }


    /**
     * Returns true if node1 comes before node2 in document order
     */
    public boolean lessThan(int node1, int node2) {
        if (node1 == DTM.NULL) {
            return false;
        }

        if (node2 == DTM.NULL) {
            return true;
        }

        return (node1 < node2);
    }

    /**
     * Create an org.w3c.dom.Node from a node in the tree
     */
    public Node makeNode(int index) {
        if (_nodes == null) {
            _nodes = new Node[_namesSize];
        }

        int nodeID = makeNodeIdentity(index);
        if (nodeID < 0) {
            return null;
        }
        else if (nodeID < _nodes.length) {
            return (_nodes[nodeID] != null) ? _nodes[nodeID]
                : (_nodes[nodeID] = new DTMNodeProxy((DTM)this, index));
        }
        else {
            return new DTMNodeProxy((DTM)this, index);
        }
    }

    /**
     * Create an org.w3c.dom.Node from a node in an iterator
     * The iterator most be started before this method is called
     */
    public Node makeNode(DTMAxisIterator iter) {
        return makeNode(iter.next());
    }

    /**
     * Create an org.w3c.dom.NodeList from a node in the tree
     */
    public NodeList makeNodeList(int index) {
        if (_nodeLists == null) {
            _nodeLists = new NodeList[_namesSize];
        }

        int nodeID = makeNodeIdentity(index);
        if (nodeID < 0) {
            return null;
        }
        else if (nodeID < _nodeLists.length) {
            return (_nodeLists[nodeID] != null) ? _nodeLists[nodeID]
                   : (_nodeLists[nodeID] = new DTMAxisIterNodeList(this,
                                                 new SingletonIterator(index)));
    }
        else {
            return new DTMAxisIterNodeList(this, new SingletonIterator(index));
        }
    }

    /**
     * Create an org.w3c.dom.NodeList from a node iterator
     * The iterator most be started before this method is called
     */
    public NodeList makeNodeList(DTMAxisIterator iter) {
        return new DTMAxisIterNodeList(this, iter);
    }

    /**
     * Iterator that returns the namespace nodes as defined by the XPath data
     * model for a given node, filtered by extended type ID.
     */
    public class TypedNamespaceIterator extends NamespaceIterator {

        private  String _nsPrefix;

        /**
         * Constructor TypedChildrenIterator
         *
         *
         * @param nodeType The extended type ID being requested.
         */
        public TypedNamespaceIterator(int nodeType) {
            super();
            if(m_expandedNameTable != null){
                _nsPrefix = m_expandedNameTable.getLocalName(nodeType);
            }
        }

       /**
        * Get the next node in the iteration.
        *
        * @return The next node handle in the iteration, or END.
        */
        public int next() {
            if ((_nsPrefix == null) ||(_nsPrefix.length() == 0) ){
                return (END);
            }
            int node = END;
            for (node = super.next(); node != END; node = super.next()) {
                if (_nsPrefix.compareTo(getLocalName(node))== 0) {
                    return returnNode(node);
                }
            }
            return (END);
        }
    }  // end of TypedNamespaceIterator



    /**************************************************************
     * This is a specialised iterator for predicates comparing node or
     * attribute values to variable or parameter values.
     */
    private final class NodeValueIterator extends InternalAxisIteratorBase
    {

        private DTMAxisIterator _source;
        private String _value;
        private boolean _op;
        private final boolean _isReverse;
        private int _returnType = RETURN_PARENT;

        public NodeValueIterator(DTMAxisIterator source, int returnType,
                                 String value, boolean op)
        {
            _source = source;
            _returnType = returnType;
            _value = value;
            _op = op;
            _isReverse = source.isReverse();
        }

        public boolean isReverse()
        {
            return _isReverse;
        }

        public DTMAxisIterator cloneIterator()
        {
            try {
                NodeValueIterator clone = (NodeValueIterator)super.clone();
                clone._isRestartable = false;
                clone._source = _source.cloneIterator();
                clone._value = _value;
                clone._op = _op;
                return clone.reset();
            }
            catch (CloneNotSupportedException e) {
                BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
                                          e.toString());
                return null;
            }
        }

        public void setRestartable(boolean isRestartable)
        {
            _isRestartable = isRestartable;
            _source.setRestartable(isRestartable);
        }

        public DTMAxisIterator reset()
        {
            _source.reset();
            return resetPosition();
        }

        public int next()
        {
            int node;
            while ((node = _source.next()) != END) {
                String val = getStringValueX(node);
                if (_value.equals(val) == _op) {
                    if (_returnType == RETURN_CURRENT) {
                        return returnNode(node);
                    }
                    else {
                        return returnNode(getParent(node));
                    }
                }
            }
            return END;
        }

        public DTMAxisIterator setStartNode(int node)
        {
            if (_isRestartable) {
                _source.setStartNode(_startNode = node);
                return resetPosition();
            }
            return this;
        }

        public void setMark()
        {
            _source.setMark();
        }

        public void gotoMark()
        {
            _source.gotoMark();
        }
    } // end NodeValueIterator

    public DTMAxisIterator getNodeValueIterator(DTMAxisIterator iterator, int type,
                                             String value, boolean op)
    {
        return(DTMAxisIterator)(new NodeValueIterator(iterator, type, value, op));
    }

    /**
     * Encapsulates an iterator in an OrderedIterator to ensure node order
     */
    public DTMAxisIterator orderNodes(DTMAxisIterator source, int node)
    {
        return new DupFilterIterator(source);
    }

    /**
     * Returns singleton iterator containg the document root
     * Works for them main document (mark == 0).  It cannot be made
     * to point to any other node through setStartNode().
     */
    public DTMAxisIterator getIterator()
    {
        return new SingletonIterator(getDocument(), true);
    }

     /**
     * Get mapping from DOM namespace types to external namespace types
     */
    public int getNSType(int node)
    {
        String s = getNamespaceURI(node);
        if (s == null) {
            return 0;
        }
        int eType = getIdForNamespace(s);
        return ((Integer)_nsIndex.get(new Integer(eType))).intValue();
    }



    /**
     * Returns the namespace type of a specific node
     */
    public int getNamespaceType(final int node)
    {
        return super.getNamespaceType(node);
    }

    /**
     * Sets up a translet-to-dom type mapping table
     */
    private int[] setupMapping(String[] names, String[] uris, int[] types, int nNames) {
        // Padding with number of names, because they
        // may need to be added, i.e for RTFs. See copy03
        final int[] result = new int[m_expandedNameTable.getSize()];
        for (int i = 0; i < nNames; i++)      {
            //int type = getGeneralizedType(namesArray[i]);
            int type = m_expandedNameTable.getExpandedTypeID(uris[i], names[i], types[i], false);
            result[type] = type;
        }
        return result;
    }

    /**
     * Returns the internal type associated with an expanded QName
     */
    public int getGeneralizedType(final String name) {
        return getGeneralizedType(name, true);
    }

    /**
     * Returns the internal type associated with an expanded QName
     */
    public int getGeneralizedType(final String name, boolean searchOnly) {
        String lName, ns = null;
        int index = -1;
        int code;

        // Is there a prefix?
        if ((index = name.lastIndexOf(":"))> -1) {
            ns = name.substring(0, index);
        }

        // Local part of name is after colon.  lastIndexOf returns -1 if
        // there is no colon, so lNameStartIdx will be zero in that case.
        int lNameStartIdx = index+1;

        // Distinguish attribute and element names.  Attribute has @ before
        // local part of name.
        if (name.charAt(lNameStartIdx) == '@') {
            code = DTM.ATTRIBUTE_NODE;
            lNameStartIdx++;
        }
        else {
            code = DTM.ELEMENT_NODE;
        }

        // Extract local name
        lName = (lNameStartIdx == 0) ? name : name.substring(lNameStartIdx);

        return m_expandedNameTable.getExpandedTypeID(ns, lName, code, searchOnly);
    }

    /**
     * Get mapping from DOM element/attribute types to external types
     */
    public short[] getMapping(String[] names, String[] uris, int[] types)
    {
        // Delegate the work to getMapping2 if the document is not fully built.
        // Some of the processing has to be different in this case.
        if (_namesSize < 0) {
            return getMapping2(names, uris, types);
        }

        int i;
        final int namesLength = names.length;
        final int exLength = m_expandedNameTable.getSize();

        final short[] result = new short[exLength];

        // primitive types map to themselves
        for (i = 0; i < DTM.NTYPES; i++) {
            result[i] = (short)i;
        }

        for (i = NTYPES; i < exLength; i++) {
            result[i] = m_expandedNameTable.getType(i);
        }

        // actual mapping of caller requested names
        for (i = 0; i < namesLength; i++) {
            int genType = m_expandedNameTable.getExpandedTypeID(uris[i],
                                                                names[i],
                                                                types[i],
                                                                true);
            if (genType >= 0 && genType < exLength) {
                result[genType] = (short)(i + DTM.NTYPES);
            }
        }

        return result;
    }

    /**
     * Get mapping from external element/attribute types to DOM types
     */
    public int[] getReverseMapping(String[] names, String[] uris, int[] types)
    {
        int i;
        final int[] result = new int[names.length + DTM.NTYPES];

        // primitive types map to themselves
        for (i = 0; i < DTM.NTYPES; i++) {
            result[i] = i;
        }

        // caller's types map into appropriate dom types
        for (i = 0; i < names.length; i++) {
            int type = m_expandedNameTable.getExpandedTypeID(uris[i], names[i], types[i], true);
            result[i+DTM.NTYPES] = type;
        }
        return(result);
    }

    /**
     * Get mapping from DOM element/attribute types to external types.
     * This method is used when the document is not fully built.
     */
    private short[] getMapping2(String[] names, String[] uris, int[] types)
    {
        int i;
        final int namesLength = names.length;
        final int exLength = m_expandedNameTable.getSize();
        int[] generalizedTypes = null;
        if (namesLength > 0) {
            generalizedTypes = new int[namesLength];
        }

        int resultLength = exLength;

        for (i = 0; i < namesLength; i++) {
            // When the document is not fully built, the searchOnly
            // flag should be set to false. That means we should add
            // the type if it is not already in the expanded name table.
            //generalizedTypes[i] = getGeneralizedType(names[i], false);
            generalizedTypes[i] =
                m_expandedNameTable.getExpandedTypeID(uris[i],
                                                      names[i],
                                                      types[i],
                                                      false);
            if (_namesSize < 0 && generalizedTypes[i] >= resultLength) {
                resultLength = generalizedTypes[i] + 1;
            }
        }

        final short[] result = new short[resultLength];

        // primitive types map to themselves
        for (i = 0; i < DTM.NTYPES; i++) {
            result[i] = (short)i;
        }

        for (i = NTYPES; i < exLength; i++) {
            result[i] = m_expandedNameTable.getType(i);
        }

        // actual mapping of caller requested names
        for (i = 0; i < namesLength; i++) {
            int genType = generalizedTypes[i];
            if (genType >= 0 && genType < resultLength) {
                result[genType] = (short)(i + DTM.NTYPES);
            }
        }

        return(result);
    }
    /**
     * Get mapping from DOM namespace types to external namespace types
     */
    public short[] getNamespaceMapping(String[] namespaces)
    {
        int i;
        final int nsLength = namespaces.length;
        final int mappingLength = _uriCount;

        final short[] result = new short[mappingLength];

        // Initialize all entries to -1
        for (i=0; i<mappingLength; i++) {
            result[i] = (short)(-1);
        }

        for (i=0; i<nsLength; i++) {
            int eType = getIdForNamespace(namespaces[i]);
            Integer type = (Integer)_nsIndex.get(new Integer(eType));
            if (type != null) {
                result[type.intValue()] = (short)i;
            }
        }

        return(result);
    }

    /**
     * Get mapping from external namespace types to DOM namespace types
     */
    public short[] getReverseNamespaceMapping(String[] namespaces)
    {
        int i;
        final int length = namespaces.length;
        final short[] result = new short[length];

        for (i = 0; i < length; i++) {
            int eType = getIdForNamespace(namespaces[i]);
            Integer type = (Integer)_nsIndex.get(new Integer(eType));
            result[i] = (type == null) ? -1 : type.shortValue();
        }

        return result;
    }

    /**
     * Construct a SAXImpl object using the default block size.
     */
    public SAXImpl(XSLTCDTMManager mgr, Source source,
                   int dtmIdentity, DTMWSFilter whiteSpaceFilter,
                   XMLStringFactory xstringfactory,
                   boolean doIndexing, boolean buildIdIndex)
    {
        this(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory,
            doIndexing, DEFAULT_BLOCKSIZE, buildIdIndex, false);
    }

    /**
     * Construct a SAXImpl object using the given block size.
     */
    public SAXImpl(XSLTCDTMManager mgr, Source source,
                   int dtmIdentity, DTMWSFilter whiteSpaceFilter,
                   XMLStringFactory xstringfactory,
                   boolean doIndexing, int blocksize,
                   boolean buildIdIndex,
                   boolean newNameTable)
    {
        super(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory,
            doIndexing, blocksize, false, buildIdIndex, newNameTable);

        _dtmManager = mgr;
        _size = blocksize;

        // Use a smaller size for the space stack if the blocksize is small
        _xmlSpaceStack = new int[blocksize <= 64 ? 4 : 64];

        /* From DOMBuilder */
        _xmlSpaceStack[0] = DTMDefaultBase.ROOTNODE;

        // If the input source is DOMSource, set the _document field and
        // create the node2Ids table.
        if (source instanceof DOMSource) {
            _hasDOMSource = true;
            DOMSource domsrc = (DOMSource)source;
            Node node = domsrc.getNode();
            if (node instanceof Document) {
                _document = (Document)node;
            }
            else {
                _document = node.getOwnerDocument();
            }
            _node2Ids = new Hashtable();
        }
    }

    /**
    * Migrate a DTM built with an old DTMManager to a new DTMManager.
    * After the migration, the new DTMManager will treat the DTM as
    * one that is built by itself.
    * This is used to support DTM sharing between multiple transformations.
    * @param manager the DTMManager
    */
    public void migrateTo(DTMManager manager) {
        super.migrateTo(manager);
        if (manager instanceof XSLTCDTMManager) {
            _dtmManager = (XSLTCDTMManager)manager;
        }
    }

    /**
     * Return the node identity for a given id String
     *
     * @param idString The id String
     * @return The identity of the node whose id is the given String.
     */
    public int getElementById(String idString)
    {
        Node node = _document.getElementById(idString);
        if (node != null) {
            Integer id = (Integer)_node2Ids.get(node);
            return (id != null) ? id.intValue() : DTM.NULL;
        }
        else {
            return DTM.NULL;
        }
    }

    /**
     * Return true if the input source is DOMSource.
     */
    public boolean hasDOMSource()
    {
        return _hasDOMSource;
    }

    /*---------------------------------------------------------------------------*/
    /* DOMBuilder methods begin                                                  */
    /*---------------------------------------------------------------------------*/

    /**
     * Call this when an xml:space attribute is encountered to
     * define the whitespace strip/preserve settings.
     */
    private void xmlSpaceDefine(String val, final int node)
    {
        final boolean setting = val.equals(PRESERVE_STRING);
        if (setting != _preserve) {
            _xmlSpaceStack[_idx++] = node;
            _preserve = setting;
        }
    }

    /**
     * Call this from endElement() to revert strip/preserve setting
     * to whatever it was before the corresponding startElement().
     */
    private void xmlSpaceRevert(final int node)
    {
        if (node == _xmlSpaceStack[_idx - 1]) {
            _idx--;
            _preserve = !_preserve;
        }
    }

    /**
     * Find out whether or not to strip whitespace nodes.
     *
     *
     * @return whether or not to strip whitespace nodes.
     */
    protected boolean getShouldStripWhitespace()
    {
        return _preserve ? false : super.getShouldStripWhitespace();
    }

    /**
     * Creates a text-node and checks if it is a whitespace node.
     */
    private void handleTextEscaping() {
        if (_disableEscaping && _textNodeToProcess != DTM.NULL
            && _type(_textNodeToProcess) == DTM.TEXT_NODE) {
            if (_dontEscape == null) {
                _dontEscape = new BitArray(_size);
            }

            // Resize the _dontEscape BitArray if necessary.
            if (_textNodeToProcess >= _dontEscape.size()) {
                _dontEscape.resize(_dontEscape.size() * 2);
            }

            _dontEscape.setBit(_textNodeToProcess);
            _disableEscaping = false;
        }
        _textNodeToProcess = DTM.NULL;
    }


    /****************************************************************/
    /*               SAX Interface Starts Here                      */
    /****************************************************************/

    /**
     * SAX2: Receive notification of character data.
     */
    public void characters(char[] ch, int start, int length) throws SAXException
    {
        super.characters(ch, start, length);

        _disableEscaping = !_escaping;
        _textNodeToProcess = getNumberOfNodes();
    }

    /**
     * SAX2: Receive notification of the beginning of a document.
     */
    public void startDocument() throws SAXException
    {
        super.startDocument();

        _nsIndex.put(new Integer(0), new Integer(_uriCount++));
        definePrefixAndUri(XML_PREFIX, XML_URI);
    }

    /**
     * SAX2: Receive notification of the end of a document.
     */
    public void endDocument() throws SAXException
    {
        super.endDocument();

        handleTextEscaping();
        _namesSize = m_expandedNameTable.getSize();
    }

    /**
     * Specialized interface used by DOM2SAX. This one has an extra Node
     * parameter to build the Node -> id map.
     */
    public void startElement(String uri, String localName,
                             String qname, Attributes attributes,
                             Node node)
        throws SAXException
    {
        this.startElement(uri, localName, qname, attributes);

        if (m_buildIdIndex) {
            _node2Ids.put(node, new Integer(m_parents.peek()));
        }
    }

    /**
     * SAX2: Receive notification of the beginning of an element.
     */
    public void startElement(String uri, String localName,
                 String qname, Attributes attributes)
        throws SAXException
    {
        super.startElement(uri, localName, qname, attributes);

        handleTextEscaping();

        if (m_wsfilter != null) {
            // Look for any xml:space attributes
            // Depending on the implementation of attributes, this
            // might be faster than looping through all attributes. ILENE
            final int index = attributes.getIndex(XMLSPACE_STRING);
            if (index >= 0) {
                xmlSpaceDefine(attributes.getValue(index), m_parents.peek());
            }
        }
    }

    /**
     * SAX2: Receive notification of the end of an element.
     */
    public void endElement(String namespaceURI, String localName, String qname)
        throws SAXException
    {
        super.endElement(namespaceURI, localName, qname);

        handleTextEscaping();

        // Revert to strip/preserve-space setting from before this element
        if (m_wsfilter != null) {
            xmlSpaceRevert(m_previous);
        }
    }

    /**
     * SAX2: Receive notification of a processing instruction.
     */
    public void processingInstruction(String target, String data)
        throws SAXException
    {
        super.processingInstruction(target, data);
        handleTextEscaping();
    }

    /**
     * SAX2: Receive notification of ignorable whitespace in element
     * content. Similar to characters(char[], int, int).
     */
    public void ignorableWhitespace(char[] ch, int start, int length)
        throws SAXException
    {
        super.ignorableWhitespace(ch, start, length);
        _textNodeToProcess = getNumberOfNodes();
    }

    /**
     * SAX2: Begin the scope of a prefix-URI Namespace mapping.
     */
    public void startPrefixMapping(String prefix, String uri)
        throws SAXException
    {
        super.startPrefixMapping(prefix, uri);
        handleTextEscaping();

        definePrefixAndUri(prefix, uri);
    }

    private void definePrefixAndUri(String prefix, String uri)
        throws SAXException
    {
        // Check if the URI already exists before pushing on stack
        Integer eType = new Integer(getIdForNamespace(uri));
        if ((Integer)_nsIndex.get(eType) == null) {
            _nsIndex.put(eType, new Integer(_uriCount++));
        }
    }

    /**
     * SAX2: Report an XML comment anywhere in the document.
     */
    public void comment(char[] ch, int start, int length)
        throws SAXException
    {
        super.comment(ch, start, length);
        handleTextEscaping();
    }

    public boolean setEscaping(boolean value) {
        final boolean temp = _escaping;
        _escaping = value;
        return temp;
    }

   /*---------------------------------------------------------------------------*/
   /* DOMBuilder methods end                                                    */
   /*---------------------------------------------------------------------------*/

    /**
     * Prints the whole tree to standard output
     */
    public void print(int node, int level)
    {
        switch(getNodeType(node))
        {
            case DTM.ROOT_NODE:
            case DTM.DOCUMENT_NODE:
                print(getFirstChild(node), level);
                break;
            case DTM.TEXT_NODE:
            case DTM.COMMENT_NODE:
            case DTM.PROCESSING_INSTRUCTION_NODE:
                System.out.print(getStringValueX(node));
                break;
            default:
                final String name = getNodeName(node);
                System.out.print("<" + name);
                for (int a = getFirstAttribute(node); a != DTM.NULL; a = getNextAttribute(a))
                {
                    System.out.print("\n" + getNodeName(a) + "=\"" + getStringValueX(a) + "\"");
                }
                System.out.print('>');
                for (int child = getFirstChild(node); child != DTM.NULL;
                    child = getNextSibling(child)) {
                    print(child, level + 1);
                }
                System.out.println("</" + name + '>');
                break;
        }
    }

    /**
     * Returns the name of a node (attribute or element).
     */
    public String getNodeName(final int node)
    {
        // Get the node type and make sure that it is within limits
        int nodeh = node;
        final short type = getNodeType(nodeh);
        switch(type)
        {
            case DTM.ROOT_NODE:
            case DTM.DOCUMENT_NODE:
            case DTM.TEXT_NODE:
            case DTM.COMMENT_NODE:
                return EMPTYSTRING;
            case DTM.NAMESPACE_NODE:
                return this.getLocalName(nodeh);
            default:
                return super.getNodeName(nodeh);
        }
    }

    /**
     * Returns the namespace URI to which a node belongs
     */
    public String getNamespaceName(final int node)
    {
        if (node == DTM.NULL) {
            return "";
        }

        String s;
        return (s = getNamespaceURI(node)) == null ? EMPTYSTRING : s;
    }


    /**
     * Returns the attribute node of a given type (if any) for an element
     */
    public int getAttributeNode(final int type, final int element)
    {
        for (int attr = getFirstAttribute(element);
           attr != DTM.NULL;
           attr = getNextAttribute(attr))
        {
            if (getExpandedTypeID(attr) == type) return attr;
        }
        return DTM.NULL;
    }

    /**
     * Returns the value of a given attribute type of a given element
     */
    public String getAttributeValue(final int type, final int element)
    {
        final int attr = getAttributeNode(type, element);
        return (attr != DTM.NULL) ? getStringValueX(attr) : EMPTYSTRING;
    }

    /**
     * This method is for testing/debugging only
     */
    public String getAttributeValue(final String name, final int element)
    {
        return getAttributeValue(getGeneralizedType(name), element);
    }

    /**
     * Returns an iterator with all the children of a given node
     */
    public DTMAxisIterator getChildren(final int node)
    {
        return (new ChildrenIterator()).setStartNode(node);
    }

    /**
     * Returns an iterator with all children of a specific type
     * for a given node (element)
     */
    public DTMAxisIterator getTypedChildren(final int type)
    {
        return(new TypedChildrenIterator(type));
    }

    /**
     * This is a shortcut to the iterators that implement the
     * supported XPath axes (only namespace::) is not supported.
     * Returns a bare-bones iterator that must be initialized
     * with a start node (using iterator.setStartNode()).
     */
    public DTMAxisIterator getAxisIterator(final int axis)
    {
        switch (axis)
        {
            case Axis.SELF:
                return new SingletonIterator();
            case Axis.CHILD:
                return new ChildrenIterator();
            case Axis.PARENT:
                return new ParentIterator();
            case Axis.ANCESTOR:
                return new AncestorIterator();
            case Axis.ANCESTORORSELF:
                return (new AncestorIterator()).includeSelf();
            case Axis.ATTRIBUTE:
                return new AttributeIterator();
            case Axis.DESCENDANT:
                return new DescendantIterator();
            case Axis.DESCENDANTORSELF:
                return (new DescendantIterator()).includeSelf();
            case Axis.FOLLOWING:
                return new FollowingIterator();
            case Axis.PRECEDING:
                return new PrecedingIterator();
            case Axis.FOLLOWINGSIBLING:
                return new FollowingSiblingIterator();
            case Axis.PRECEDINGSIBLING:
                return new PrecedingSiblingIterator();
            case Axis.NAMESPACE:
                return new NamespaceIterator();
            case Axis.ROOT:
                return new RootIterator();
            default:
                BasisLibrary.runTimeError(BasisLibrary.AXIS_SUPPORT_ERR,
                        Axis.getNames(axis));
        }
        return null;
    }

    /**
     * Similar to getAxisIterator, but this one returns an iterator
     * containing nodes of a typed axis (ex.: child::foo)
     */
    public DTMAxisIterator getTypedAxisIterator(int axis, int type)
    {
        // Most common case handled first
        if (axis == Axis.CHILD) {
            return new TypedChildrenIterator(type);
        }

        if (type == NO_TYPE) {
            return(EMPTYITERATOR);
        }

        switch (axis)
        {
            case Axis.SELF:
                return new TypedSingletonIterator(type);
            case Axis.CHILD:
                return new TypedChildrenIterator(type);
            case Axis.PARENT:
                return new ParentIterator().setNodeType(type);
            case Axis.ANCESTOR:
                return new TypedAncestorIterator(type);
            case Axis.ANCESTORORSELF:
                return (new TypedAncestorIterator(type)).includeSelf();
            case Axis.ATTRIBUTE:
                return new TypedAttributeIterator(type);
            case Axis.DESCENDANT:
                return new TypedDescendantIterator(type);
            case Axis.DESCENDANTORSELF:
                return (new TypedDescendantIterator(type)).includeSelf();
            case Axis.FOLLOWING:
                return new TypedFollowingIterator(type);
            case Axis.PRECEDING:
                return new TypedPrecedingIterator(type);
            case Axis.FOLLOWINGSIBLING:
                return new TypedFollowingSiblingIterator(type);
            case Axis.PRECEDINGSIBLING:
                return new TypedPrecedingSiblingIterator(type);
            case Axis.NAMESPACE:
                return  new TypedNamespaceIterator(type);
            case Axis.ROOT:
                return new TypedRootIterator(type);
            default:
                BasisLibrary.runTimeError(BasisLibrary.TYPED_AXIS_SUPPORT_ERR,
                        Axis.getNames(axis));
        }
        return null;
    }

    /**
     * Do not think that this returns an iterator for the namespace axis.
     * It returns an iterator with nodes that belong in a certain namespace,
     * such as with <xsl:apply-templates select="blob/foo:*"/>
     * The 'axis' specifies the axis for the base iterator from which the
     * nodes are taken, while 'ns' specifies the namespace URI type.
     */
    public DTMAxisIterator getNamespaceAxisIterator(int axis, int ns)
    {

        DTMAxisIterator iterator = null;

        if (ns == NO_TYPE) {
            return EMPTYITERATOR;
        }
        else {
            switch (axis) {
                case Axis.CHILD:
                    return new NamespaceChildrenIterator(ns);
                case Axis.ATTRIBUTE:
                    return new NamespaceAttributeIterator(ns);
                default:
                    return new NamespaceWildcardIterator(axis, ns);
            }
        }
    }

    /**
     * Iterator that handles node tests that test for a namespace, but have
     * a wild card for the local name of the node, i.e., node tests of the
     * form <axis>::<prefix>:*
     */
    public final class NamespaceWildcardIterator
        extends InternalAxisIteratorBase
    {
        /**
         * The namespace type index.
         */
        protected int m_nsType;

        /**
         * A nested typed axis iterator that retrieves nodes of the principal
         * node kind for that axis.
         */
        protected DTMAxisIterator m_baseIterator;

        /**
         * Constructor NamespaceWildcard
         *
         * @param axis The axis that this iterator will traverse
         * @param nsType The namespace type index
         */
        public NamespaceWildcardIterator(int axis, int nsType) {
            m_nsType = nsType;

            // Create a nested iterator that will select nodes of
            // the principal node kind for the selected axis.
            switch (axis) {
                case Axis.ATTRIBUTE: {
                    // For "attribute::p:*", the principal node kind is
                    // attribute
                    m_baseIterator = getAxisIterator(axis);
                }
                case Axis.NAMESPACE: {
                    // This covers "namespace::p:*".  It is syntactically
                    // correct, though it doesn't make much sense.
                    m_baseIterator = getAxisIterator(axis);
                }
                default: {
                    // In all other cases, the principal node kind is
                    // element
                    m_baseIterator = getTypedAxisIterator(axis,
                                                          DTM.ELEMENT_NODE);
                }
            }
        }

        /**
         * Set start to END should 'close' the iterator,
         * i.e. subsequent call to next() should return END.
         *
         * @param node Sets the root of the iteration.
         *
         * @return A DTMAxisIterator set to the start of the iteration.
         */
        public DTMAxisIterator setStartNode(int node) {
            if (_isRestartable) {
                _startNode = node;
                m_baseIterator.setStartNode(node);
                resetPosition();
            }
            return this;
        }

        /**
         * Get the next node in the iteration.
         *
         * @return The next node handle in the iteration, or END.
         */
        public int next() {
            int node;

            while ((node = m_baseIterator.next()) != END) {
                // Return only nodes that are in the selected namespace
                if (getNSType(node) == m_nsType) {
                    return returnNode(node);
                }
            }

            return END;
        }

        /**
         * Returns a deep copy of this iterator.  The cloned iterator is not
         * reset.
         *
         * @return a deep copy of this iterator.
         */
        public DTMAxisIterator cloneIterator() {
            try {
                DTMAxisIterator nestedClone = m_baseIterator.cloneIterator();
                NamespaceWildcardIterator clone =
                    (NamespaceWildcardIterator) super.clone();

                clone.m_baseIterator = nestedClone;
                clone.m_nsType = m_nsType;
                clone._isRestartable = false;

                return clone;
            } catch (CloneNotSupportedException e) {
                BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
                                          e.toString());
                return null;
            }
        }

        /**
         * True if this iterator has a reversed axis.
         *
         * @return <code>true</code> if this iterator is a reversed axis.
         */
        public boolean isReverse() {
            return m_baseIterator.isReverse();
        }

        public void setMark() {
            m_baseIterator.setMark();
        }

        public void gotoMark() {
            m_baseIterator.gotoMark();
        }
    }

    /**
     * Iterator that returns children within a given namespace for a
     * given node. The functionality chould be achieved by putting a
     * filter on top of a basic child iterator, but a specialised
     * iterator is used for efficiency (both speed and size of translet).
     */
    public final class NamespaceChildrenIterator
        extends InternalAxisIteratorBase
    {

        /** The extended type ID being requested. */
        private final int _nsType;

        /**
         * Constructor NamespaceChildrenIterator
         *
         *
         * @param type The extended type ID being requested.
         */
        public NamespaceChildrenIterator(final int type) {
            _nsType = type;
        }

        /**
         * Set start to END should 'close' the iterator,
         * i.e. subsequent call to next() should return END.
         *
         * @param node Sets the root of the iteration.
         *
         * @return A DTMAxisIterator set to the start of the iteration.
         */
        public DTMAxisIterator setStartNode(int node) {
            //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
            if (node == DTMDefaultBase.ROOTNODE) {
                node = getDocument();
            }

            if (_isRestartable) {
                _startNode = node;
                _currentNode = (node == DTM.NULL) ? DTM.NULL : NOTPROCESSED;

                return resetPosition();
            }

            return this;
        }

        /**
         * Get the next node in the iteration.
         *
         * @return The next node handle in the iteration, or END.
         */
        public int next() {
            if (_currentNode != DTM.NULL) {
                for (int node = (NOTPROCESSED == _currentNode)
                                     ? _firstch(makeNodeIdentity(_startNode))
                                     : _nextsib(_currentNode);
                     node != END;
                     node = _nextsib(node)) {
                    int nodeHandle = makeNodeHandle(node);

                    if (getNSType(nodeHandle) == _nsType) {
                        _currentNode = node;

                        return returnNode(nodeHandle);
                    }
                }
            }

            return END;
        }
    }  // end of NamespaceChildrenIterator

    /**
     * Iterator that returns attributes within a given namespace for a node.
     */
    public final class NamespaceAttributeIterator
            extends InternalAxisIteratorBase
    {

        /** The extended type ID being requested. */
        private final int _nsType;

        /**
         * Constructor NamespaceAttributeIterator
         *
         *
         * @param nsType The extended type ID being requested.
         */
        public NamespaceAttributeIterator(int nsType) {
            super();

            _nsType = nsType;
        }

        /**
         * Set start to END should 'close' the iterator,
         * i.e. subsequent call to next() should return END.
         *
         * @param node Sets the root of the iteration.
         *
         * @return A DTMAxisIterator set to the start of the iteration.
         */
        public DTMAxisIterator setStartNode(int node) {
            //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
            if (node == DTMDefaultBase.ROOTNODE) {
                node = getDocument();
            }

            if (_isRestartable) {
                int nsType = _nsType;

                _startNode = node;

                for (node = getFirstAttribute(node);
                     node != END;
                     node = getNextAttribute(node)) {
                    if (getNSType(node) == nsType) {
                        break;
                    }
                }

                _currentNode = node;
                return resetPosition();
            }

            return this;
        }

        /**
         * Get the next node in the iteration.
         *
         * @return The next node handle in the iteration, or END.
         */
        public int next() {
            int node = _currentNode;
            int nsType = _nsType;
            int nextNode;

            if (node == END) {
                return END;
            }

            for (nextNode = getNextAttribute(node);
                 nextNode != END;
                 nextNode = getNextAttribute(nextNode)) {
                if (getNSType(nextNode) == nsType) {
                    break;
                }
            }

            _currentNode = nextNode;

            return returnNode(node);
        }
    }  // end of NamespaceAttributeIterator

    /**
     * Returns an iterator with all descendants of a node that are of
     * a given type.
     */
    public DTMAxisIterator getTypedDescendantIterator(int type)
    {
        return new TypedDescendantIterator(type);
    }

    /**
     * Returns the nth descendant of a node
     */
    public DTMAxisIterator getNthDescendant(int type, int n, boolean includeself)
    {
        DTMAxisIterator source = (DTMAxisIterator) new TypedDescendantIterator(type);
        return new NthDescendantIterator(n);
    }

    /**
     * Copy the string value of a node directly to an output handler
     */
    public void characters(final int node, SerializationHandler handler)
        throws TransletException
    {
        if (node != DTM.NULL) {
            try {
                dispatchCharactersEvents(node, handler, false);
            } catch (SAXException e) {
                throw new TransletException(e);
            }
        }
    }

    /**
     * Copy a node-set to an output handler
     */
    public void copy(DTMAxisIterator nodes, SerializationHandler handler)
        throws TransletException
    {
        int node;
        while ((node = nodes.next()) != DTM.NULL) {
            copy(node, handler);
        }
    }

    /**
     * Copy the whole tree to an output handler
     */
    public void copy(SerializationHandler handler) throws TransletException
    {
        copy(getDocument(), handler);
    }

    /**
     * Performs a deep copy (ref. XSLs copy-of())
     *
     * TODO: Copy namespace declarations. Can't be done until we
     *       add namespace nodes and keep track of NS prefixes
     * TODO: Copy comment nodes
     */
    public void copy(final int node, SerializationHandler handler)
        throws TransletException
    {
        copy(node, handler, false );
    }


 private final void copy(final int node, SerializationHandler handler, boolean isChild)
        throws TransletException
    {
     int nodeID = makeNodeIdentity(node);
        int eType = _exptype2(nodeID);
        int type = _exptype2Type(eType);

        try {
            switch(type)
            {
                case DTM.ROOT_NODE:
                case DTM.DOCUMENT_NODE:
                    for(int c = _firstch2(nodeID); c != DTM.NULL; c = _nextsib2(c)) {
                        copy(makeNodeHandle(c), handler, true);
                    }
                    break;
                case DTM.PROCESSING_INSTRUCTION_NODE:
                    copyPI(node, handler);
                    break;
                case DTM.COMMENT_NODE:
                    handler.comment(getStringValueX(node));
                    break;
                case DTM.TEXT_NODE:
                    boolean oldEscapeSetting = false;
                    boolean escapeBit = false;

                    if (_dontEscape != null) {
                        escapeBit = _dontEscape.getBit(getNodeIdent(node));
                        if (escapeBit) {
                            oldEscapeSetting = handler.setEscaping(false);
                        }
                    }

                    copyTextNode(nodeID, handler);

                    if (escapeBit) {
                        handler.setEscaping(oldEscapeSetting);
                    }
                    break;
                case DTM.ATTRIBUTE_NODE:
                    copyAttribute(nodeID, eType, handler);
                    break;
                case DTM.NAMESPACE_NODE:
                    handler.namespaceAfterStartElement(getNodeNameX(node), getNodeValue(node));
                    break;
                default:
                    if (type == DTM.ELEMENT_NODE)
                    {
                        // Start element definition
                        final String name = copyElement(nodeID, eType, handler);
                        //if(isChild) => not to copy any namespaces  from parents
                        // else copy all namespaces in scope
                        copyNS(nodeID, handler,!isChild);
                        copyAttributes(nodeID, handler);
                        // Copy element children
                        for (int c = _firstch2(nodeID); c != DTM.NULL; c = _nextsib2(c)) {
                            copy(makeNodeHandle(c), handler, true);
                        }

                        // Close element definition
                        handler.endElement(name);
                    }
                    // Shallow copy of attribute to output handler
                    else {
                        final String uri = getNamespaceName(node);
                        if (uri.length() != 0) {
                            final String prefix = getPrefix(node);
                            handler.namespaceAfterStartElement(prefix, uri);
                        }
                        handler.addAttribute(getNodeName(node), getNodeValue(node));
                    }
                    break;
            }
        }
        catch (Exception e) {
            throw new TransletException(e);
        }

    }
    /**
     * Copies a processing instruction node to an output handler
     */
    private void copyPI(final int node, SerializationHandler handler)
        throws TransletException
    {
        final String target = getNodeName(node);
        final String value = getStringValueX(node);

        try {
            handler.processingInstruction(target, value);
        } catch (Exception e) {
            throw new TransletException(e);
        }
    }

    /**
     * Performs a shallow copy (ref. XSLs copy())
     */
    public String shallowCopy(final int node, SerializationHandler handler)
        throws TransletException
    {
        int nodeID = makeNodeIdentity(node);
        int exptype = _exptype2(nodeID);
        int type = _exptype2Type(exptype);

        try {
            switch(type)
            {
                case DTM.ELEMENT_NODE:
                    final String name = copyElement(nodeID, exptype, handler);
                    copyNS(nodeID, handler, true);
                    return name;
                case DTM.ROOT_NODE:
                case DTM.DOCUMENT_NODE:
                    return EMPTYSTRING;
                case DTM.TEXT_NODE:
                    copyTextNode(nodeID, handler);
                    return null;
                case DTM.PROCESSING_INSTRUCTION_NODE:
                    copyPI(node, handler);
                    return null;
                case DTM.COMMENT_NODE:
                    handler.comment(getStringValueX(node));
                    return null;
                case DTM.NAMESPACE_NODE:
                    handler.namespaceAfterStartElement(getNodeNameX(node), getNodeValue(node));
                    return null;
                case DTM.ATTRIBUTE_NODE:
                    copyAttribute(nodeID, exptype, handler);
                    return null;
                default:
                    final String uri1 = getNamespaceName(node);
                    if (uri1.length() != 0) {
                        final String prefix = getPrefix(node);
                        handler.namespaceAfterStartElement(prefix, uri1);
                    }
                    handler.addAttribute(getNodeName(node), getNodeValue(node));
                    return null;
            }
        } catch (Exception e) {
            throw new TransletException(e);
        }
    }

    /**
     * Returns a node' defined language for a node (if any)
     */
    public String getLanguage(int node)
    {
        int parent = node;
        while (DTM.NULL != parent) {
            if (DTM.ELEMENT_NODE == getNodeType(parent)) {
                int langAttr = getAttributeNode(parent, "http://www.w3.org/XML/1998/namespace", "lang");

                if (DTM.NULL != langAttr) {
                    return getNodeValue(langAttr);
                }
            }

            parent = getParent(parent);
        }
        return(null);
    }

    /**
     * Returns an instance of the DOMBuilder inner class
     * This class will consume the input document through a SAX2
     * interface and populate the tree.
     */
    public DOMBuilder getBuilder()
    {
        return this;
    }

    /**
     * Return a SerializationHandler for output handling.
     * This method is used by Result Tree Fragments.
     */
    public SerializationHandler getOutputDomBuilder()
    {
        return new ToXMLSAXHandler(this, "UTF-8");
    }

    /**
     * Return a instance of a DOM class to be used as an RTF
     */
    public DOM getResultTreeFrag(int initSize, int rtfType)
    {
        return getResultTreeFrag(initSize, rtfType, true);
    }

    /**
     * Return a instance of a DOM class to be used as an RTF
     *
     * @param initSize The initial size of the DOM.
     * @param rtfType The type of the RTF
     * @param addToManager true if the RTF should be registered with the DTMManager.
     * @return The DOM object which represents the RTF.
     */
    public DOM getResultTreeFrag(int initSize, int rtfType, boolean addToManager)
    {
        if (rtfType == DOM.SIMPLE_RTF) {
            if (addToManager) {
                int dtmPos = _dtmManager.getFirstFreeDTMID();
                SimpleResultTreeImpl rtf = new SimpleResultTreeImpl(_dtmManager,
                                           dtmPos << DTMManager.IDENT_DTM_NODE_BITS);
                _dtmManager.addDTM(rtf, dtmPos, 0);
                return rtf;
            }
            else {
                return new SimpleResultTreeImpl(_dtmManager, 0);
            }
        }
        else if (rtfType == DOM.ADAPTIVE_RTF) {
            if (addToManager) {
                int dtmPos = _dtmManager.getFirstFreeDTMID();
                AdaptiveResultTreeImpl rtf = new AdaptiveResultTreeImpl(_dtmManager,
                                       dtmPos << DTMManager.IDENT_DTM_NODE_BITS,
                                       m_wsfilter, initSize, m_buildIdIndex);
                _dtmManager.addDTM(rtf, dtmPos, 0);
                return rtf;

            }
            else {
                return new AdaptiveResultTreeImpl(_dtmManager, 0,
                                       m_wsfilter, initSize, m_buildIdIndex);
            }
        }
        else {
            return (DOM) _dtmManager.getDTM(null, true, m_wsfilter,
                                            true, false, false,
                                            initSize, m_buildIdIndex);
        }
    }

    /**
     * %HZ% Need Javadoc
     */
    public Hashtable getElementsWithIDs() {
        if (m_idAttributes == null) {
            return null;
        }

        // Convert a java.util.Hashtable to an xsltc.runtime.Hashtable
        Enumeration idValues = m_idAttributes.keys();
        if (!idValues.hasMoreElements()) {
            return null;
        }

        Hashtable idAttrsTable = new Hashtable();

        while (idValues.hasMoreElements()) {
            Object idValue = idValues.nextElement();

            idAttrsTable.put(idValue, m_idAttributes.get(idValue));
        }

        return idAttrsTable;
    }

    /**
     * The getUnparsedEntityURI function returns the URI of the unparsed
     * entity with the specified name in the same document as the context
     * node (see [3.3 Unparsed Entities]). It returns the empty string if
     * there is no such entity.
     */
    public String getUnparsedEntityURI(String name)
    {
        // Special handling for DOM input
        if (_document != null) {
            String uri = "";
            DocumentType doctype = _document.getDoctype();
            if (doctype != null) {
                NamedNodeMap entities = doctype.getEntities();

                if (entities == null) {
                    return uri;
                }

                Entity entity = (Entity) entities.getNamedItem(name);

                if (entity == null) {
                    return uri;
                }

                String notationName = entity.getNotationName();
                if (notationName != null) {
                    uri = entity.getSystemId();
                    if (uri == null) {
                        uri = entity.getPublicId();
                    }
                }
            }
            return uri;
        }
        else {
            return super.getUnparsedEntityURI(name);
        }
    }

}
