/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, Lotus
 * Development Corporation., http://www.lotus.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
package org.apache.xml.dtm.ref;

import javax.xml.transform.SourceLocator;

import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMAxisIterator;
import org.apache.xml.dtm.DTMAxisTraverser;
import org.apache.xml.dtm.DTMManager;
import org.apache.xml.dtm.DTMWSFilter;
import org.apache.xml.utils.FastStringBuffer;
import org.apache.xml.utils.XMLString;
import org.apache.xml.utils.XMLStringFactory;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.ext.LexicalHandler;

/**
 * This is the implementation of the DTM document interface.  It receives
 * requests from an XML content handler similar to that of an XML DOM or SAX parser
 * to store information from the xml document in an array based
 * dtm table structure.  This informtion is used later for document navigation,
 * query, and SAX event dispatch functions. The DTM can also be used directly as a
 * document composition model for an application.  The requests received are:
 * <ul>
 * <li>initiating DTM to set the doc handle</li>
 * <li>resetting DTM for data structure reuse</li>
 * <li>hinting the end of document to adjust the end of data structure pointers</li>
 * <li>createnodes (element, comment, text, attribute, ....)</li>
 * <li>hinting the end of an element to patch parent and siblings<li>
 * <li>setting application provided symbol name stringpool data structures</li>
 * </ul>
 * <p>State: In progress!!</p>
 *
 * %REVIEW% I _think_ the SAX convention is that "no namespace" is expressed
 * as "" rather than as null (which is the DOM's convention). What should
 * DTM expect? What should it do with the other?
 *
 * <p>Origin: the implemention is a composite logic based on the DTM of XalanJ1 and
 *     DocImpl, DocumentImpl, ElementImpl, TextImpl, etc. of XalanJ2</p>
 */
