/*
 * 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 org.apache.xalan.xsltc.DOM;
import org.apache.xalan.xsltc.TransletException;
import org.apache.xalan.xsltc.StripFilter;
import org.apache.xalan.xsltc.runtime.Hashtable;
import org.apache.xalan.xsltc.runtime.BasisLibrary;
import org.apache.xalan.xsltc.runtime.AttributeList;

import org.apache.xml.dtm.DTMAxisIterator;
import org.apache.xml.dtm.DTMAxisTraverser;
import org.apache.xml.dtm.DTMWSFilter;
import org.apache.xml.utils.XMLString;

import org.apache.xml.serializer.SerializationHandler;

import javax.xml.transform.SourceLocator;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

/**
 * AdaptiveResultTreeImpl is a adaptive DOM model for result tree fragments (RTF). It is
 * used in the case where the RTF is likely to be pure text yet it can still be a DOM tree. 
 * It is designed for RTFs which have &lt;xsl:call-template&gt; or &lt;xsl:apply-templates&gt; in 
 * the contents. Example:
 * <pre>
 *    &lt;xsl:variable name = "x"&gt;
 *      &lt;xsl:call-template name = "test"&gt;
 *         &lt;xsl:with-param name="a" select="."/&gt;
 *      &lt;/xsl:call-template&gt;
 *    &lt;/xsl:variable>
 * </pre>
 * <p>In this example the result produced by <xsl:call-template> is likely to be a single
 * Text node. But it can also be a DOM tree. This kind of RTF cannot be modelled by 
 * SimpleResultTreeImpl. 
 * <p>
 * AdaptiveResultTreeImpl can be considered as a smart switcher between SimpleResultTreeImpl
 * and SAXImpl. It treats the RTF as simple Text and uses the SimpleResultTreeImpl model
 * at the beginning. However, if it receives a call which indicates that this is a DOM tree
 * (e.g. startElement), it will automatically transform itself into a wrapper around a 
 * SAXImpl. In this way we can have a light-weight model when the result only contains
 * simple text, while at the same time it still works when the RTF is a DOM tree.
 * <p>
 * All methods in this class are overridden to delegate the action to the wrapped SAXImpl object
 * if it is non-null, or delegate the action to the SimpleResultTreeImpl if there is no
 * wrapped SAXImpl.
 * <p>
 * %REVISIT% Can we combine this class with SimpleResultTreeImpl? I think it is possible, but
 * it will make SimpleResultTreeImpl more expensive. I will use two separate classes at 
 * this time.
 */
public class AdaptiveResultTreeImpl extends SimpleResultTreeImpl
{
    
    // Document URI index, which increases by 1 at each getDocumentURI() call.
    private static int _documentURIIndex = 0;

    // The SAXImpl object wrapped by this class, if the RTF is a tree.
    private SAXImpl _dom;
    
    /** The following fields are only used for the nested SAXImpl **/
    
    // The whitespace filter
    private DTMWSFilter _wsfilter;
    
    // The size of the RTF
    private int _initSize;
    
    // True if we want to build the ID index table
    private boolean _buildIdIndex;
    
    // The AttributeList
    private final AttributeList  _attributes = new AttributeList();
    
    // The element name
    private String _openElementName;
    
    
    // Create a AdaptiveResultTreeImpl
    public AdaptiveResultTreeImpl(XSLTCDTMManager dtmManager, int documentID,
                                  DTMWSFilter wsfilter, int initSize,
                                  boolean buildIdIndex)
    {
        super(dtmManager, documentID);
        
        _wsfilter = wsfilter;
        _initSize = initSize;
        _buildIdIndex = buildIdIndex;
    }
    
    // Return the DOM object wrapped in this object.
    public DOM getNestedDOM()
    {
        return _dom;
    }
        
    // Return the document ID
    public int getDocument()
    {
        if (_dom != null) {
            return _dom.getDocument();
        }
        else {
            return super.getDocument();
        }
    }

    // Return the String value of the RTF
    public String getStringValue()
    {
        if (_dom != null) {
            return _dom.getStringValue();
        }
        else {
            return super.getStringValue();
        }
    }
    
    public DTMAxisIterator getIterator()
    {
        if (_dom != null) {
            return _dom.getIterator();
        }
        else {
            return super.getIterator();
        }
    }
	
