/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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$
 */

package org.apache.xalan.xsltc.dom;

import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;

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

import org.apache.xalan.xsltc.DOM;
import org.apache.xalan.xsltc.DOMEnhancedForDTM;
import org.apache.xalan.xsltc.StripFilter;
import org.apache.xalan.xsltc.TransletException;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
import org.apache.xalan.xsltc.runtime.Hashtable;
import org.apache.xml.dtm.Axis;
import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMAxisIterator;
import org.apache.xml.dtm.DTMManager;
import org.apache.xml.dtm.DTMWSFilter;
import org.apache.xml.dtm.ref.DTMAxisIterNodeList;
import org.apache.xml.dtm.ref.DTMDefaultBase;
import org.apache.xml.dtm.ref.DTMNodeProxy;
import org.apache.xml.dtm.ref.EmptyIterator;
import org.apache.xml.dtm.ref.sax2dtm.SAX2DTM2;
import org.apache.xml.serializer.SerializationHandler;
import org.apache.xml.serializer.ToXMLSAXHandler;
import org.apache.xml.utils.SystemIDResolver;
import org.apache.xml.utils.XMLStringFactory;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Entity;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
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
        Iterator idEntries = m_idAttributes.entrySet().iterator();
        if (!idEntries.hasNext()) {
            return null;
        }

        Hashtable idAttrsTable = new Hashtable();
        
        while (idEntries.hasNext()) {
            Map.Entry entry = (Map.Entry) idEntries.next();
            idAttrsTable.put(entry.getKey(), entry.getValue());
        }

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

}