public class DTMDocumentImpl
implements DTM, org.xml.sax.ContentHandler, org.xml.sax.ext.LexicalHandler
{

        // Number of lower bits used to represent node index.
        protected static final byte DOCHANDLE_SHIFT = 22;
        // Masks the lower order of node handle.
        // Same as {@link DTMConstructor.IDENT_NODE_DEFAULT}
        protected static final int NODEHANDLE_MASK = (1 << (DOCHANDLE_SHIFT + 1)) - 1;
        // Masks the higher order Document handle
        // Same as {@link DTMConstructor.IDENT_DOC_DEFAULT}
        protected static final int DOCHANDLE_MASK = -1 - NODEHANDLE_MASK;

        int m_docHandle = NULL;		 // masked document handle for this dtm document
        int m_docElement = NULL;	 // nodeHandle to the root of the actual dtm doc content

        // Context for parse-and-append operations
        int currentParent = 0;			// current parent - default is document root
        int previousSibling = 0;		// previous sibling - no previous sibling
        protected int m_currentNode = -1;		// current node

        // The tree under construction can itself be used as
        // the element stack, so m_elemStack isn't needed.
        //protected Stack m_elemStack = new Stack();	 // element stack

        private boolean previousSiblingWasParent = false;
        // Local cache for record-at-a-time fetch
        int gotslot[] = new int[4];

        // endDocument recieved?
        private boolean done = false;
        boolean m_isError = false;

        private final boolean DEBUG = false;

        /** The document base URI. */
        protected String m_documentBaseURI;

  /** If we're building the model incrementally on demand, we need to
   * be able to tell the source when to send us more data.
   *
   * Note that if this has not been set, and you attempt to read ahead
   * of the current build point, we'll probably throw a null-pointer
   * exception. We could try to wait-and-retry instead, as a very poor
   * fallback, but that has all the known problems with multithreading
   * on multiprocessors and we Don't Want to Go There.
   *
   * @see setIncrementalSAXSource
   */
  private IncrementalSAXSource m_incrSAXSource=null;


        // ========= DTM data structure declarations. ==============

        // nodes array: integer array blocks to hold the first level reference of the nodes,
        // each reference slot is addressed by a nodeHandle index value.
        // Assumes indices are not larger than {@link NODEHANDLE_MASK}
        // ({@link DOCHANDLE_SHIFT} bits).
        ChunkedIntArray nodes = new ChunkedIntArray(4);

        // text/comment table: string buffer to hold the text string values of the document,
        // each of which is addressed by the absolute offset and length in the buffer
        private FastStringBuffer m_char = new FastStringBuffer();
        // Start of string currently being accumulated into m_char;
        // needed because the string may be appended in several chunks.
        private int m_char_current_start=0;

        // %TBD% INITIALIZATION/STARTUP ISSUES
        // -- Should we really be creating these, or should they be
        // passed in from outside? Scott want to be able to share
        // pools across multiple documents, so setting them here is
        // probably not the right default.
        private DTMStringPool m_localNames = new DTMStringPool();
        private DTMStringPool m_nsNames = new DTMStringPool();
        private DTMStringPool m_prefixNames = new DTMStringPool();

        // %TBD% If we use the current ExpandedNameTable mapper, it
        // needs to be bound to the NS and local name pools. Which
        // means it needs to attach to them AFTER we've resolved their
        // startup. Or it needs to attach to this document and
        // retrieve them each time. Or this needs to be
        // an interface _implemented_ by this class... which might be simplest!
        private ExpandedNameTable m_expandedNames=
                new ExpandedNameTable();

        private XMLStringFactory m_xsf;


        /**
         * Construct a DTM.
         *
         * @param documentNumber the ID number assigned to this document.
         * It will be shifted up into the high bits and returned as part of
         * all node ID numbers, so those IDs indicate which document they
         * came from as well as a location within the document. It is the
         * DTMManager's responsibility to assign a unique number to each
         * document.
         */
        public DTMDocumentImpl(DTMManager mgr, int documentNumber,
                               DTMWSFilter whiteSpaceFilter,
                               XMLStringFactory xstringfactory){
                initDocument(documentNumber);	 // clear nodes and document handle
                m_xsf = xstringfactory;
        }

  /** Bind a IncrementalSAXSource to this DTM. If we discover we need nodes
   * that have not yet been built, we will ask this object to send us more
   * events, and it will manage interactions with its data sources.
   *
   * Note that we do not actually build the IncrementalSAXSource, since we don't
   * know what source it's reading from, what thread that source will run in,
   * or when it will run.
   *
   * @param source The IncrementalSAXSource that we want to recieve events from
   * on demand.
   */
  public void setIncrementalSAXSource(IncrementalSAXSource source)
  {
    m_incrSAXSource=source;

    // Establish SAX-stream link so we can receive the requested data
    source.setContentHandler(this);
    source.setLexicalHandler(this);

    // Are the following really needed? IncrementalSAXSource doesn't yet
    // support them, and they're mostly no-ops here...
    //source.setErrorHandler(this);
    //source.setDTDHandler(this);
    //source.setDeclHandler(this);
  }

        /**
         * Wrapper for ChunkedIntArray.append, to automatically update the
         * previous sibling's "next" reference (if necessary) and periodically
         * wake a reader who may have encountered incomplete data and entered
         * a wait state.
         * @param w0 int As in ChunkedIntArray.append
         * @param w1 int As in ChunkedIntArray.append
         * @param w2 int As in ChunkedIntArray.append
         * @param w3 int As in ChunkedIntArray.append
         * @return int As in ChunkedIntArray.append
         * @see ChunkedIntArray.append
         */
        private final int appendNode(int w0, int w1, int w2, int w3)
        {
                // A decent compiler may inline this.
                int slotnumber = nodes.appendSlot(w0, w1, w2, w3);

                if (DEBUG) System.out.println(slotnumber+": "+w0+" "+w1+" "+w2+" "+w3);

                if (previousSiblingWasParent)
                        nodes.writeEntry(previousSibling,2,slotnumber);

                previousSiblingWasParent = false;	// Set the default; endElement overrides

                return slotnumber;
        }

        // ========= DTM Implementation Control Functions. ==============

        /**
         * Set an implementation dependent feature.
         * <p>
         * %REVIEW% Do we really expect to set features on DTMs?
         *
         * @param featureId A feature URL.
         * @param state true if this feature should be on, false otherwise.
         */
        public void setFeature(String featureId, boolean state) {};

        /**
         * Set a reference pointer to the element name symbol table.
         * %REVIEW% Should this really be Public? Changing it while
         * DTM is in use would be a disaster.
         *
         * @param poolRef DTMStringPool reference to an instance of table.
         */
        public void setLocalNameTable(DTMStringPool poolRef) {
                m_localNames = poolRef;
        }

        /**
         * Get a reference pointer to the element name symbol table.
         *
         * @return DTMStringPool reference to an instance of table.
         */
        public DTMStringPool getLocalNameTable() {
                 return m_localNames;
         }

        /**
         * Set a reference pointer to the namespace URI symbol table.
         * %REVIEW% Should this really be Public? Changing it while
         * DTM is in use would be a disaster.
         *
         * @param poolRef DTMStringPool reference to an instance of table.
         */
        public void setNsNameTable(DTMStringPool poolRef) {
                m_nsNames = poolRef;
        }

        /**
         * Get a reference pointer to the namespace URI symbol table.
         *
         * @return DTMStringPool reference to an instance of table.
         */
        public DTMStringPool getNsNameTable() {
                 return m_nsNames;
         }

        /**
         * Set a reference pointer to the prefix name symbol table.
         * %REVIEW% Should this really be Public? Changing it while
         * DTM is in use would be a disaster.
         *
         * @param poolRef DTMStringPool reference to an instance of table.
         */
        public void setPrefixNameTable(DTMStringPool poolRef) {
                m_prefixNames = poolRef;
        }

        /**
         * Get a reference pointer to the prefix name symbol table.
         *
         * @return DTMStringPool reference to an instance of table.
         */
        public DTMStringPool getPrefixNameTable() {
                return m_prefixNames;
        }

         /**
          * Set a reference pointer to the content-text repository
          *
          * @param bufferRef FastStringBuffer reference to an instance of
          * buffer
          */
         void setContentBuffer(FastStringBuffer buffer) {
                 m_char = buffer;
         }

         /**
          * Get a reference pointer to the content-text repository
          *
          * @return FastStringBuffer reference to an instance of buffer
          */
         FastStringBuffer getContentBuffer() {
                 return m_char;
         }

  /** getContentHandler returns "our SAX builder" -- the thing that
   * someone else should send SAX events to in order to extend this
   * DTM model.
   *
   * @return null if this model doesn't respond to SAX events,
   * "this" if the DTM object has a built-in SAX ContentHandler,
   * the IncrementalSAXSource if we're bound to one and should receive
   * the SAX stream via it for incremental build purposes...
   * */
  public org.xml.sax.ContentHandler getContentHandler()
  {
    if (m_incrSAXSource instanceof IncrementalSAXSource_Filter)
      return (ContentHandler) m_incrSAXSource;
    else
      return this;
  }

  /**
   * Return this DTM's lexical handler.
   *
   * %REVIEW% Should this return null if constrution already done/begun?
   *
   * @return null if this model doesn't respond to lexical SAX events,
   * "this" if the DTM object has a built-in SAX ContentHandler,
   * the IncrementalSAXSource if we're bound to one and should receive
   * the SAX stream via it for incremental build purposes...
   */
  public LexicalHandler getLexicalHandler()
  {

    if (m_incrSAXSource instanceof IncrementalSAXSource_Filter)
      return (LexicalHandler) m_incrSAXSource;
    else
      return this;
  }

  /**
   * Return this DTM's EntityResolver.
   *
   * @return null if this model doesn't respond to SAX entity ref events.
   */
  public org.xml.sax.EntityResolver getEntityResolver()
  {

    return null;
  }

  /**
   * Return this DTM's DTDHandler.
   *
   * @return null if this model doesn't respond to SAX dtd events.
   */
  public org.xml.sax.DTDHandler getDTDHandler()
  {

    return null;
  }

  /**
   * Return this DTM's ErrorHandler.
   *
   * @return null if this model doesn't respond to SAX error events.
   */
  public org.xml.sax.ErrorHandler getErrorHandler()
  {

    return null;
  }

  /**
   * Return this DTM's DeclHandler.
   *
   * @return null if this model doesn't respond to SAX Decl events.
   */
  public org.xml.sax.ext.DeclHandler getDeclHandler()
  {

    return null;
  }

  /** @return true iff we're building this model incrementally (eg
   * we're partnered with a IncrementalSAXSource) and thus require that the
   * transformation and the parse run simultaneously. Guidance to the
   * DTMManager.
   * */
  public boolean needsTwoThreads()
  {
    return null!=m_incrSAXSource;
  }

  //================================================================
  // ========= SAX2 ContentHandler methods =========
  // Accept SAX events, use them to build/extend the DTM tree.
  // Replaces the deprecated DocumentHandler interface.

  public void characters(char[] ch, int start, int length)
       throws org.xml.sax.SAXException
  {
    // Actually creating the text node is handled by
    // processAccumulatedText(); here we just accumulate the
    // characters into the buffer.
    m_char.append(ch,start,length);
  }

  // Flush string accumulation into a text node
  private void processAccumulatedText()
  {
    int len=m_char.length();
    if(len!=m_char_current_start)
      {
        // The FastStringBuffer has been previously agreed upon
        appendTextChild(m_char_current_start,len-m_char_current_start);
        m_char_current_start=len;
      }
  }
  public void endDocument()
       throws org.xml.sax.SAXException
  {
    // May need to tell the low-level builder code to pop up a level.
    // There _should't_ be any significant pending text at this point.
    appendEndDocument();
  }
  public void endElement(java.lang.String namespaceURI, java.lang.String localName,
      java.lang.String qName)
       throws org.xml.sax.SAXException
  {
    processAccumulatedText();
    // No args but we do need to tell the low-level builder code to
    // pop up a level.
    appendEndElement();
  }
  public void endPrefixMapping(java.lang.String prefix)
       throws org.xml.sax.SAXException
  {
    // No-op
  }
  public void ignorableWhitespace(char[] ch, int start, int length)
       throws org.xml.sax.SAXException
  {
    // %TBD% I believe ignorable text isn't part of the DTM model...?
  }
  public void processingInstruction(java.lang.String target, java.lang.String data)
       throws org.xml.sax.SAXException
  {
    processAccumulatedText();
    // %TBD% Which pools do target and data go into?
  }
  public void setDocumentLocator(Locator locator)
  {
    // No-op for DTM
  }
  public void skippedEntity(java.lang.String name)
       throws org.xml.sax.SAXException
  {
    processAccumulatedText();
    //%TBD%
  }
  public void startDocument()
       throws org.xml.sax.SAXException
  {
    appendStartDocument();
  }
  public void startElement(java.lang.String namespaceURI, java.lang.String localName,
      java.lang.String qName, Attributes atts)
       throws org.xml.sax.SAXException
  {
    processAccumulatedText();

    // %TBD% Split prefix off qname
    String prefix=null;
    int colon=qName.indexOf(':');
    if(colon>0)
      prefix=qName.substring(0,colon);

    // %TBD% Where do we pool expandedName, or is it just the union, or...
    /**/System.out.println("Prefix="+prefix+" index="+m_prefixNames.stringToIndex(prefix));
    appendStartElement(m_nsNames.stringToIndex(namespaceURI),
                     m_localNames.stringToIndex(localName),
                     m_prefixNames.stringToIndex(prefix)); /////// %TBD%

    // %TBD% I'm assuming that DTM will require resequencing of
    // NS decls before other attrs, hence two passes are taken.
    // %TBD% Is there an easier way to test for NSDecl?
    int nAtts=(atts==null) ? 0 : atts.getLength();
    // %TBD% Countdown is more efficient if nobody cares about sequence.
    for(int i=nAtts-1;i>=0;--i)
      {
        qName=atts.getQName(i);
        if(qName.startsWith("xmlns:") || "xmlns".equals(qName))
          {
            prefix=null;
            colon=qName.indexOf(':');
            if(colon>0)
              {
                prefix=qName.substring(0,colon);
              }
            else
              {
                // %REVEIW% Null or ""?
                prefix=null; // Default prefix
              }


            appendNSDeclaration(
                                    m_prefixNames.stringToIndex(prefix),
                                    m_nsNames.stringToIndex(atts.getValue(i)),
                                    atts.getType(i).equalsIgnoreCase("ID"));
          }
      }

    for(int i=nAtts-1;i>=0;--i)
      {
        qName=atts.getQName(i);
        if(!(qName.startsWith("xmlns:") || "xmlns".equals(qName)))
          {
            // %TBD% I hate having to extract the prefix into a new
            // string when we may never use it. Consider pooling whole
            // qNames, which are already strings?
            prefix=null;
            colon=qName.indexOf(':');
            if(colon>0)
              {
                prefix=qName.substring(0,colon);
                localName=qName.substring(colon+1);
              }
            else
              {
                prefix=""; // Default prefix
                localName=qName;
              }


            m_char.append(atts.getValue(i)); // Single-string value
            int contentEnd=m_char.length();

            if(!("xmlns".equals(prefix) || "xmlns".equals(qName)))
              appendAttribute(m_nsNames.stringToIndex(atts.getURI(i)),
                                  m_localNames.stringToIndex(localName),
                                  m_prefixNames.stringToIndex(prefix),
                                  atts.getType(i).equalsIgnoreCase("ID"),
                                  m_char_current_start, contentEnd-m_char_current_start);
            m_char_current_start=contentEnd;
          }
      }
  }
  public void startPrefixMapping(java.lang.String prefix, java.lang.String uri)
       throws org.xml.sax.SAXException
  {
    // No-op in DTM, handled during element/attr processing?
  }

  //
  // LexicalHandler support. Not all SAX2 parsers support these events
  // but we may want to pass them through when they exist...
  //
  public void comment(char[] ch, int start, int length)
       throws org.xml.sax.SAXException
  {
    processAccumulatedText();

    m_char.append(ch,start,length); // Single-string value
    appendComment(m_char_current_start,length);
    m_char_current_start+=length;
  }
  public void endCDATA()
       throws org.xml.sax.SAXException
  {
    // No-op in DTM
  }
  public void endDTD()
       throws org.xml.sax.SAXException
  {
    // No-op in DTM
  }
  public void endEntity(java.lang.String name)
       throws org.xml.sax.SAXException
  {
    // No-op in DTM
  }
  public void startCDATA()
       throws org.xml.sax.SAXException
  {
    // No-op in DTM
  }
  public void startDTD(java.lang.String name, java.lang.String publicId,
      java.lang.String systemId)
       throws org.xml.sax.SAXException
  {
    // No-op in DTM
  }
  public void startEntity(java.lang.String name)
       throws org.xml.sax.SAXException
  {
    // No-op in DTM
  }


  //================================================================
  // ========= Document Handler Functions =========
  // %REVIEW% jjk -- DocumentHandler is  SAX Level 1, and deprecated....
  // and this wasn't a fully compliant or declared implementation of that API
  // in any case. Phase out in favor of SAX2 ContentHandler/LexicalHandler

        /**
         * Reset a dtm document to its initial (empty) state.
         *
         * The DTMManager will invoke this method when the dtm is created.
         *
         * @param docHandle int the handle for the DTM document.
         */
        final void initDocument(int documentNumber)
        {
                // save masked DTM document handle
                m_docHandle = documentNumber<<DOCHANDLE_SHIFT;

                // Initialize the doc -- no parent, no next-sib
                nodes.writeSlot(0,DOCUMENT_NODE,-1,-1,0);
                // wait for the first startElement to create the doc root node
                done = false;
        }

// 	/**
// 	 * Receive hint of the end of a document.
// 	 *
// 	 * <p>The content handler will invoke this method only once, and it will
// 	 * be the last method invoked during the parse.  The handler shall not
// 	 * not invoke this method until it has either abandoned parsing
// 	 * (because of an unrecoverable error) or reached the end of
// 	 * input.</p>
// 	 */
// 	public void documentEnd()
// 	{
// 		done = true;
// 		// %TBD% may need to notice the last slot number and slot count to avoid
// 		// residual data from provious use of this DTM
// 	}

// 	/**
// 	 * Receive notification of the beginning of a document.
// 	 *
// 	 * <p>The SAX parser will invoke this method only once, before any
// 	 * other methods in this interface.</p>
// 	 */
// 	public void reset()
// 	{

// 		// %TBD% reset slot 0 to indicate ChunkedIntArray reuse or wait for
// 		//       the next initDocument().
// 		m_docElement = NULL;	 // reset nodeHandle to the root of the actual dtm doc content
// 		initDocument(0);
// 	}

// 	/**
// 	 * Factory method; creates an Element node in this document.
// 	 *
// 	 * The node created will be chained according to its natural order of request
// 	 * received.  %TBD% It can be rechained later via the optional DTM writable interface.
// 	 *
// 	 * <p>The XML content handler will invoke endElement() method after all
// 	 * of the element's content are processed in order to give DTM the indication
// 	 * to prepare and patch up parent and sibling node pointers.</p>
// 	 *
// 	 * <p>The following interface for createElement will use an index value corresponds
// 	 * to the symbol entry in the DTMDStringPool based symbol tables.</p>
// 	 *
// 	 * @param nsIndex The namespace of the node
// 	 * @param nameIndex The element name.
// 	 * @see #endElement
// 	 * @see org.xml.sax.Attributes
// 	 * @return nodeHandle int of the element created
// 	 */
// 	public int createElement(int nsIndex, int nameIndex, Attributes atts)
// 	{
// 		// do document root node creation here on the first element, create nodes for
// 		// this element and its attributes, store the element, namespace, and attritute
// 		// name indexes to the nodes array, keep track of the current node and parent
// 		// element used

// 		// W0  High:  Namespace  Low:  Node Type
// 		int w0 = (nsIndex << 16) | ELEMENT_NODE;
// 		// W1: Parent
// 		int w1 = currentParent;
// 		// W2: Next  (initialized as 0)
// 		int w2 = 0;
// 		// W3: Tagname
// 		int w3 = nameIndex;
// 		//int ourslot = nodes.appendSlot(w0, w1, w2, w3);
// 		int ourslot = appendNode(w0, w1, w2, w3);
// 		currentParent = ourslot;
// 		previousSibling = 0;
// 		setAttributes(atts);

// 		// set the root element pointer when creating the first element node
// 		if (m_docElement == NULL)
// 			m_docElement = ourslot;
// 		return (m_docHandle | ourslot);
// 	}

// 	// Factory method to create an Element node not associated with a given name space
// 	// using String value parameters passed in from a content handler or application
// 	/**
// 	 * Factory method; creates an Element node not associated with a given name space in this document.
// 	 *
// 	 * The node created will be chained according to its natural order of request
// 	 * received.  %TBD% It can be rechained later via the optional DTM writable interface.
// 	 *
// 	 * <p>The XML content handler or application will invoke endElement() method after all
// 	 * of the element's content are processed in order to give DTM the indication
// 	 * to prepare and patch up parent and sibling node pointers.</p>
// 	 *
// 	 * <p>The following parameters for createElement contains raw string values for name
// 	 * symbols used in an Element node.</p>
// 	 *
// 	 * @param name String the element name, including the prefix if any.
// 	 * @param atts The attributes attached to the element, if any.
// 	 * @see #endElement
// 	 * @see org.xml.sax.Attributes
// 	 */
// 	public int createElement(String name, Attributes atts)
// 	{
// 		// This method wraps around the index valued interface of the createElement interface.
// 		// The raw string values are stored into the current DTM name symbol tables.  The method
// 		// method will then use the index values returned to invoke the other createElement()
// 		// onverted to index values modified to match a
// 		// method.
// 		int nsIndex = NULL;
// 		int nameIndex = m_localNames.stringToIndex(name);
// 		// note - there should be no prefix separator in the name because it is not associated
// 		// with a name space

// 		return createElement(nsIndex, nameIndex, atts);
// 	}

// 	// Factory method to create an Element node associated with a given name space
// 	// using String value parameters passed in from a content handler or application
// 	/**
// 	 * Factory method; creates an Element node associated with a given name space in this document.
// 	 *
// 	 * The node created will be chained according to its natural order of request
// 	 * received.  %TBD% It can be rechained later via the optional DTM writable interface.
// 	 *
// 	 * <p>The XML content handler or application will invoke endElement() method after all
// 	 * of the element's content are processed in order to give DTM the indication
// 	 * to prepare and patch up parent and sibling node pointers.</p>
// 	 *
// 	 * <p>The following parameters for createElementNS contains raw string values for name
// 	 * symbols used in an Element node.</p>
// 	 *
// 	 * @param ns String the namespace of the node
// 	 * @param name String the element name, including the prefix if any.
// 	 * @param atts The attributes attached to the element, if any.
// 	 * @see #endElement
// 	 * @see org.xml.sax.Attributes
// 	 */
// 	public int createElementNS(String ns, String name, Attributes atts)
// 	{
// 		// This method wraps around the index valued interface of the createElement interface.
// 		// The raw string values are stored into the current DTM name symbol tables.  The method
// 		// method will then use the index values returned to invoke the other createElement()
// 		// onverted to index values modified to match a
// 		// method.
// 		int nsIndex = m_nsNames.stringToIndex(ns);
// 		int nameIndex = m_localNames.stringToIndex(name);
// 		// The prefixIndex is not needed by the indexed interface of the createElement method
// 		int prefixSep = name.indexOf(":");
// 		int prefixIndex = m_prefixNames.stringToIndex(name.substring(0, prefixSep));
// 		return createElement(nsIndex, nameIndex, atts);
// 	}

// 	/**
// 	 * Receive an indication for the end of an element.
// 	 *
// 	 * <p>The XML content handler will invoke this method at the end of every
// 	 * element in the XML document to give hint its time to pop up the current
// 	 * element and parent and patch up parent and sibling pointers if necessary
// 	 *
// 	 * <p>%tbd% The following interface may need to be modified to match a
// 	 * coordinated access to the DTMDStringPool based symbol tables.</p>
// 		 *
// 	 * @param ns the namespace of the element
// 	 * @param localName The local part of the qualified name of the element
// 	 * @param name The element name
// 	 */
// 	public void endElement(String ns, String name)
// 	{
// 		// pop up the stacks

// 		//
// 		if (previousSiblingWasParent)
// 			nodes.writeEntry(previousSibling, 2, NULL);

// 		// Pop parentage
// 		previousSibling = currentParent;
// 		nodes.readSlot(currentParent, gotslot);
// 		currentParent = gotslot[1] & 0xFFFF;

// 		// The element just being finished will be
// 		// the previous sibling for the next operation
// 		previousSiblingWasParent = true;

// 		// Pop a level of namespace table
// 		// namespaceTable.removeLastElem();
// 	}

// 	/**
// 	 * Creates attributes for the current node.
// 	 *
// 	 * @param atts Attributes to be created.
// 	 */
// 	void setAttributes(Attributes atts) {
// 		int atLength = (null == atts) ? 0 : atts.getLength();
// 		for (int i=0; i < atLength; i++) {
// 			String qname = atts.getQName(i);
// 			createAttribute(atts.getQName(i), atts.getValue(i));
// 		}
// 	}

// 	/**
// 	 * Appends an attribute to the document.
// 	 * @param qname Qualified Name of the attribute
// 	 * @param value Value of the attribute
// 	 * @return Handle of node
// 	 */
// 	public int createAttribute(String qname, String value) {
// 		int colonpos = qname.indexOf(":");
// 		String attName = qname.substring(colonpos+1);
// 		int w0 = 0;
// 		if (colonpos > 0) {
// 			String prefix = qname.substring(0, colonpos);
// 			if (prefix.equals("xml")) {
// 				//w0 = ATTRIBUTE_NODE |
// 				//	(org.apache.xalan.templates.Constants.S_XMLNAMESPACEURI << 16);
// 			} else {
// 				//w0 = ATTRIBUTE_NODE |
// 			}
// 		} else {
// 			w0 = ATTRIBUTE_NODE;
// 		}
// 		// W1:  Parent
// 		int w1 = currentParent;
// 		// W2:  Next (not yet resolved)
// 		int w2 = 0;
// 		// W3:  Tag name
// 		int w3 = m_localNames.stringToIndex(attName);
// 		// Add node
// 		int ourslot = appendNode(w0, w1, w2, w3);
// 		previousSibling = ourslot;	// Should attributes be previous siblings

// 		// W0: Node Type
// 		w0 = TEXT_NODE;
// 		// W1: Parent
// 		w1 = ourslot;
// 		// W2: Start Position within buffer
// 		w2 = m_char.length();
// 		m_char.append(value);
// 		// W3: Length
// 		w3 = m_char.length() - w2;
// 		appendNode(w0, w1, w2, w3);
// 		charStringStart=m_char.length();
// 		charStringLength = 0;
// 		//previousSibling = ourslot;
// 		// Attrs are Parents
// 		previousSiblingWasParent = true;
// 		return (m_docHandle | ourslot);
// 	}

// 	/**
// 	 * Factory method; creates a Text node in this document.
// 	 *
// 	 * The node created will be chained according to its natural order of request
// 	 * received.  %TBD% It can be rechained later via the optional DTM writable interface.
// 	 *
// 	 * @param text String The characters text string from the XML document.
// 	 * @return int DTM node-number of the text node created
// 	 */
// 	public int createTextNode(String text)
// 	throws DTMException
// 	{
// 		// wraps around the index value based createTextNode method
// 		return createTextNode(text.toCharArray(), 0, text.length());
// 	}

// 	/**
// 	 * Factory method; creates a Text node in this document.
// 	 *
// 	 * The node created will be chained according to its natural order of request
// 	 * received.  %TBD% It can be rechained later via the optional DTM writable interface.
// 	 *
// 	 * %REVIEW% for text normalization issues, unless we are willing to
// 	 * insist that all adjacent text must be merged before this method
// 	 * is called.
// 	 *
// 	 * @param ch The characters from the XML document.
// 	 * @param start The start position in the array.
// 	 * @param length The number of characters to read from the array.
// 	 */
// 	public int createTextNode(char ch[], int start, int length)
// 	throws DTMException
// 	{
// 		m_char.append(ch, start, length);		// store the chunk to the text/comment string table

// 		// create a Text Node
// 		// %TBD% may be possible to combine with appendNode()to replace the next chunk of code
// 		int w0 = TEXT_NODE;
// 		// W1: Parent
// 		int w1 = currentParent;
// 		// W2: Start position within m_char
// 		int w2 = charStringStart;
// 		// W3: Length of the full string
// 		int w3 = length;
// 		int ourslot = appendNode(w0, w1, w2, w3);
// 		previousSibling = ourslot;

// 		charStringStart=m_char.length();
// 		charStringLength = 0;
// 		return (m_docHandle | ourslot);
// 	}

// 	/**
// 	 * Factory method; creates a Comment node in this document.
// 	 *
// 	 * The node created will be chained according to its natural order of request
// 	 * received.  %TBD% It can be rechained later via the optional DTM writable interface.
// 	 *
// 	 * @param text String The characters text string from the XML document.
// 	 * @return int DTM node-number of the text node created
// 	 */
// 	public int createComment(String text)
// 	throws DTMException
// 	{
// 		// wraps around the index value based createTextNode method
// 		return createComment(text.toCharArray(), 0, text.length());
// 	}

// 	/**
// 	 * Factory method; creates a Comment node in this document.
// 	 *
// 	 * The node created will be chained according to its natural order of request
// 	 * received.  %TBD% It can be rechained later via the optional DTM writable interface.
// 	 *
// 	 * @param ch An array holding the characters in the comment.
// 	 * @param start The starting position in the array.
// 	 * @param length The number of characters to use from the array.
// 	 * @see DTMException
// 	 */
// 	public int createComment(char ch[], int start, int length)
// 	throws DTMException
// 	{
// 		m_char.append(ch, start, length);		// store the comment string to the text/comment string table

// 		// create a Comment Node
// 		// %TBD% may be possible to combine with appendNode()to replace the next chunk of code
// 		int w0 = COMMENT_NODE;
// 		// W1: Parent
// 		int w1 = currentParent;
// 		// W2: Start position within m_char
// 		int w2 = charStringStart;
// 		// W3: Length of the full string
// 		int w3 = length;
// 		int ourslot = appendNode(w0, w1, w2, w3);
// 		previousSibling = ourslot;

// 		charStringStart=m_char.length();
// 		charStringLength = 0;
// 		return (m_docHandle | ourslot);
// 	}

// 	// Counters to keep track of the current text string being accumulated with respect
// 	// to the text/comment string table: charStringStart should point to the starting
// 	// offset of the string in the table and charStringLength the acccumulated length when
// 	// appendAccumulatedText starts, and reset to the end of the table and 0 at the end
// 	// of appendAccumulatedText for the next set of characters receives
// 	int charStringStart=0,charStringLength=0;

        // ========= Document Navigation Functions =========

        /** Given a node handle, test if it has child nodes.
         * <p> %REVIEW% This is obviously useful at the DOM layer, where it
         * would permit testing this without having to create a proxy
         * node. It's less useful in the DTM API, where
         * (dtm.getFirstChild(nodeHandle)!=DTM.NULL) is just as fast and
         * almost as self-evident. But it's a convenience, and eases porting
         * of DOM code to DTM.  </p>
         *
         * @param nodeHandle int Handle of the node.
         * @return int true if the given node has child nodes.
         */
        public boolean hasChildNodes(int nodeHandle) {
                return(getFirstChild(nodeHandle) != NULL);
        }

        /**
         * Given a node handle, get the handle of the node's first child.
         * If not yet resolved, waits for more nodes to be added to the document and
         * tries again.
         *
         * @param nodeHandle int Handle of the node.
         * @return int DTM node-number of first child, or DTM.NULL to indicate none exists.
         */
        public int getFirstChild(int nodeHandle) {

                // ###shs worry about tracing/debug later
                nodeHandle &= NODEHANDLE_MASK;
                // Read node into variable
                nodes.readSlot(nodeHandle, gotslot);

                // type is the last half of first slot
                short type = (short) (gotslot[0] & 0xFFFF);

                // Check to see if Element or Document node
                if ((type == ELEMENT_NODE) || (type == DOCUMENT_NODE) ||
                                (type == ENTITY_REFERENCE_NODE)) {

                        // In case when Document root is given
                        //	if (nodeHandle == 0) nodeHandle = 1;
                        // %TBD% Probably was a mistake.
                        // If someone explicitly asks for first child
                        // of Document, I would expect them to want
                        // that and only that.

                        int kid = nodeHandle + 1;
                        nodes.readSlot(kid, gotslot);
                        while (ATTRIBUTE_NODE == (gotslot[0] & 0xFFFF)) {
                                // points to next sibling
                                kid = gotslot[2];
                                // Return NULL if node has only attributes
                                if (kid == NULL) return NULL;
                                nodes.readSlot(kid, gotslot);
                        }
                        // If parent slot matches given parent, return kid
                        if (gotslot[1] == nodeHandle)
                        {
                          int firstChild = kid | m_docHandle;

                          return firstChild;
                        }
                }
                // No child found

                return NULL;
        }

        /**
        * Given a node handle, advance to its last child.
        * If not yet resolved, waits for more nodes to be added to the document and
        * tries again.
        *
        * @param nodeHandle int Handle of the node.
        * @return int Node-number of last child,
        * or DTM.NULL to indicate none exists.
        */
        public int getLastChild(int nodeHandle) {
                // ###shs put trace/debug later
                nodeHandle &= NODEHANDLE_MASK;
                // do not need to test node type since getFirstChild does that
                int lastChild = NULL;
                for (int nextkid = getFirstChild(nodeHandle); nextkid != NULL;
                                nextkid = getNextSibling(nextkid)) {
                        lastChild = nextkid;
                }
                return lastChild | m_docHandle;
        }

        /**
         * Retrieves an attribute node by by qualified name and namespace URI.
         *
         * @param nodeHandle int Handle of the node upon which to look up this attribute.
         * @param namespaceURI The namespace URI of the attribute to
         *   retrieve, or null.
         * @param name The local name of the attribute to
         *   retrieve.
         * @return The attribute node handle with the specified name (
         *   <code>nodeName</code>) or <code>DTM.NULL</code> if there is no such
         *   attribute.
         */
        public int getAttributeNode(int nodeHandle, String namespaceURI, String name) {
                int nsIndex = m_nsNames.stringToIndex(namespaceURI),
                                                                        nameIndex = m_localNames.stringToIndex(name);
                nodeHandle &= NODEHANDLE_MASK;
                nodes.readSlot(nodeHandle, gotslot);
                short type = (short) (gotslot[0] & 0xFFFF);
                // If nodeHandle points to element next slot would be first attribute
                if (type == ELEMENT_NODE)
                        nodeHandle++;
                // Iterate through Attribute Nodes
                while (type == ATTRIBUTE_NODE) {
                        if ((nsIndex == (gotslot[0] << 16)) && (gotslot[3] == nameIndex))
                                return nodeHandle | m_docHandle;
                        // Goto next sibling
                        nodeHandle = gotslot[2];
                        nodes.readSlot(nodeHandle, gotslot);
                }
                return NULL;
        }

        /**
         * Given a node handle, get the index of the node's first attribute.
         *
         * @param nodeHandle int Handle of the Element node.
         * @return Handle of first attribute, or DTM.NULL to indicate none exists.
         */
        public int getFirstAttribute(int nodeHandle) {
                nodeHandle &= NODEHANDLE_MASK;

                // %REVIEW% jjk: Just a quick observation: If you're going to
                // call readEntry repeatedly on the same node, it may be
                // more efficiently to do a readSlot to get the data locally,
                // reducing the addressing and call-and-return overhead.

                // Should we check if handle is element (do we want sanity checks?)
                if (ELEMENT_NODE != (nodes.readEntry(nodeHandle, 0) & 0xFFFF))
                        return NULL;
                // First Attribute (if any) should be at next position in table
                nodeHandle++;
                return(ATTRIBUTE_NODE == (nodes.readEntry(nodeHandle, 0) & 0xFFFF)) ?
                nodeHandle | m_docHandle : NULL;
        }

        /**
         * Given a node handle, get the index of the node's first child.
         * If not yet resolved, waits for more nodes to be added to the document and
         * tries again
         *
         * @param nodeHandle handle to node, which should probably be an element
         *                   node, but need not be.
         *
         * @param inScope    true if all namespaces in scope should be returned,
         *                   false if only the namespace declarations should be
         *                   returned.
         * @return handle of first namespace, or DTM.NULL to indicate none exists.
         */
        public int getFirstNamespaceNode(int nodeHandle, boolean inScope) {

                return NULL;
        }

        /**
         * Given a node handle, advance to its next sibling.
         *
         * %TBD% This currently uses the DTM-internal definition of
         * sibling; eg, the last attr's next sib is the first
         * child. In the old DTM, the DOM proxy layer provided the
         * additional logic for the public view.  If we're rewriting
         * for XPath emulation, that test must be done here.
         *
         * %TBD% CODE INTERACTION WITH INCREMENTAL PARSE - If not yet
         * resolved, should wait for more nodes to be added to the document
         * and tries again.
         *
         * @param nodeHandle int Handle of the node.
         * @return int Node-number of next sibling,
         * or DTM.NULL to indicate none exists.
         * */
        public int getNextSibling(int nodeHandle) {
                nodeHandle &= NODEHANDLE_MASK;
                // Document root has no next sibling
                if (nodeHandle == 0)
                        return NULL;

                short type = (short) (nodes.readEntry(nodeHandle, 0) & 0xFFFF);
                if ((type == ELEMENT_NODE) || (type == ATTRIBUTE_NODE) ||
                                (type == ENTITY_REFERENCE_NODE)) {
                        int nextSib = nodes.readEntry(nodeHandle, 2);
                        if (nextSib == NULL)
                                return NULL;
                        if (nextSib != 0)
                                return (m_docHandle | nextSib);
                        // ###shs should cycle/wait if nextSib is 0? Working on threading next
                }
                // Next Sibling is in the next position if it shares the same parent
                int thisParent = nodes.readEntry(nodeHandle, 1);

                if (nodes.readEntry(++nodeHandle, 1) == thisParent)
                        return (m_docHandle | nodeHandle);

                return NULL;
        }

        /**
         * Given a node handle, find its preceeding sibling.
         * WARNING: DTM is asymmetric; this operation is resolved by search, and is
         * relatively expensive.
         *
         * @param nodeHandle the id of the node.
         * @return int Node-number of the previous sib,
         * or DTM.NULL to indicate none exists.
         */
        public int getPreviousSibling(int nodeHandle) {
                nodeHandle &= NODEHANDLE_MASK;
                // Document root has no previous sibling
                if (nodeHandle == 0)
                        return NULL;

                int parent = nodes.readEntry(nodeHandle, 1);
                int kid = NULL;
                for (int nextkid = getFirstChild(parent); nextkid != nodeHandle;
                                nextkid = getNextSibling(nextkid)) {
                        kid = nextkid;
                }
                return kid | m_docHandle;
        }

        /**
         * Given a node handle, advance to the next attribute. If an
         * element, we advance to its first attribute; if an attr, we advance to
         * the next attr on the same node.
         *
         * @param nodeHandle int Handle of the node.
         * @return int DTM node-number of the resolved attr,
         * or DTM.NULL to indicate none exists.
         */
        public int getNextAttribute(int nodeHandle) {
                nodeHandle &= NODEHANDLE_MASK;
                nodes.readSlot(nodeHandle, gotslot);

                //%REVIEW% Why are we using short here? There's no storage
                //reduction for an automatic variable, especially one used
                //so briefly, and it typically costs more cycles to process
                //than an int would.
                short type = (short) (gotslot[0] & 0xFFFF);

                if (type == ELEMENT_NODE) {
                        return getFirstAttribute(nodeHandle);
                } else if (type == ATTRIBUTE_NODE) {
                        if (gotslot[2] != NULL)
                                return (m_docHandle | gotslot[2]);
                }
                return NULL;
        }

        /**
         * Given a namespace handle, advance to the next namespace.
         *
         * %TBD% THIS METHOD DOES NOT MATCH THE CURRENT SIGNATURE IN
         * THE DTM INTERFACE.  FIX IT, OR JUSTIFY CHANGING THE DTM
         * API.
         *
         * @param namespaceHandle handle to node which must be of type NAMESPACE_NODE.
         * @return handle of next namespace, or DTM.NULL to indicate none exists.
         */
        public int getNextNamespaceNode(int baseHandle,int namespaceHandle, boolean inScope) {
                // ###shs need to work on namespace
                return NULL;
        }

        /**
         * Given a node handle, advance to its next descendant.
         * If not yet resolved, waits for more nodes to be added to the document and
         * tries again.
         *
         * @param subtreeRootNodeHandle
         * @param nodeHandle int Handle of the node.
         * @return handle of next descendant,
         * or DTM.NULL to indicate none exists.
         */
        public int getNextDescendant(int subtreeRootHandle, int nodeHandle) {
                subtreeRootHandle &= NODEHANDLE_MASK;
                nodeHandle &= NODEHANDLE_MASK;
                // Document root [Document Node? -- jjk] - no next-sib
                if (nodeHandle == 0)
                        return NULL;
                while (!m_isError) {
                        // Document done and node out of bounds
                        if (done && (nodeHandle > nodes.slotsUsed()))
                                break;
                        if (nodeHandle > subtreeRootHandle) {
                                nodes.readSlot(nodeHandle+1, gotslot);
                                if (gotslot[2] != 0) {
                                        short type = (short) (gotslot[0] & 0xFFFF);
                                        if (type == ATTRIBUTE_NODE) {
                                                nodeHandle +=2;
                                        } else {
                                                int nextParentPos = gotslot[1];
                                                if (nextParentPos >= subtreeRootHandle)
                                                        return (m_docHandle | (nodeHandle+1));
                                                else
                                                        break;
                                        }
                                } else if (!done) {
                                        // Add wait logic here
                                } else
                                        break;
                        } else {
                                nodeHandle++;
                        }
                }
                // Probably should throw error here like original instead of returning
                return NULL;
        }

        /**
         * Given a node handle, advance to the next node on the following axis.
         *
         * @param axisContextHandle the start of the axis that is being traversed.
         * @param nodeHandle
         * @return handle of next sibling,
         * or DTM.NULL to indicate none exists.
         */
        public int getNextFollowing(int axisContextHandle, int nodeHandle) {
                //###shs still working on
                return NULL;
        }

        /**
         * Given a node handle, advance to the next node on the preceding axis.
         *
         * @param axisContextHandle the start of the axis that is being traversed.
         * @param nodeHandle the id of the node.
         * @return int Node-number of preceding sibling,
         * or DTM.NULL to indicate none exists.
         */
        public int getNextPreceding(int axisContextHandle, int nodeHandle) {
                // ###shs copied from Xalan 1, what is this suppose to do?
                nodeHandle &= NODEHANDLE_MASK;
                while (nodeHandle > 1) {
                        nodeHandle--;
                        if (ATTRIBUTE_NODE == (nodes.readEntry(nodeHandle, 0) & 0xFFFF))
                                continue;

                        // if nodeHandle is _not_ an ancestor of
                        // axisContextHandle, specialFind will return it.
                        // If it _is_ an ancestor, specialFind will return -1

                        // %REVIEW% unconditional return defeats the
                        // purpose of the while loop -- does this
                        // logic make any sense?

                        return (m_docHandle | nodes.specialFind(axisContextHandle, nodeHandle));
                }
                return NULL;
        }

        /**
         * Given a node handle, find its parent node.
         *
         * @param nodeHandle the id of the node.
         * @return int Node-number of parent,
         * or DTM.NULL to indicate none exists.
         */
        public int getParent(int nodeHandle) {
                // Should check to see within range?

                // Document Root should not have to be handled differently
                return (m_docHandle | nodes.readEntry(nodeHandle, 1));
        }

        /**
         * Returns the root element of the document.
         * @return nodeHandle to the Document Root.
         */
        public int getDocumentRoot() {
                return (m_docHandle | m_docElement);
        }

        /**
                * Given a node handle, find the owning document node.
                *
                * @param nodeHandle the id of the node.
                * @return int Node handle of document, which should always be valid.
                */
        public int getDocument() {
                return m_docHandle;
        }

        /**
         * Given a node handle, find the owning document node.  This has the exact
         * same semantics as the DOM Document method of the same name, in that if
         * the nodeHandle is a document node, it will return NULL.
         *
         * <p>%REVIEW% Since this is DOM-specific, it may belong at the DOM
         * binding layer. Included here as a convenience function and to
         * aid porting of DOM code to DTM.</p>
         *
         * @param nodeHandle the id of the node.
         * @return int Node handle of owning document, or NULL if the nodeHandle is
         *             a document.
         */
        public int getOwnerDocument(int nodeHandle) {
                // Assumption that Document Node is always in 0 slot
                if ((nodeHandle & NODEHANDLE_MASK) == 0)
                        return NULL;
                return (nodeHandle & DOCHANDLE_MASK);
        }

        /**
         * Given a node handle, find the owning document node.  This has the DTM
         * semantics; a Document node is its own owner.
         *
         * <p>%REVIEW% Since this is DOM-specific, it may belong at the DOM
         * binding layer. Included here as a convenience function and to
         * aid porting of DOM code to DTM.</p>
         *
         * @param nodeHandle the id of the node.
         * @return int Node handle of owning document, or NULL if the nodeHandle is
         *             a document.
         */
        public int getDocumentRoot(int nodeHandle) {
                // Assumption that Document Node is always in 0 slot
                if ((nodeHandle & NODEHANDLE_MASK) == 0)
                        return NULL;
                return (nodeHandle & DOCHANDLE_MASK);
        }

        /**
         * Get the string-value of a node as a String object
         * (see http://www.w3.org/TR/xpath#data-model
         * for the definition of a node's string-value).
         *
         * @param nodeHandle The node ID.
         *
         * @return A string object that represents the string-value of the given node.
         */
        public XMLString getStringValue(int nodeHandle) {
        // ###zaj - researching
        nodes.readSlot(nodeHandle, gotslot);
        int nodetype=gotslot[0] & 0xFF;
        String value=null;

        switch (nodetype) {
        case TEXT_NODE:
        case COMMENT_NODE:
        case CDATA_SECTION_NODE:
                value= m_char.getString(gotslot[2], gotslot[3]);
                break;
        case PROCESSING_INSTRUCTION_NODE:
        case ATTRIBUTE_NODE:
        case ELEMENT_NODE:
        case ENTITY_REFERENCE_NODE:
        default:
                break;
        }
        return m_xsf.newstr( value );

        }

        /**
         * Get number of character array chunks in
         * the string-value of a node.
         * (see http://www.w3.org/TR/xpath#data-model
         * for the definition of a node's string-value).
         * Note that a single text node may have multiple text chunks.
         *
         * EXPLANATION: This method is an artifact of the fact that the
         * underlying m_chars object may not store characters in a
         * single contiguous array -- for example,the current
         * FastStringBuffer may split a single node's text across
         * multiple allocation units.  This call tells us how many
         * separate accesses will be required to retrieve the entire
         * content. PLEASE NOTE that this may not be the same as the
         * number of SAX characters() events that caused the text node
         * to be built in the first place, since m_chars buffering may
         * be on different boundaries than the parser's buffers.
         *
         * @param nodeHandle The node ID.
         *
         * @return number of character array chunks in
         *         the string-value of a node.
         * */
        //###zaj - tbd
        public int getStringValueChunkCount(int nodeHandle)
        {
                //###zaj    return value
                return 0;
        }

        /**
         * Get a character array chunk in the string-value of a node.
         * (see http://www.w3.org/TR/xpath#data-model
         * for the definition of a node's string-value).
         * Note that a single text node may have multiple text chunks.
         *
         * EXPLANATION: This method is an artifact of the fact that
         * the underlying m_chars object may not store characters in a
         * single contiguous array -- for example,the current
         * FastStringBuffer may split a single node's text across
         * multiple allocation units.  This call retrieves a single
         * contiguous portion of the text -- as much as m-chars was
         * able to store in a single allocation unit.  PLEASE NOTE
         * that this may not be the same granularityas the SAX
         * characters() events that caused the text node to be built
         * in the first place, since m_chars buffering may be on
         * different boundaries than the parser's buffers.
         *
         * @param nodeHandle The node ID.
         * @param chunkIndex Which chunk to get.
         * @param startAndLen An array of 2 where the start position and length of
         *                    the chunk will be returned.
         *
         * @return The character array reference where the chunk occurs.  */
        //###zaj - tbd
        public char[] getStringValueChunk(int nodeHandle, int chunkIndex,
                                                                                                                                                int[] startAndLen) {return new char[0];}

        /**
         * Given a node handle, return an ID that represents the node's expanded name.
         *
         * @param nodeHandle The handle to the node in question.
         *
         * @return the expanded-name id of the node.
         */
        public int getExpandedTypeID(int nodeHandle) {
           nodes.readSlot(nodeHandle, gotslot);
           String qName = m_localNames.indexToString(gotslot[3]);
           // Remove prefix from qName
           // %TBD% jjk This is assuming the elementName is the qName.
           int colonpos = qName.indexOf(":");
           String localName = qName.substring(colonpos+1);
           // Get NS
           String namespace = m_nsNames.indexToString(gotslot[0] << 16);
           // Create expanded name
           String expandedName = namespace + ":" + localName;
           int expandedNameID = m_nsNames.stringToIndex(expandedName);

        return expandedNameID;
        }


        /**
         * Given an expanded name, return an ID.  If the expanded-name does not
         * exist in the internal tables, the entry will be created, and the ID will
         * be returned.  Any additional nodes that are created that have this
         * expanded name will use this ID.
         *
         * @param nodeHandle The handle to the node in question.
         *
         * @return the expanded-name id of the node.
         */
        public int getExpandedTypeID(String namespace, String localName, int type) {
           // Create expanded name
          // %TBD% jjk Expanded name is bitfield-encoded as
          // typeID[6]nsuriID[10]localID[16]. Switch to that form, and to
          // accessing the ns/local via their tables rather than confusing
          // nsnames and expandednames.
           String expandedName = namespace + ":" + localName;
           int expandedNameID = m_nsNames.stringToIndex(expandedName);

           return expandedNameID;
        }


        /**
         * Given an expanded-name ID, return the local name part.
         *
         * @param ExpandedNameID an ID that represents an expanded-name.
         * @return String Local name of this node.
         */
        public String getLocalNameFromExpandedNameID(int ExpandedNameID) {

           // Get expanded name
           String expandedName = m_localNames.indexToString(ExpandedNameID);
           // Remove prefix from expanded name
           int colonpos = expandedName.indexOf(":");
           String localName = expandedName.substring(colonpos+1);
           return localName;
        }


        /**
         * Given an expanded-name ID, return the namespace URI part.
         *
         * @param ExpandedNameID an ID that represents an expanded-name.
         * @return String URI value of this node's namespace, or null if no
         * namespace was resolved.
        */
        public String getNamespaceFromExpandedNameID(int ExpandedNameID) {

           String expandedName = m_localNames.indexToString(ExpandedNameID);
           // Remove local name from expanded name
           int colonpos = expandedName.indexOf(":");
           String nsName = expandedName.substring(0, colonpos);

        return nsName;
        }


        /**
         * fixednames
        */
        static final String[] fixednames=
        {
                null,null,							// nothing, Element
                null,"#text",						// Attr, Text
                "#cdata_section",null,	// CDATA, EntityReference
                null,null,							// Entity, PI
                "#comment","#document",	// Comment, Document
                null,"#document-fragment", // Doctype, DocumentFragment
                null};									// Notation

        /**
         * Given a node handle, return its DOM-style node name. This will
         * include names such as #text or #document.
         *
         * @param nodeHandle the id of the node.
         * @return String Name of this node, which may be an empty string.
         * %REVIEW% Document when empty string is possible...
         */
        public String getNodeName(int nodeHandle) {
                nodes.readSlot(nodeHandle, gotslot);
                short type = (short) (gotslot[0] & 0xFFFF);
                String name = fixednames[type];
                if (null == name) {
                  int i=gotslot[3];
                  /**/System.out.println("got i="+i+" "+(i>>16)+"/"+(i&0xffff));

                  name=m_localNames.indexToString(i & 0xFFFF);
                  String prefix=m_prefixNames.indexToString(i >>16);
                  if(prefix!=null && prefix.length()>0)
                    name=prefix+":"+name;
                }
                return name;
        }

        /**
         * Given a node handle, return the XPath node name.  This should be
         * the name as described by the XPath data model, NOT the DOM-style
         * name.
         *
         * @param nodeHandle the id of the node.
         * @return String Name of this node.
         */
        public String getNodeNameX(int nodeHandle) {return null;}

        /**
         * Given a node handle, return its DOM-style localname.
         * (As defined in Namespaces, this is the portion of the name after any
         * colon character)
         *
         * %REVIEW% What's the local name of something other than Element/Attr?
         * Should this be DOM-style (undefined unless namespaced), or other?
         *
         * @param nodeHandle the id of the node.
         * @return String Local name of this node.
         */
        public String getLocalName(int nodeHandle) {
                nodes.readSlot(nodeHandle, gotslot);
                short type = (short) (gotslot[0] & 0xFFFF);
                String name = "";
                if ((type==ELEMENT_NODE) || (type==ATTRIBUTE_NODE)) {
                  int i=gotslot[3];
                  name=m_localNames.indexToString(i & 0xFFFF);
                  if(name==null) name="";
                }
                return name;
        }

        /**
         * Given a namespace handle, return the prefix that the namespace decl is
         * mapping.
         * Given a node handle, return the prefix used to map to the namespace.
         *
         * <p> %REVIEW% Are you sure you want "" for no prefix?  </p>
         *
         * %REVIEW%  Should this be DOM-style (undefined unless namespaced),
         * or other?
         *
         * @param nodeHandle the id of the node.
         * @return String prefix of this node's name, or "" if no explicit
         * namespace prefix was given.
         */
        public String getPrefix(int nodeHandle) {
                nodes.readSlot(nodeHandle, gotslot);
                short type = (short) (gotslot[0] & 0xFFFF);
                String name = "";
                if((type==ELEMENT_NODE) || (type==ATTRIBUTE_NODE)) {
                  int i=gotslot[3];
                  name=m_prefixNames.indexToString(i >>16);
                  if(name==null) name="";
                }
                return name;
        }

        /**
         * Given a node handle, return its DOM-style namespace URI
         * (As defined in Namespaces, this is the declared URI which this node's
         * prefix -- or default in lieu thereof -- was mapped to.)
         *
         * @param nodeHandle the id of the node.
         * @return String URI value of this node's namespace, or null if no
         * namespace was resolved.
         */
        public String getNamespaceURI(int nodeHandle) {return null;}

        /**
         * Given a node handle, return its node value. This is mostly
         * as defined by the DOM, but may ignore some conveniences.
         * <p>
         *
         * @param nodeHandle The node id.
         * @return String Value of this node, or null if not
         * meaningful for this node type.
         */
        public String getNodeValue(int nodeHandle)
        {
                nodes.readSlot(nodeHandle, gotslot);
                int nodetype=gotslot[0] & 0xFF;		// ###zaj use mask to get node type
                String value=null;

                switch (nodetype) {			// ###zaj todo - document nodetypes
                case ATTRIBUTE_NODE:
                        nodes.readSlot(nodeHandle+1, gotslot);
                case TEXT_NODE:
                case COMMENT_NODE:
                case CDATA_SECTION_NODE:
                        value=m_char.getString(gotslot[2], gotslot[3]);		//###zaj
                        break;
                case PROCESSING_INSTRUCTION_NODE:
                case ELEMENT_NODE:
                case ENTITY_REFERENCE_NODE:
                default:
                        break;
                }
                return value;
        }

        /**
         * Given a node handle, return its DOM-style node type.
         * <p>
         * %REVIEW% Generally, returning short is false economy. Return int?
         *
         * @param nodeHandle The node id.
         * @return int Node type, as per the DOM's Node._NODE constants.
         */
        public short getNodeType(int nodeHandle) {
                return(short) (nodes.readEntry(nodeHandle, 0) & 0xFFFF);
        }

        /**
         * Get the depth level of this node in the tree (equals 1 for
         * a parentless node).
         *
         * @param nodeHandle The node id.
         * @return the number of ancestors, plus one
         * @xsl.usage internal
         */
        public short getLevel(int nodeHandle) {
                short count = 0;
                while (nodeHandle != 0) {
                        count++;
                        nodeHandle = nodes.readEntry(nodeHandle, 1);
                }
                return count;
        }

        // ============== Document query functions ==============

        /**
         * Tests whether DTM DOM implementation implements a specific feature and
         * that feature is supported by this node.
         *
         * @param feature The name of the feature to test.
         * @param versionThis is the version number of the feature to test.
         *   If the version is not
         *   specified, supporting any version of the feature will cause the
         *   method to return <code>true</code>.
         * @return Returns <code>true</code> if the specified feature is
         *   supported on this node, <code>false</code> otherwise.
         */
        public boolean isSupported(String feature, String version) {return false;}

        /**
         * Return the base URI of the document entity. If it is not known
         * (because the document was parsed from a socket connection or from
         * standard input, for example), the value of this property is unknown.
         *
         * @return the document base URI String object or null if unknown.
         */
        public String getDocumentBaseURI()
        {

          return m_documentBaseURI;
        }

        /**
         * Set the base URI of the document entity.
         *
         * @param baseURI the document base URI String object or null if unknown.
         */
        public void setDocumentBaseURI(String baseURI)
        {

          m_documentBaseURI = baseURI;
        }

        /**
         * Return the system identifier of the document entity. If
         * it is not known, the value of this property is unknown.
         *
         * @param nodeHandle The node id, which can be any valid node handle.
         * @return the system identifier String object or null if unknown.
         */
        public String getDocumentSystemIdentifier(int nodeHandle) {return null;}

        /**
         * Return the name of the character encoding scheme
         *        in which the document entity is expressed.
         *
         * @param nodeHandle The node id, which can be any valid node handle.
         * @return the document encoding String object.
         */
        public String getDocumentEncoding(int nodeHandle) {return null;}

        /**
         * Return an indication of the standalone status of the document,
         *        either "yes" or "no". This property is derived from the optional
         *        standalone document declaration in the XML declaration at the
         *        beginning of the document entity, and has no value if there is no
         *        standalone document declaration.
         *
         * @param nodeHandle The node id, which can be any valid node handle.
         * @return the document standalone String object, either "yes", "no", or null.
         */
        public String getDocumentStandalone(int nodeHandle) {return null;}

        /**
         * Return a string representing the XML version of the document. This
         * property is derived from the XML declaration optionally present at the
         * beginning of the document entity, and has no value if there is no XML
         * declaration.
         *
         * @param the document handle
         *
         * @return the document version String object
         */
        public String getDocumentVersion(int documentHandle) {return null;}

        /**
         * Return an indication of
         * whether the processor has read the complete DTD. Its value is a
         * boolean. If it is false, then certain properties (indicated in their
         * descriptions below) may be unknown. If it is true, those properties
         * are never unknown.
         *
         * @return <code>true</code> if all declarations were processed {};
         *         <code>false</code> otherwise.
         */
        public boolean getDocumentAllDeclarationsProcessed() {return false;}

        /**
         *   A document type declaration information item has the following properties:
         *
         *     1. [system identifier] The system identifier of the external subset, if
         *        it exists. Otherwise this property has no value.
         *
         * @return the system identifier String object, or null if there is none.
         */
        public String getDocumentTypeDeclarationSystemIdentifier() {return null;}

        /**
         * Return the public identifier of the external subset,
         * normalized as described in 4.2.2 External Entities [XML]. If there is
         * no external subset or if it has no public identifier, this property
         * has no value.
         *
         * @param the document type declaration handle
         *
         * @return the public identifier String object, or null if there is none.
         */
        public String getDocumentTypeDeclarationPublicIdentifier() {return null;}

        /**
         * Returns the <code>Element</code> whose <code>ID</code> is given by
         * <code>elementId</code>. If no such element exists, returns
         * <code>DTM.NULL</code>. Behavior is not defined if more than one element
         * has this <code>ID</code>. Attributes (including those
         * with the name "ID") are not of type ID unless so defined by DTD/Schema
         * information available to the DTM implementation.
         * Implementations that do not know whether attributes are of type ID or
         * not are expected to return <code>DTM.NULL</code>.
         *
         * <p>%REVIEW% Presumably IDs are still scoped to a single document,
         * and this operation searches only within a single document, right?
         * Wouldn't want collisions between DTMs in the same process.</p>
         *
         * @param elementId The unique <code>id</code> value for an element.
         * @return The handle of the matching element.
         */
        public int getElementById(String elementId) {return 0;}

        /**
         * 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.
         * <p>
         * XML processors may choose to use the System Identifier (if one
         * is provided) to resolve the entity, rather than the URI in the
         * Public Identifier. The details are dependent on the processor, and
         * we would have to support some form of plug-in resolver to handle
         * this properly. Currently, we simply return the System Identifier if
         * present, and hope that it a usable URI or that our caller can
         * map it to one.
         * TODO: Resolve Public Identifiers... or consider changing function name.
         * <p>
         * If we find a relative URI
         * reference, XML expects it to be resolved in terms of the base URI
         * of the document. The DOM doesn't do that for us, and it isn't
         * entirely clear whether that should be done here; currently that's
         * pushed up to a higher level of our application. (Note that DOM Level
         * 1 didn't store the document's base URI.)
         * TODO: Consider resolving Relative URIs.
         * <p>
         * (The DOM's statement that "An XML processor may choose to
         * completely expand entities before the structure model is passed
         * to the DOM" refers only to parsed entities, not unparsed, and hence
         * doesn't affect this function.)
         *
         * @param name A string containing the Entity Name of the unparsed
         * entity.
         *
         * @return String containing the URI of the Unparsed Entity, or an
         * empty string if no such entity exists.
         */
        public String getUnparsedEntityURI(String name) {return null;}


        // ============== Boolean methods ================

        /**
         * Return true if the xsl:strip-space or xsl:preserve-space was processed
         * during construction of the DTM document.
         *
         * <p>%REVEIW% Presumes a 1:1 mapping from DTM to Document, since
         * we aren't saying which Document to query...?</p>
         */
        public boolean supportsPreStripping() {return false;}

        /**
         * Figure out whether nodeHandle2 should be considered as being later
         * in the document than nodeHandle1, in Document Order as defined
         * by the XPath model. This may not agree with the ordering defined
         * by other XML applications.
         * <p>
         * There are some cases where ordering isn't defined, and neither are
         * the results of this function -- though we'll generally return true.
         *
         * TODO: Make sure this does the right thing with attribute nodes!!!
         *
         * @param node1 DOM Node to perform position comparison on.
         * @param node2 DOM Node to perform position comparison on .
         *
         * @return false if node2 comes before node1, otherwise return true.
         * You can think of this as
         * <code>(node1.documentOrderPosition &lt;= node2.documentOrderPosition)</code>.
         */
        public boolean isNodeAfter(int nodeHandle1, int nodeHandle2) {return false;}

        /**
         *     2. [element content whitespace] A boolean indicating whether the
         *        character is white space appearing within element content (see [XML],
         *        2.10 "White Space Handling"). Note that validating XML processors are
         *        required by XML 1.0 to provide this information. If there is no
         *        declaration for the containing element, this property has no value for
         *        white space characters. If no declaration has been read, but the [all
         *        declarations processed] property of the document information item is
         *        false (so there may be an unread declaration), then the value of this
         *        property is unknown for white space characters. It is always false for
         *        characters that are not white space.
         *
         * @param nodeHandle the node ID.
         * @return <code>true</code> if the character data is whitespace;
         *         <code>false</code> otherwise.
         */
        public boolean isCharacterElementContentWhitespace(int nodeHandle) {return false;}

        /**
         *    10. [all declarations processed] This property is not strictly speaking
         *        part of the infoset of the document. Rather it is an indication of
         *        whether the processor has read the complete DTD. Its value is a
         *        boolean. If it is false, then certain properties (indicated in their
         *        descriptions below) may be unknown. If it is true, those properties
         *        are never unknown.
         *
         * @param the document handle
         *
         * @param documentHandle A node handle that must identify a document.
         * @return <code>true</code> if all declarations were processed;
         *         <code>false</code> otherwise.
         */
        public boolean isDocumentAllDeclarationsProcessed(int documentHandle) {return false;}

        /**
         *     5. [specified] A flag indicating whether this attribute was actually
         *        specified in the start-tag of its element, or was defaulted from the
         *        DTD.
         *
         * @param the attribute handle
         *
         * NEEDSDOC @param attributeHandle
         * @return <code>true</code> if the attribute was specified;
         *         <code>false</code> if it was defaulted.
         */
        public boolean isAttributeSpecified(int attributeHandle) {return false;}

        // ========== Direct SAX Dispatch, for optimization purposes ========

        /**
         * Directly call the
         * characters method on the passed ContentHandler for the
         * string-value of the given node (see http://www.w3.org/TR/xpath#data-model
         * for the definition of a node's string-value). Multiple calls to the
         * ContentHandler's characters methods may well occur for a single call to
         * this method.
         *
         * @param nodeHandle The node ID.
         * @param ch A non-null reference to a ContentHandler.
         *
         * @throws org.xml.sax.SAXException
         */
        public void dispatchCharactersEvents(
                                                                                                                                                        int nodeHandle, org.xml.sax.ContentHandler ch, boolean normalize)
        throws org.xml.sax.SAXException {}

        /**
         * Directly create SAX parser events from a subtree.
         *
         * @param nodeHandle The node ID.
         * @param ch A non-null reference to a ContentHandler.
         *
         * @throws org.xml.sax.SAXException
         */

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

        /**
         * Return an DOM node for the given node.
         *
         * @param nodeHandle The node ID.
         *
         * @return A node representation of the DTM node.
         */
        public org.w3c.dom.Node getNode(int nodeHandle)
        {
          return null;
        }

        // ==== Construction methods (may not be supported by some implementations!) =====
        // %REVIEW% jjk: These probably aren't the right API. At the very least
        // they need to deal with current-insertion-location and end-element
        // issues.

        /**
         * Append a child to the end of the child list of the current node. Please note that the node
         * is always cloned if it is owned by another document.
         *
         * <p>%REVIEW% "End of the document" needs to be defined more clearly.
         * Does it become the last child of the Document? Of the root element?</p>
         *
         * @param newChild Must be a valid new node handle.
         * @param clone true if the child should be cloned into the document.
         * @param cloneDepth if the clone argument is true, specifies that the
         *                   clone should include all it's children.
         */
        public void appendChild(int newChild, boolean clone, boolean cloneDepth) {
                boolean sameDoc = ((newChild & DOCHANDLE_MASK) == m_docHandle);
                if (clone || !sameDoc) {

                } else {

                }
        }

        /**
         * Append a text node child that will be constructed from a string,
         * to the end of the document.
         *
         * <p>%REVIEW% "End of the document" needs to be defined more clearly.
         * Does it become the last child of the Document? Of the root element?</p>
         *
         * @param str Non-null reference to a string.
         */
        public void appendTextChild(String str) {
                // ###shs Think more about how this differs from createTextNode
          //%TBD%
        }


  //================================================================
  // ==== BUILDER methods ====
  // %TBD% jjk: SHOULD PROBABLY BE INLINED, unless we want to support
  // both SAX1 and SAX2 and share this logic between them.

  /** Append a text child at the current insertion point. Assumes that the
   * actual content of the text has previously been appended to the m_char
   * buffer (shared with the builder).
   *
   * @param m_char_current_start int Starting offset of node's content in m_char.
   * @param contentLength int Length of node's content in m_char.
   * */
  void appendTextChild(int m_char_current_start,int contentLength)
  {
    // create a Text Node
    // %TBD% may be possible to combine with appendNode()to replace the next chunk of code
    int w0 = TEXT_NODE;
    // W1: Parent
    int w1 = currentParent;
    // W2: Start position within m_char
    int w2 = m_char_current_start;
    // W3: Length of the full string
    int w3 = contentLength;

    int ourslot = appendNode(w0, w1, w2, w3);
    previousSibling = ourslot;
  }

  /** Append a comment child at the current insertion point. Assumes that the
   * actual content of the comment has previously been appended to the m_char
   * buffer (shared with the builder).
   *
   * @param m_char_current_start int Starting offset of node's content in m_char.
   * @param contentLength int Length of node's content in m_char.
   * */
  void appendComment(int m_char_current_start,int contentLength)
  {
    // create a Comment Node
    // %TBD% may be possible to combine with appendNode()to replace the next chunk of code
    int w0 = COMMENT_NODE;
    // W1: Parent
    int w1 = currentParent;
    // W2: Start position within m_char
    int w2 = m_char_current_start;
    // W3: Length of the full string
    int w3 = contentLength;

    int ourslot = appendNode(w0, w1, w2, w3);
    previousSibling = ourslot;
  }


  /** Append an Element child at the current insertion point. This
   * Element then _becomes_ the insertion point; subsequent appends
   * become its lastChild until an appendEndElement() call is made.
   *
   * Assumes that the symbols (local name, namespace URI and prefix)
   * have already been added to the pools
   *
   * Note that this _only_ handles the Element node itself. Attrs and
   * namespace nodes are unbundled in the ContentHandler layer
   * and appended separately.
   *
   * @param namespaceIndex: Index within the namespaceURI string pool
   * @param localNameIndex Index within the local name string pool
   * @param prefixIndex: Index within the prefix string pool
   * */
  void appendStartElement(int namespaceIndex,int localNameIndex, int prefixIndex)
  {
                // do document root node creation here on the first element, create nodes for
                // this element and its attributes, store the element, namespace, and attritute
                // name indexes to the nodes array, keep track of the current node and parent
                // element used

                // W0  High:  Namespace  Low:  Node Type
                int w0 = (namespaceIndex << 16) | ELEMENT_NODE;
                // W1: Parent
                int w1 = currentParent;
                // W2: Next  (initialized as 0)
                int w2 = 0;
                // W3: Tagname high: prefix Low: local name
                int w3 = localNameIndex | prefixIndex<<16;
                /**/System.out.println("set w3="+w3+" "+(w3>>16)+"/"+(w3&0xffff));

                //int ourslot = nodes.appendSlot(w0, w1, w2, w3);
                int ourslot = appendNode(w0, w1, w2, w3);
                currentParent = ourslot;
                previousSibling = 0;

                // set the root element pointer when creating the first element node
                if (m_docElement == NULL)
                        m_docElement = ourslot;
  }

  /** Append a Namespace Declaration child at the current insertion point.
   * Assumes that the symbols (namespace URI and prefix) have already been
   * added to the pools
   *
   * @param prefixIndex: Index within the prefix string pool
   * @param namespaceIndex: Index within the namespaceURI string pool
   * @param isID: If someone really insists on writing a bad DTD, it is
   * theoretically possible for a namespace declaration to also be declared
   * as being a node ID. I don't really want to support that stupidity,
   * but I'm not sure we can refuse to accept it.
   * */
  void appendNSDeclaration(int prefixIndex, int namespaceIndex,
                           boolean isID)
  {
    // %REVIEW% I'm assigning this node the "namespace for namespaces"
    // which the DOM defined. It is expected that the Namespace spec will
    // adopt this as official. It isn't strictly needed since it's implied
    // by the nodetype, but for now...

    // %REVIEW% Prefix need not be recorded; it's implied too. But
    // recording it might simplify the design.

    // %TBD% isID is not currently honored.

    final int namespaceForNamespaces=m_nsNames.stringToIndex("http://www.w3.org/2000/xmlns/");

    // W0  High:  Namespace  Low:  Node Type
    int w0 = NAMESPACE_NODE | (m_nsNames.stringToIndex("http://www.w3.org/2000/xmlns/")<<16);

    // W1:  Parent
    int w1 = currentParent;
    // W2:  CURRENTLY UNUSED -- It's next-sib in attrs, but we have no kids.
    int w2 = 0;
    // W3:  namespace name
    int w3 = namespaceIndex;
    // Add node
    int ourslot = appendNode(w0, w1, w2, w3);
    previousSibling = ourslot;	// Should attributes be previous siblings
    previousSiblingWasParent = false;
    return ;//(m_docHandle | ourslot);
  }

  /** Append an Attribute child at the current insertion
   * point.  Assumes that the symbols (namespace URI, local name, and
   * prefix) have already been added to the pools, and that the content has
   * already been appended to m_char. Note that the attribute's content has
   * been flattened into a single string; DTM does _NOT_ attempt to model
   * the details of entity references within attribute values.
   *
   * @param namespaceIndex int Index within the namespaceURI string pool
   * @param localNameIndex int Index within the local name string pool
   * @param prefixIndex int Index within the prefix string pool
   * @param isID boolean True if this attribute was declared as an ID
   * (for use in supporting getElementByID).
   * @param m_char_current_start int Starting offset of node's content in m_char.
   * @param contentLength int Length of node's content in m_char.
   * */
  void appendAttribute(int namespaceIndex, int localNameIndex, int prefixIndex,
                       boolean isID,
                       int m_char_current_start, int contentLength)
  {
    // %TBD% isID is not currently honored.

    // W0  High:  Namespace  Low:  Node Type
    int w0 = ATTRIBUTE_NODE | namespaceIndex<<16;

    // W1:  Parent
    int w1 = currentParent;
    // W2:  Next (not yet resolved)
    int w2 = 0;
    // W3:  Tagname high: prefix Low: local name
    int w3 = localNameIndex | prefixIndex<<16;
    /**/System.out.println("set w3="+w3+" "+(w3>>16)+"/"+(w3&0xffff));
    // Add node
    int ourslot = appendNode(w0, w1, w2, w3);
    previousSibling = ourslot;	// Should attributes be previous siblings

    // Attribute's content is currently appended as a Text Node

    // W0: Node Type
    w0 = TEXT_NODE;
    // W1: Parent
    w1 = ourslot;
    // W2: Start Position within buffer
    w2 = m_char_current_start;
    // W3: Length
    w3 = contentLength;
    appendNode(w0, w1, w2, w3);

    // Attrs are Parents
    previousSiblingWasParent = true;
    return ;//(m_docHandle | ourslot);
  }

  /**
   * This returns a stateless "traverser", that can navigate over an
   * XPath axis, though not in document order.
   *
   * @param axis One of Axes.ANCESTORORSELF, etc.
   *
   * @return A DTMAxisIterator, or null if the given axis isn't supported.
   */
  public DTMAxisTraverser getAxisTraverser(final int axis)
  {
    return null;
  }

  /**
   * 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()).
   *
   * @param axis One of Axes.ANCESTORORSELF, etc.
   *
   * @return A DTMAxisIterator, or null if the given axis isn't supported.
   */
  public DTMAxisIterator getAxisIterator(final int axis)
  {
    // %TBD%
    return null;
  }

  /**
   * Get an iterator that can navigate over an XPath Axis, predicated by
   * the extended type ID.
   *
   *
   * @param axis
   * @param type An extended type ID.
   *
   * @return A DTMAxisIterator, or null if the given axis isn't supported.
   */
  public DTMAxisIterator getTypedAxisIterator(final int axis, final int type)
  {
    // %TBD%
    return null;
  }


  /** Terminate the element currently acting as an insertion point. Subsequent
   * insertions will occur as the last child of this element's parent.
   * */
  void appendEndElement()
  {
    // pop up the stacks

    if (previousSiblingWasParent)
      nodes.writeEntry(previousSibling, 2, NULL);

    // Pop parentage
    previousSibling = currentParent;
    nodes.readSlot(currentParent, gotslot);
    currentParent = gotslot[1] & 0xFFFF;

    // The element just being finished will be
    // the previous sibling for the next operation
    previousSiblingWasParent = true;

    // Pop a level of namespace table
    // namespaceTable.removeLastElem();
  }

  /**  Starting a new document. Perform any resets/initialization
   * not already handled.
   * */
  void appendStartDocument()
  {

    // %TBD% reset slot 0 to indicate ChunkedIntArray reuse or wait for
    //       the next initDocument().
    m_docElement = NULL;	 // reset nodeHandle to the root of the actual dtm doc content
    initDocument(0);
  }

  /**  All appends to this document have finished; do whatever final
   * cleanup is needed.
   * */
  void appendEndDocument()
  {
    done = true;
    // %TBD% may need to notice the last slot number and slot count to avoid
    // residual data from provious use of this DTM
  }

  /**
   * For the moment all the run time properties are ignored by this
   * class.
   *
   * @param property a <code>String</code> value
   * @param value an <code>Object</code> value
   */
  public void setProperty(String property, Object value)
  {
  }

  /**
   * Source information is not handled yet, so return
   * <code>null</code> here.
   *
   * @param node an <code>int</code> value
   * @return null
   */
  public SourceLocator getSourceLocatorFor(int node)
  {
    return null;
  }


  /**
   * A dummy routine to satisify the abstract interface. If the DTM
   * implememtation that extends the default base requires notification
   * of registration, they can override this method.
   */
   public void documentRegistration()
   {
   }

  /**
   * A dummy routine to satisify the abstract interface. If the DTM
   * implememtation that extends the default base requires notification
   * when the document is being released, they can override this method
   */
   public void documentRelease()
   {
   }

   /**
    * 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)
   {
   }

}
