/*
 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
 */
/*
 * 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: SimpleResultTreeImpl.java,v 1.2.4.1 2005/09/06 10:09:25 pvedula Exp $
 */
package com.sun.org.apache.xalan.internal.xsltc.dom;

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.StripFilter;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xml.internal.dtm.Axis;
import com.sun.org.apache.xml.internal.dtm.DTM;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.dtm.DTMAxisTraverser;
import com.sun.org.apache.xml.internal.dtm.DTMManager;
import com.sun.org.apache.xml.internal.dtm.ref.DTMAxisIteratorBase;
import com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault;
import com.sun.org.apache.xml.internal.serializer.EmptySerializer;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import com.sun.org.apache.xml.internal.utils.XMLString;
import com.sun.org.apache.xml.internal.utils.XMLStringDefault;
import java.util.Map;
import javax.xml.transform.SourceLocator;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * This class represents a light-weight DOM model for simple result tree fragment(RTF).
 * A simple RTF is an RTF that has only one Text node. The Text node can be produced by a
 * combination of Text, xsl:value-of and xsl:number instructions. It can also be produced
 * by a control structure (xsl:if or xsl:choose) whose body is pure Text.
 * <p>
 * A SimpleResultTreeImpl has only two nodes, i.e. the ROOT node and its Text child. All DOM
 * interfaces are overridden with this in mind. For example, the getStringValue() interface
 * returns the value of the Text node. This class receives the character data from the
 * characters() interface.
 * <p>
 * This class implements DOM and SerializationHandler. It also implements the DTM interface
 * for support in MultiDOM. The nested iterators (SimpleIterator and SingletonIterator) are
 * used to support the nodeset() extension function.
 */
public class SimpleResultTreeImpl extends EmptySerializer implements DOM, DTM
{

    /**
     * The SimpleIterator is designed to support the nodeset() extension function. It has
     * a traversal direction parameter. The DOWN direction is used for child and descendant
     * axes, while the UP direction is used for parent and ancestor axes.
     *
     * This iterator only handles two nodes (RTF_ROOT and RTF_TEXT). If the type is set,
     * it will also match the node type with the given type.
     */
    public final class SimpleIterator extends DTMAxisIteratorBase
    {
        static final int DIRECTION_UP = 0;
        static final int DIRECTION_DOWN = 1;
        static final int NO_TYPE = -1;

        // The direction of traversal (default to DOWN).
        // DOWN is for child and descendant. UP is for parent and ancestor.
        int _direction = DIRECTION_DOWN;

        int _type = NO_TYPE;
        int _currentNode;

        public SimpleIterator()
        {
        }

        public SimpleIterator(int direction)
        {
            _direction = direction;
        }

        public SimpleIterator(int direction, int type)
        {
             _direction = direction;
             _type = type;
        }

        public int next()
        {
            // Increase the node ID for down traversal. Also match the node type
            // if the type is given.
            if (_direction == DIRECTION_DOWN) {
                while (_currentNode < NUMBER_OF_NODES) {
                    if (_type != NO_TYPE) {
                        if ((_currentNode == RTF_ROOT && _type == DTM.ROOT_NODE)
                            || (_currentNode == RTF_TEXT && _type == DTM.TEXT_NODE))
                            return returnNode(getNodeHandle(_currentNode++));
                        else
                            _currentNode++;
                    }
                    else
                        return returnNode(getNodeHandle(_currentNode++));
                }

                return END;
            }
            // Decrease the node ID for up traversal.
            else {
                while (_currentNode >= 0) {
                    if (_type != NO_TYPE) {
                        if ((_currentNode == RTF_ROOT && _type == DTM.ROOT_NODE)
                            || (_currentNode == RTF_TEXT && _type == DTM.TEXT_NODE))
                            return returnNode(getNodeHandle(_currentNode--));
                        else
                            _currentNode--;
                    }
                    else
                        return returnNode(getNodeHandle(_currentNode--));
                }

                return END;
            }
        }