    public DTMAxisIterator getChildren(final int node)
    {
        if (_dom != null) {
            return _dom.getChildren(node);
        }
        else {
            return super.getChildren(node);
        }
    }
    
    public DTMAxisIterator getTypedChildren(final int type)
    {
        if (_dom != null) {
            return _dom.getTypedChildren(type);
        }
        else {
            return super.getTypedChildren(type);
        }
    }
    
    public DTMAxisIterator getAxisIterator(final int axis)
    {
        if (_dom != null) {
            return _dom.getAxisIterator(axis);
        }
        else {
            return super.getAxisIterator(axis);
        }
    }
    
    public DTMAxisIterator getTypedAxisIterator(final int axis, final int type)
    {
        if (_dom != null) {
            return _dom.getTypedAxisIterator(axis, type);
        }
        else {
            return super.getTypedAxisIterator(axis, type);
        }        
    }
    
    public DTMAxisIterator getNthDescendant(int node, int n, boolean includeself)
    {
        if (_dom != null) {
            return _dom.getNthDescendant(node, n, includeself);
        }
        else {
            return super.getNthDescendant(node, n, includeself);
        }
    }
    
    public DTMAxisIterator getNamespaceAxisIterator(final int axis, final int ns)
    {
        if (_dom != null) {
            return _dom.getNamespaceAxisIterator(axis, ns);
        }
        else {
            return super.getNamespaceAxisIterator(axis, ns);
        }
    }
    
    public DTMAxisIterator getNodeValueIterator(DTMAxisIterator iter, int returnType,
					     String value, boolean op)
    {
        if (_dom != null) {
            return _dom.getNodeValueIterator(iter, returnType, value, op);
        }
        else {
            return super.getNodeValueIterator(iter, returnType, value, op);
        }
    }
    
    public DTMAxisIterator orderNodes(DTMAxisIterator source, int node)
    {
        if (_dom != null) {
            return _dom.orderNodes(source, node);
        }
        else {
            return super.orderNodes(source, node);
        }
    }
    
    public String getNodeName(final int node)
    {
        if (_dom != null) {
            return _dom.getNodeName(node);
        }
        else {
            return super.getNodeName(node);
        }
    }
    
    public String getNodeNameX(final int node)
    {
        if (_dom != null) {
            return _dom.getNodeNameX(node);
        }
        else {
            return super.getNodeNameX(node);
        }
    }
    
    public String getNamespaceName(final int node)
    {
        if (_dom != null) {
            return _dom.getNamespaceName(node);
        }
        else {
            return super.getNamespaceName(node);
        }
    }
    