        public DTMAxisIterator setStartNode(int nodeHandle)
        {
            int nodeID = getNodeIdent(nodeHandle);
            _startNode = nodeID;

            // Increase the node ID by 1 if self is not included.
            if (!_includeSelf && nodeID != DTM.NULL) {
                if (_direction == DIRECTION_DOWN)
                    nodeID++;
                else if (_direction == DIRECTION_UP)
                    nodeID--;
            }

            _currentNode = nodeID;
            return this;
        }

        public void setMark()
        {
            _markedNode = _currentNode;
        }

        public void gotoMark()
        {
            _currentNode = _markedNode;
        }

    } // END of SimpleIterator

    /**
     * The SingletonIterator is used for the self axis.
     */
    public final class SingletonIterator extends DTMAxisIteratorBase
    {
        static final int NO_TYPE = -1;
        int _type = NO_TYPE;
        int _currentNode;

        public SingletonIterator()
        {
        }

        public SingletonIterator(int type)
        {
            _type = type;
        }

        public void setMark()
        {
            _markedNode = _currentNode;
        }

        public void gotoMark()
        {
            _currentNode = _markedNode;
        }

        public DTMAxisIterator setStartNode(int nodeHandle)
        {
            _currentNode = _startNode = getNodeIdent(nodeHandle);
            return this;
        }

        public int next()
        {
            if (_currentNode == END)
                return END;

            _currentNode = END;

            if (_type != NO_TYPE) {
                if ((_currentNode == RTF_ROOT && _type == DTM.ROOT_NODE)
                    || (_currentNode == RTF_TEXT && _type == DTM.TEXT_NODE))
                    return getNodeHandle(_currentNode);
            }
            else
                return getNodeHandle(_currentNode);

            return END;
        }

    }  // END of SingletonIterator

    // empty iterator to be returned when there are no children
    private final static DTMAxisIterator EMPTY_ITERATOR =
        new DTMAxisIteratorBase() {
            public DTMAxisIterator reset() { return this; }
            public DTMAxisIterator setStartNode(int node) { return this; }
            public int next() { return DTM.NULL; }
            public void setMark() {}
            public void gotoMark() {}
            public int getLast() { return 0; }
            public int getPosition() { return 0; }
            public DTMAxisIterator cloneIterator() { return this; }
            public void setRestartable(boolean isRestartable) { }
        };


    // The root node id of the simple RTF
    public static final int RTF_ROOT = 0;

    // The Text node id of the simple RTF (simple RTF has only one Text node).
    public static final int RTF_TEXT = 1;

    // The number of nodes.
    public static final int NUMBER_OF_NODES = 2;

    // Document URI index, which increases by 1 at each getDocumentURI() call.
    private static int _documentURIIndex = 0;

    // Constant for empty String
    private static final String EMPTY_STR = "";

    // The String value of the Text node.
    // This is set at the endDocument() call.
    private String _text;

    // The array of Text items, which is built by the characters() call.
    // The characters() interface can be called multiple times. Each character item
    // can have different escape settings.
    protected String[] _textArray;

    // The DTMManager
    protected XSLTCDTMManager _dtmManager;

    // Number of character items
    protected int _size = 0;

    // The document ID
    private int _documentID;

    // A BitArray, each bit holding the escape setting for a character item.
    private BitArray _dontEscape = null;

    // The current escape setting
    private boolean _escaping = true;

    // Create a SimpleResultTreeImpl from a DTMManager and a document ID.
    public SimpleResultTreeImpl(XSLTCDTMManager dtmManager, int documentID)
    {
        _dtmManager = dtmManager;
        _documentID = documentID;
        _textArray = new String[4];
    }

    public DTMManagerDefault getDTMManager()
    {
        return _dtmManager;
    }

    // Return the document ID
    public int getDocument()
    {
        return _documentID;
    }

    // Return the String value of the RTF
    public String getStringValue()
    {
        return _text;
    }

    public DTMAxisIterator getIterator()
    {
        return new SingletonIterator(getDocument());
    }

    public DTMAxisIterator getChildren(final int node)
    {
        return new SimpleIterator().setStartNode(node);
    }

    public DTMAxisIterator getTypedChildren(final int type)
    {
        return new SimpleIterator(SimpleIterator.DIRECTION_DOWN, type);
    }

    // Return the axis iterator for a given axis.
    // The SimpleIterator is used for the child, descendant, parent and ancestor axes.
    public DTMAxisIterator getAxisIterator(final int axis)
    {
        switch (axis)
        {
            case Axis.CHILD:
            case Axis.DESCENDANT:
                return new SimpleIterator(SimpleIterator.DIRECTION_DOWN);
            case Axis.PARENT:
            case Axis.ANCESTOR:
                return new SimpleIterator(SimpleIterator.DIRECTION_UP);
            case Axis.ANCESTORORSELF:
                return (new SimpleIterator(SimpleIterator.DIRECTION_UP)).includeSelf();
            case Axis.DESCENDANTORSELF:
                return (new SimpleIterator(SimpleIterator.DIRECTION_DOWN)).includeSelf();
            case Axis.SELF:
                return new SingletonIterator();
            default:
                return EMPTY_ITERATOR;
        }
    }

    public DTMAxisIterator getTypedAxisIterator(final int axis, final int type)
    {
        switch (axis)
        {
            case Axis.CHILD:
            case Axis.DESCENDANT:
                return new SimpleIterator(SimpleIterator.DIRECTION_DOWN, type);
            case Axis.PARENT:
            case Axis.ANCESTOR:
                return new SimpleIterator(SimpleIterator.DIRECTION_UP, type);
            case Axis.ANCESTORORSELF:
                return (new SimpleIterator(SimpleIterator.DIRECTION_UP, type)).includeSelf();
            case Axis.DESCENDANTORSELF:
                return (new SimpleIterator(SimpleIterator.DIRECTION_DOWN, type)).includeSelf();
            case Axis.SELF:
                return new SingletonIterator(type);
            default:
                return EMPTY_ITERATOR;
        }
    }

    // %REVISIT% Can this one ever get used?
    public DTMAxisIterator getNthDescendant(int node, int n, boolean includeself)
    {
        return null;
    }

    public DTMAxisIterator getNamespaceAxisIterator(final int axis, final int ns)
    {
        return null;
    }

    // %REVISIT% Can this one ever get used?
    public DTMAxisIterator getNodeValueIterator(DTMAxisIterator iter, int returnType,
                                             String value, boolean op)
    {
        return null;
    }

    public DTMAxisIterator orderNodes(DTMAxisIterator source, int node)
    {
        return source;
    }

    public String getNodeName(final int node)
    {
        if (getNodeIdent(node) == RTF_TEXT)
            return "#text";
        else
            return EMPTY_STR;
    }

    public String getNodeNameX(final int node)
    {
        return EMPTY_STR;
    }

    public String getNamespaceName(final int node)
    {
        return EMPTY_STR;
    }

    // Return the expanded type id of a given node
    public int getExpandedTypeID(final int nodeHandle)
    {
        int nodeID = getNodeIdent(nodeHandle);
        if (nodeID == RTF_TEXT)
            return DTM.TEXT_NODE;
        else if (nodeID == RTF_ROOT)
            return DTM.ROOT_NODE;
        else
            return DTM.NULL;
    }

    public int getNamespaceType(final int node)
    {
        return 0;
    }

    public int getParent(final int nodeHandle)
    {
        int nodeID = getNodeIdent(nodeHandle);
        return (nodeID == RTF_TEXT) ? getNodeHandle(RTF_ROOT) : DTM.NULL;
    }

    public int getAttributeNode(final int gType, final int element)
    {
        return DTM.NULL;
    }

    public String getStringValueX(final int nodeHandle)
    {
        int nodeID = getNodeIdent(nodeHandle);
        if (nodeID == RTF_ROOT || nodeID == RTF_TEXT)
            return _text;
        else
            return EMPTY_STR;
    }

    public void copy(final int node, SerializationHandler handler)
        throws TransletException
    {
        characters(node, handler);
    }