    // Return the expanded type id of a given node
    public int getExpandedTypeID(final int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getExpandedTypeID(nodeHandle);
        }
        else {
            return super.getExpandedTypeID(nodeHandle);
        }
    }
    
    public int getNamespaceType(final int node)
    {
        if (_dom != null) {
            return _dom.getNamespaceType(node);
        }
        else {
            return super.getNamespaceType(node);
        }
    }
    
    public int getParent(final int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getParent(nodeHandle);
        }
        else {
            return super.getParent(nodeHandle);
        }
    }
    
    public int getAttributeNode(final int gType, final int element)
    {
        if (_dom != null) {
            return _dom.getAttributeNode(gType, element);
        }
        else {
            return super.getAttributeNode(gType, element);
        }
    }
    
    public String getStringValueX(final int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getStringValueX(nodeHandle);
        }
        else {
            return super.getStringValueX(nodeHandle);
        }
    }
    
    public void copy(final int node, SerializationHandler handler)
	throws TransletException
    {
        if (_dom != null) {
            _dom.copy(node, handler);
        }
        else {
            super.copy(node, handler);
        }
    }
    
    public void copy(DTMAxisIterator nodes, SerializationHandler handler)
	throws TransletException
    {
        if (_dom != null) {
            _dom.copy(nodes, handler);
        }
        else {
            super.copy(nodes, handler);
        }
    }
    
    public String shallowCopy(final int node, SerializationHandler handler)
	throws TransletException
    {
        if (_dom != null) {
            return _dom.shallowCopy(node, handler);
        }
        else {
            return super.shallowCopy(node, handler);
        }
    }
    
    public boolean lessThan(final int node1, final int node2)
    {
        if (_dom != null) {
            return _dom.lessThan(node1, node2);
        }
        else {
            return super.lessThan(node1, node2);
        }
    }
    
    /**
     * Dispatch the character content of a node to an output handler.
     *
     * The escape setting should be taken care of when outputting to
     * a handler.
     */
    public void characters(final int node, SerializationHandler handler)
	throws TransletException
    {
        if (_dom != null) {
            _dom.characters(node, handler);
        }
        else {
            super.characters(node, handler);
        }        
    }
    
    public Node makeNode(int index)
    {
        if (_dom != null) {
            return _dom.makeNode(index);
        }
        else {
            return super.makeNode(index);
        }        
    }
    
    public Node makeNode(DTMAxisIterator iter)
    {
        if (_dom != null) {
            return _dom.makeNode(iter);
        }
        else {
            return super.makeNode(iter);
        }        
    }
    
    public NodeList makeNodeList(int index)
    {
        if (_dom != null) {
            return _dom.makeNodeList(index);
        }
        else {
            return super.makeNodeList(index);
        }        
    }
    
    public NodeList makeNodeList(DTMAxisIterator iter)
    {
        if (_dom != null) {
            return _dom.makeNodeList(iter);
        }
        else {
            return super.makeNodeList(iter);
        }        
    }
    
    public String getLanguage(int node)
    {
        if (_dom != null) {
            return _dom.getLanguage(node);
        }
        else {
            return super.getLanguage(node);
        }        
    }
    
    public int getSize()
    {
        if (_dom != null) {
            return _dom.getSize();
        }
        else {
            return super.getSize();
        }        
    }
    
    public String getDocumentURI(int node)
    {
        if (_dom != null) {
            return _dom.getDocumentURI(node);
        }
        else {
            return "adaptive_rtf" + _documentURIIndex++;
        }        
    }
    
    public void setFilter(StripFilter filter)
    {
        if (_dom != null) {
            _dom.setFilter(filter);
        }
        else {
            super.setFilter(filter);
        }        
    }
    
    public void setupMapping(String[] names, String[] uris, int[] types, String[] namespaces)
    {
        if (_dom != null) {
            _dom.setupMapping(names, uris, types, namespaces);
        }
        else {
            super.setupMapping(names, uris, types, namespaces);
        }        
    }
    
    public boolean isElement(final int node)
    {
        if (_dom != null) {
            return _dom.isElement(node);
        }
        else {
            return super.isElement(node);
        }        
    }
    
    public boolean isAttribute(final int node)
    {
        if (_dom != null) {
            return _dom.isAttribute(node);
        }
        else {
            return super.isAttribute(node);
        }        
    }
    
    public String lookupNamespace(int node, String prefix)
	throws TransletException
    {
        if (_dom != null) {
            return _dom.lookupNamespace(node, prefix);
        }
        else {
            return super.lookupNamespace(node, prefix);
        }        
    }
    
    /**
     * Return the node identity from a node handle.
     */
    public final int getNodeIdent(final int nodehandle)
    {
        if (_dom != null) {
            return _dom.getNodeIdent(nodehandle);
        }
        else {
            return super.getNodeIdent(nodehandle);
        }        
    }
    
    /**
     * Return the node handle from a node identity.
     */
    public final int getNodeHandle(final int nodeId)
    {
        if (_dom != null) {
            return _dom.getNodeHandle(nodeId);
        }
        else {
            return super.getNodeHandle(nodeId);
        }        
    }
    
    public DOM getResultTreeFrag(int initialSize, int rtfType)
    {
        if (_dom != null) {
            return _dom.getResultTreeFrag(initialSize, rtfType);
        }
        else {
            return super.getResultTreeFrag(initialSize, rtfType);
        }        
    }
    
    public SerializationHandler getOutputDomBuilder()
    {
        return this;
    }
    
    public int getNSType(int node)
    {
        if (_dom != null) {
            return _dom.getNSType(node);
        }
        else {
            return super.getNSType(node);
        }        
    }
    
    public String getUnparsedEntityURI(String name)
    {
        if (_dom != null) {
            return _dom.getUnparsedEntityURI(name);
        }
        else {
            return super.getUnparsedEntityURI(name);
        }        
    }
    
    public Hashtable getElementsWithIDs()
    {
        if (_dom != null) {
            return _dom.getElementsWithIDs();
        }
        else {
            return super.getElementsWithIDs();
        }        
    }

    /** Implementation of the SerializationHandler interfaces **/
        
    /** The code in some of the following interfaces are copied from SAXAdapter. **/
    
    private void maybeEmitStartElement() throws SAXException
    {
	if (_openElementName != null) {

	   int index;
	   if ((index =_openElementName.indexOf(":")) < 0)
	       _dom.startElement(null, _openElementName, _openElementName, _attributes);
	   else
	       _dom.startElement(null, _openElementName.substring(index+1), _openElementName, _attributes);


	    _openElementName = null;
	}
    }
    
    // Create and initialize the wrapped SAXImpl object
    private void prepareNewDOM() throws SAXException
    {
        _dom = (SAXImpl)_dtmManager.getDTM(null, true, _wsfilter,
                                  true, false, false,
                                  _initSize, _buildIdIndex);
        _dom.startDocument();
        // Flush pending Text nodes to SAXImpl
        for (int i = 0; i < _size; i++) {
            String str = _textArray[i];
            _dom.characters(str.toCharArray(), 0, str.length());
        }
        _size = 0;
    }
    
    public void startDocument() throws SAXException
    {    
    }
    
    public void endDocument() throws SAXException
    {
        if (_dom != null) {
            _dom.endDocument();
        }
        else {
            super.endDocument();
        }
    }

    public void characters(String str) throws SAXException
    {
        if (_dom != null) {
            characters(str.toCharArray(), 0, str.length());
        }
        else {
            super.characters(str);
        }
    }
    
    public void characters(char[] ch, int offset, int length)
	throws SAXException
    {
        if (_dom != null) {
	    maybeEmitStartElement();
	    _dom.characters(ch, offset, length);
        }
        else {
            super.characters(ch, offset, length);
        }
    }
    
    public boolean setEscaping(boolean escape) throws SAXException
    {
        if (_dom != null) {
            return _dom.setEscaping(escape);
        }
        else {
            return super.setEscaping(escape);
        }
    }
    
    public void startElement(String elementName) throws SAXException
    {
        if (_dom == null) {
            prepareNewDOM();
        }
        	   	    
	maybeEmitStartElement();
	_openElementName = elementName;
	_attributes.clear();
    }

    public void startElement(String uri, String localName, String qName)
        throws SAXException
    {
        startElement(qName);
    }

    public void startElement(String uri, String localName, String qName, Attributes attributes)
        throws SAXException
    {
        startElement(qName);
    }
    
    public void endElement(String elementName) throws SAXException
    {    
	maybeEmitStartElement();
	_dom.endElement(null, null, elementName);
    }

    public void endElement(String uri, String localName, String qName)
        throws SAXException
    {
        endElement(qName);
    }

 public void addUniqueAttribute(String qName, String value, int flags)
        throws SAXException
    {
        addAttribute(qName, value); 
    }

    public void addAttribute(String name, String value)
    {    
	if (_openElementName != null) {
	    _attributes.add(name, value);
	}
	else {
	    BasisLibrary.runTimeError(BasisLibrary.STRAY_ATTRIBUTE_ERR, name);
	}
    }

    public void namespaceAfterStartElement(String prefix, String uri)
        throws SAXException
    {    
	if (_dom == null) {
	   prepareNewDOM(); 
	}
	
	_dom.startPrefixMapping(prefix, uri);
    }
    
    public void comment(String comment) throws SAXException
    {    
	if (_dom == null) {
	   prepareNewDOM(); 
	}
	
	maybeEmitStartElement();
        char[] chars = comment.toCharArray();
        _dom.comment(chars, 0, chars.length);
    }

    public void comment(char[] chars, int offset, int length)
        throws SAXException
    {    
	if (_dom == null) {
	   prepareNewDOM(); 
	}
	
	maybeEmitStartElement();
        _dom.comment(chars, offset, length);
    }
    
    public void processingInstruction(String target, String data)
	throws SAXException
    {    
	if (_dom == null) {
	   prepareNewDOM(); 
	}
	
	maybeEmitStartElement();
	_dom.processingInstruction(target, data);
    }
    
    /** Implementation of the DTM interfaces **/
         
    public void setFeature(String featureId, boolean state)
    {
        if (_dom != null) {
            _dom.setFeature(featureId, state);
        }
    }
    
    public void setProperty(String property, Object value)
    {
        if (_dom != null) {
            _dom.setProperty(property, value);
        }
    }
    
    public DTMAxisTraverser getAxisTraverser(final int axis)
    {
        if (_dom != null) {
            return _dom.getAxisTraverser(axis);
        }
        else {
            return super.getAxisTraverser(axis);
        }
    }
    
    public boolean hasChildNodes(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.hasChildNodes(nodeHandle);
        }
        else {
            return super.hasChildNodes(nodeHandle);
        }
    }
    
    public int getFirstChild(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getFirstChild(nodeHandle);
        }
        else {
            return super.getFirstChild(nodeHandle);
        }
    }
    
    public int getLastChild(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getLastChild(nodeHandle);
        }
        else {
            return super.getLastChild(nodeHandle);
        }
    }
    
    public int getAttributeNode(int elementHandle, String namespaceURI, String name)
    {
        if (_dom != null) {
            return _dom.getAttributeNode(elementHandle, namespaceURI, name);
        }
        else {
            return super.getAttributeNode(elementHandle, namespaceURI, name);
        }
    }
    
    public int getFirstAttribute(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getFirstAttribute(nodeHandle);
        }
        else {
            return super.getFirstAttribute(nodeHandle);
        }
    }
    
    public int getFirstNamespaceNode(int nodeHandle, boolean inScope)
    {
        if (_dom != null) {
            return _dom.getFirstNamespaceNode(nodeHandle, inScope);
        }
        else {
            return super.getFirstNamespaceNode(nodeHandle, inScope);
        }
    }
    
    public int getNextSibling(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getNextSibling(nodeHandle);
        }
        else {
            return super.getNextSibling(nodeHandle);
        }
     }
    
    public int getPreviousSibling(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getPreviousSibling(nodeHandle);
        }
        else {
            return super.getPreviousSibling(nodeHandle);
        }
     }
    
    public int getNextAttribute(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getNextAttribute(nodeHandle);
        }
        else {
            return super.getNextAttribute(nodeHandle);
        }
    }
    
    public int getNextNamespaceNode(int baseHandle, int namespaceHandle,
                                  boolean inScope)
    {
        if (_dom != null) {
            return _dom.getNextNamespaceNode(baseHandle, namespaceHandle, inScope);
        }
        else {
            return super.getNextNamespaceNode(baseHandle, namespaceHandle, inScope);
        }
    }
    
    public int getOwnerDocument(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getOwnerDocument(nodeHandle);
        }
        else {
            return super.getOwnerDocument(nodeHandle);
        }
    }
    
    public int getDocumentRoot(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getDocumentRoot(nodeHandle);
        }
        else {
            return super.getDocumentRoot(nodeHandle);
        }
    }
    
    public XMLString getStringValue(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getStringValue(nodeHandle);
        }
        else {
            return super.getStringValue(nodeHandle);
        }
    }
    
    public int getStringValueChunkCount(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getStringValueChunkCount(nodeHandle);
        }
        else {
            return super.getStringValueChunkCount(nodeHandle);
        }
    }
    
    public char[] getStringValueChunk(int nodeHandle, int chunkIndex,
                                    int[] startAndLen)
    {
        if (_dom != null) {
            return _dom.getStringValueChunk(nodeHandle, chunkIndex, startAndLen);
        }
        else {
            return super.getStringValueChunk(nodeHandle, chunkIndex, startAndLen);
        }
    }
    
    public int getExpandedTypeID(String namespace, String localName, int type)
    {
        if (_dom != null) {
            return _dom.getExpandedTypeID(namespace, localName, type);
        }
        else {
            return super.getExpandedTypeID(namespace, localName, type);
        }
    }
    
    public String getLocalNameFromExpandedNameID(int ExpandedNameID)
    {
        if (_dom != null) {
            return _dom.getLocalNameFromExpandedNameID(ExpandedNameID);
        }
        else {
            return super.getLocalNameFromExpandedNameID(ExpandedNameID);
        }
    }
    
    public String getNamespaceFromExpandedNameID(int ExpandedNameID)
    {
        if (_dom != null) {
            return _dom.getNamespaceFromExpandedNameID(ExpandedNameID);
        }
        else {
            return super.getNamespaceFromExpandedNameID(ExpandedNameID);
        }
    }
    
    public String getLocalName(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getLocalName(nodeHandle);
        }
        else {
            return super.getLocalName(nodeHandle);
        }
    }
    
    public String getPrefix(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getPrefix(nodeHandle);
        }
        else {
            return super.getPrefix(nodeHandle);
        }
    }
    
    public String getNamespaceURI(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getNamespaceURI(nodeHandle);
        }
        else {
            return super.getNamespaceURI(nodeHandle);
        }
    }
    
    public String getNodeValue(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getNodeValue(nodeHandle);
        }
        else {
            return super.getNodeValue(nodeHandle);
        }
    }
    
    public short getNodeType(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getNodeType(nodeHandle);
        }
        else {
            return super.getNodeType(nodeHandle);
        }
    }
    
    public short getLevel(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getLevel(nodeHandle);
        }
        else {
            return super.getLevel(nodeHandle);
        }
    }
    
    public boolean isSupported(String feature, String version)
    {
        if (_dom != null) {
            return _dom.isSupported(feature, version);
        }
        else {
            return super.isSupported(feature, version);
        }
    }
    
    public String getDocumentBaseURI()
    {
        if (_dom != null) {
            return _dom.getDocumentBaseURI();
        }
        else {
            return super.getDocumentBaseURI();
        }
    }
    
    public void setDocumentBaseURI(String baseURI)
    {
        if (_dom != null) {
            _dom.setDocumentBaseURI(baseURI);
        }
        else {
            super.setDocumentBaseURI(baseURI);
        }
    }
    
    public String getDocumentSystemIdentifier(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getDocumentSystemIdentifier(nodeHandle);
        }
        else {
            return super.getDocumentSystemIdentifier(nodeHandle);
        }
    }
    
    public String getDocumentEncoding(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getDocumentEncoding(nodeHandle);
        }
        else {
            return super.getDocumentEncoding(nodeHandle);
        }
    }
    
    public String getDocumentStandalone(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getDocumentStandalone(nodeHandle);
        }
        else {
            return super.getDocumentStandalone(nodeHandle);
        }
    }
    
    public String getDocumentVersion(int documentHandle)
    {
        if (_dom != null) {
            return _dom.getDocumentVersion(documentHandle);
        }
        else {
            return super.getDocumentVersion(documentHandle);
        }
    }
    
    public boolean getDocumentAllDeclarationsProcessed()
    {
        if (_dom != null) {
            return _dom.getDocumentAllDeclarationsProcessed();
        }
        else {
            return super.getDocumentAllDeclarationsProcessed();
        }
    }
    
    public String getDocumentTypeDeclarationSystemIdentifier()
    {
        if (_dom != null) {
            return _dom.getDocumentTypeDeclarationSystemIdentifier();
        }
        else {
            return super.getDocumentTypeDeclarationSystemIdentifier();
        }
    }
    
    public String getDocumentTypeDeclarationPublicIdentifier()
    {
        if (_dom != null) {
            return _dom.getDocumentTypeDeclarationPublicIdentifier();
        }
        else {
            return super.getDocumentTypeDeclarationPublicIdentifier();
        }
    }
    
    public int getElementById(String elementId)
    {
        if (_dom != null) {
            return _dom.getElementById(elementId);
        }
        else {
            return super.getElementById(elementId);
        }
    }
        
    public boolean supportsPreStripping()
    {
        if (_dom != null) {
            return _dom.supportsPreStripping();
        }
        else {
            return super.supportsPreStripping();
        }
    }
    
    public boolean isNodeAfter(int firstNodeHandle, int secondNodeHandle)
    {
        if (_dom != null) {
            return _dom.isNodeAfter(firstNodeHandle, secondNodeHandle);
        }
        else {
            return super.isNodeAfter(firstNodeHandle, secondNodeHandle);
        }
    }
    
    public boolean isCharacterElementContentWhitespace(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.isCharacterElementContentWhitespace(nodeHandle);
        }
        else {
            return super.isCharacterElementContentWhitespace(nodeHandle);
        }
    }
    
    public boolean isDocumentAllDeclarationsProcessed(int documentHandle)
    {
        if (_dom != null) {
            return _dom.isDocumentAllDeclarationsProcessed(documentHandle);
        }
        else {
            return super.isDocumentAllDeclarationsProcessed(documentHandle);
        }
    }
    
    public boolean isAttributeSpecified(int attributeHandle)
    {
        if (_dom != null) {
            return _dom.isAttributeSpecified(attributeHandle);
        }
        else {
            return super.isAttributeSpecified(attributeHandle);
        }
    }
    
    public void dispatchCharactersEvents(int nodeHandle, org.xml.sax.ContentHandler ch,
                                         boolean normalize)
          throws org.xml.sax.SAXException
    {
        if (_dom != null) {
            _dom.dispatchCharactersEvents(nodeHandle,  ch, normalize);
        }
        else {
            super.dispatchCharactersEvents(nodeHandle, ch, normalize);
        }
    }
    
    public void dispatchToEvents(int nodeHandle, org.xml.sax.ContentHandler ch)
      throws org.xml.sax.SAXException
    {
        if (_dom != null) {
            _dom.dispatchToEvents(nodeHandle,  ch);
        }
        else {
            super.dispatchToEvents(nodeHandle, ch);
        }
    }
    
    public org.w3c.dom.Node getNode(int nodeHandle)
    {
        if (_dom != null) {
            return _dom.getNode(nodeHandle);
        }
        else {
            return super.getNode(nodeHandle);
        }
    }
    
    public boolean needsTwoThreads()
    {
        if (_dom != null) {
            return _dom.needsTwoThreads();
        }
        else {
            return super.needsTwoThreads();
        }
    }
    
    public org.xml.sax.ContentHandler getContentHandler()
    {
        if (_dom != null) {
            return _dom.getContentHandler();
        }
        else {
            return super.getContentHandler();
        }
    }
    
    public org.xml.sax.ext.LexicalHandler getLexicalHandler()
    {
        if (_dom != null) {
            return _dom.getLexicalHandler();
        }
        else {
            return super.getLexicalHandler();
        }
    }
    
    public org.xml.sax.EntityResolver getEntityResolver()
    {
        if (_dom != null) {
            return _dom.getEntityResolver();
        }
        else {
            return super.getEntityResolver();
        }
    }
    
    public org.xml.sax.DTDHandler getDTDHandler()
    {
        if (_dom != null) {
            return _dom.getDTDHandler();
        }
        else {
            return super.getDTDHandler();
        }
    }
    
    public org.xml.sax.ErrorHandler getErrorHandler()
    {
        if (_dom != null) {
            return _dom.getErrorHandler();
        }
        else {
            return super.getErrorHandler();
        }
    }
    
    public org.xml.sax.ext.DeclHandler getDeclHandler()
    {
        if (_dom != null) {
            return _dom.getDeclHandler();
        }
        else {
            return super.getDeclHandler();
        }
    }
    
    public void appendChild(int newChild, boolean clone, boolean cloneDepth)
    {
        if (_dom != null) {
            _dom.appendChild(newChild, clone, cloneDepth);
        }
        else {
            super.appendChild(newChild, clone, cloneDepth);
        }
    }
    
    public void appendTextChild(String str)
    {
        if (_dom != null) {
            _dom.appendTextChild(str);
        }
        else {
            super.appendTextChild(str);
        }
    }
    
    public SourceLocator getSourceLocatorFor(int node)
    {
        if (_dom != null) {
            return _dom.getSourceLocatorFor(node);
        }
        else {
            return super.getSourceLocatorFor(node);
        }
    }
    
    public void documentRegistration()
    {
        if (_dom != null) {
            _dom.documentRegistration();
        }
        else {
            super.documentRegistration();
        }
    }
    
    public void documentRelease()
    {
        if (_dom != null) {
            _dom.documentRelease();
        }
        else {
            super.documentRelease();
        }
    }

}