    public void copy(DTMAxisIterator nodes, SerializationHandler handler)
        throws TransletException
    {
        int node;
        while ((node = nodes.next()) != DTM.NULL)
        {
            copy(node, handler);
        }
    }

    public String shallowCopy(final int node, SerializationHandler handler)
        throws TransletException
    {
        characters(node, handler);
        return null;
    }

    public boolean lessThan(final int node1, final int node2)
    {
        if (node1 == DTM.NULL) {
            return false;
        }
        else if (node2 == DTM.NULL) {
            return true;
        }
        else
            return (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
    {
        int nodeID = getNodeIdent(node);
        if (nodeID == RTF_ROOT || nodeID == RTF_TEXT) {
            boolean escapeBit = false;
            boolean oldEscapeSetting = false;

            try {
                for (int i = 0; i < _size; i++) {

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

                    handler.characters(_textArray[i]);

                    if (escapeBit) {
                        handler.setEscaping(oldEscapeSetting);
                    }
                }
            } catch (SAXException e) {
                throw new TransletException(e);
            }
        }
    }

    // %REVISIT% Can the makeNode() and makeNodeList() interfaces ever get used?
    public Node makeNode(int index)
    {
        return null;
    }

    public Node makeNode(DTMAxisIterator iter)
    {
        return null;
    }

    public NodeList makeNodeList(int index)
    {
        return null;
    }

    public NodeList makeNodeList(DTMAxisIterator iter)
    {
        return null;
    }

    public String getLanguage(int node)
    {
        return null;
    }

    public int getSize()
    {
        return 2;
    }

    public String getDocumentURI(int node)
    {
        return "simple_rtf" + _documentURIIndex++;
    }

    public void setFilter(StripFilter filter)
    {
    }

    public void setupMapping(String[] names, String[] uris, int[] types, String[] namespaces)
    {
    }

    public boolean isElement(final int node)
    {
        return false;
    }

    public boolean isAttribute(final int node)
    {
        return false;
    }

    public String lookupNamespace(int node, String prefix)
        throws TransletException
    {
        return null;
    }

    /**
     * Return the node identity from a node handle.
     */
    public int getNodeIdent(final int nodehandle)
    {
        return (nodehandle != DTM.NULL) ? (nodehandle - _documentID) : DTM.NULL;
    }

    /**
     * Return the node handle from a node identity.
     */
    public int getNodeHandle(final int nodeId)
    {
        return (nodeId != DTM.NULL) ? (nodeId + _documentID) : DTM.NULL;
    }

    public DOM getResultTreeFrag(int initialSize, int rtfType)
    {
        return null;
    }

    public DOM getResultTreeFrag(int initialSize, int rtfType, boolean addToManager)
    {
        return null;
    }

    public SerializationHandler getOutputDomBuilder()
    {
        return this;
    }

    public int getNSType(int node)
    {
        return 0;
    }

    public String getUnparsedEntityURI(String name)
    {
        return null;
    }

    public Map<String, Integer> getElementsWithIDs()
    {
        return null;
    }

    /** Implementation of the SerializationHandler interfaces **/

    /**
     * We only need to override the endDocument, characters, and
     * setEscaping interfaces. A simple RTF does not have element
     * nodes. We do not need to touch startElement and endElement.
     */

    public void startDocument() throws SAXException
    {

    }

    public void endDocument() throws SAXException
    {
        // Set the String value when the document is built.
        if (_size == 1)
            _text = _textArray[0];
        else {
            StringBuffer buffer = new StringBuffer();
            for (int i = 0; i < _size; i++) {
                buffer.append(_textArray[i]);
            }
            _text = buffer.toString();
        }
    }

    public void characters(String str) throws SAXException
    {
        // Resize the text array if necessary
        if (_size >= _textArray.length) {
            String[] newTextArray = new String[_textArray.length * 2];
            System.arraycopy(_textArray, 0, newTextArray, 0, _textArray.length);
            _textArray = newTextArray;
        }

        // If the escape setting is false, set the corresponding bit in
        // the _dontEscape BitArray.
        if (!_escaping) {
            // The _dontEscape array is only created when needed.
            if (_dontEscape == null) {
                _dontEscape = new BitArray(8);
            }

            // Resize the _dontEscape array if necessary
            if (_size >= _dontEscape.size())
                _dontEscape.resize(_dontEscape.size() * 2);

            _dontEscape.setBit(_size);
        }

        _textArray[_size++] = str;
    }

    public void characters(char[] ch, int offset, int length)
        throws SAXException
    {
        if (_size >= _textArray.length) {
            String[] newTextArray = new String[_textArray.length * 2];
            System.arraycopy(_textArray, 0, newTextArray, 0, _textArray.length);
            _textArray = newTextArray;
        }

        if (!_escaping) {
            if (_dontEscape == null) {
                _dontEscape = new BitArray(8);
            }

            if (_size >= _dontEscape.size())
                _dontEscape.resize(_dontEscape.size() * 2);

            _dontEscape.setBit(_size);
        }

        _textArray[_size++] = new String(ch, offset, length);

    }

    public boolean setEscaping(boolean escape) throws SAXException
    {
        final boolean temp = _escaping;
        _escaping = escape;
        return temp;
    }

    /** Implementation of the DTM interfaces **/

    /**
     * The DTM interfaces are not used in this class. Implementing the DTM
     * interface is a requirement from MultiDOM. If we have a better way
     * of handling multiple documents, we can get rid of the DTM dependency.
     *
     * The following interfaces are just placeholders. The implementation
     * does not have an impact because they will not be used.
     */

    public void setFeature(String featureId, boolean state)
    {
    }

    public void setProperty(String property, Object value)
    {
    }

    public DTMAxisTraverser getAxisTraverser(final int axis)
    {
        return null;
    }

    public boolean hasChildNodes(int nodeHandle)
    {
        return (getNodeIdent(nodeHandle) == RTF_ROOT);
    }

    public int getFirstChild(int nodeHandle)
    {
        int nodeID = getNodeIdent(nodeHandle);
        if (nodeID == RTF_ROOT)
            return getNodeHandle(RTF_TEXT);
        else
            return DTM.NULL;
    }

    public int getLastChild(int nodeHandle)
    {
        return getFirstChild(nodeHandle);
    }

    public int getAttributeNode(int elementHandle, String namespaceURI, String name)
    {
        return DTM.NULL;
    }

    public int getFirstAttribute(int nodeHandle)
    {
        return DTM.NULL;
    }

    public int getFirstNamespaceNode(int nodeHandle, boolean inScope)
    {
        return DTM.NULL;
    }

    public int getNextSibling(int nodeHandle)
    {
        return DTM.NULL;
    }

    public int getPreviousSibling(int nodeHandle)
    {
        return DTM.NULL;
    }

    public int getNextAttribute(int nodeHandle)
    {
        return DTM.NULL;
    }

    public int getNextNamespaceNode(int baseHandle, int namespaceHandle,
                                  boolean inScope)
    {
        return DTM.NULL;
    }

    public int getOwnerDocument(int nodeHandle)
    {
        return getDocument();
    }

    public int getDocumentRoot(int nodeHandle)
    {
        return getDocument();
    }

    public XMLString getStringValue(int nodeHandle)
    {
        return new XMLStringDefault(getStringValueX(nodeHandle));
    }

    public int getStringValueChunkCount(int nodeHandle)
    {
        return 0;
    }

    public char[] getStringValueChunk(int nodeHandle, int chunkIndex,
                                    int[] startAndLen)
    {
        return null;
    }

    public int getExpandedTypeID(String namespace, String localName, int type)
    {
        return DTM.NULL;
    }

    public String getLocalNameFromExpandedNameID(int ExpandedNameID)
    {
        return EMPTY_STR;
    }

    public String getNamespaceFromExpandedNameID(int ExpandedNameID)
    {
        return EMPTY_STR;
    }

    public String getLocalName(int nodeHandle)
    {
        return EMPTY_STR;
    }

    public String getPrefix(int nodeHandle)
    {
        return null;
    }

    public String getNamespaceURI(int nodeHandle)
    {
        return EMPTY_STR;
    }

    public String getNodeValue(int nodeHandle)
    {
        return (getNodeIdent(nodeHandle) == RTF_TEXT) ? _text : null;
    }

    public short getNodeType(int nodeHandle)
    {
        int nodeID = getNodeIdent(nodeHandle);
        if (nodeID == RTF_TEXT)
            return DTM.TEXT_NODE;
        else if (nodeID == RTF_ROOT)
            return DTM.ROOT_NODE;
        else
            return DTM.NULL;

    }

    public short getLevel(int nodeHandle)
    {
        int nodeID = getNodeIdent(nodeHandle);
        if (nodeID == RTF_TEXT)
            return 2;
        else if (nodeID == RTF_ROOT)
            return 1;
        else
            return DTM.NULL;
    }

    public boolean isSupported(String feature, String version)
    {
        return false;
    }

    public String getDocumentBaseURI()
    {
        return EMPTY_STR;
    }

    public void setDocumentBaseURI(String baseURI)
    {
    }

    public String getDocumentSystemIdentifier(int nodeHandle)
    {
        return null;
    }

    public String getDocumentEncoding(int nodeHandle)
    {
        return null;
    }

    public String getDocumentStandalone(int nodeHandle)
    {
        return null;
    }

    public String getDocumentVersion(int documentHandle)
    {
        return null;
    }

    public boolean getDocumentAllDeclarationsProcessed()
    {
        return false;
    }

    public String getDocumentTypeDeclarationSystemIdentifier()
    {
        return null;
    }

    public String getDocumentTypeDeclarationPublicIdentifier()
    {
        return null;
    }

    public int getElementById(String elementId)
    {
        return DTM.NULL;
    }

    public boolean supportsPreStripping()
    {
        return false;
    }

    public boolean isNodeAfter(int firstNodeHandle, int secondNodeHandle)
    {
        return lessThan(firstNodeHandle, secondNodeHandle);
    }

    public boolean isCharacterElementContentWhitespace(int nodeHandle)
    {
        return false;
    }

    public boolean isDocumentAllDeclarationsProcessed(int documentHandle)
    {
        return false;
    }

    public boolean isAttributeSpecified(int attributeHandle)
    {
        return false;
    }

    public void dispatchCharactersEvents(
        int nodeHandle,
        org.xml.sax.ContentHandler ch,
        boolean normalize)
          throws org.xml.sax.SAXException
    {
    }

    public void dispatchToEvents(int nodeHandle, org.xml.sax.ContentHandler ch)
      throws org.xml.sax.SAXException
    {
    }

    public org.w3c.dom.Node getNode(int nodeHandle)
    {
        return makeNode(nodeHandle);
    }

    public boolean needsTwoThreads()
    {
        return false;
    }

    public org.xml.sax.ContentHandler getContentHandler()
    {
        return null;
    }

    public org.xml.sax.ext.LexicalHandler getLexicalHandler()
    {
        return null;
    }

    public org.xml.sax.EntityResolver getEntityResolver()
    {
        return null;
    }

    public org.xml.sax.DTDHandler getDTDHandler()
    {
        return null;
    }

    public org.xml.sax.ErrorHandler getErrorHandler()
    {
        return null;
    }

    public org.xml.sax.ext.DeclHandler getDeclHandler()
    {
        return null;
    }

    public void appendChild(int newChild, boolean clone, boolean cloneDepth)
    {
    }

    public void appendTextChild(String str)
    {
    }

    public SourceLocator getSourceLocatorFor(int node)
    {
        return null;
    }

    public void documentRegistration()
    {
    }

    public void documentRelease()
    {
    }

    public void migrateTo(DTMManager manager)
    {
    }

    public void release()
    {
        if (_documentID != 0) {
            _dtmManager.release(this, true);
            _documentID = 0;
        }
    }
}
