diff --git a/src/org/apache/xalan/transformer/NodeSortKey.java b/src/org/apache/xalan/transformer/NodeSortKey.java
deleted file mode 100644
index f6d9d79..0000000
--- a/src/org/apache/xalan/transformer/NodeSortKey.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 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.xalan.transformer;
-
-import java.util.Locale;
-
-import org.apache.xpath.XPath;
-
-import java.text.Collator;
-
-import org.apache.xalan.res.XSLTErrorResources;
-
-/**
- * <meta name="usage" content="internal"/>
- * Data structure for use by the NodeSorter class.
- */
-class NodeSortKey
-{
-
-  /** Select pattern for this sort key          */
-  XPath m_selectPat;
-
-  /** Flag indicating whether to treat thee result as a number     */
-  boolean m_treatAsNumbers;
-
-  /** Flag indicating whether to sort in descending order      */
-  boolean m_descending;
-
-  /** Flag indicating by case          */
-  boolean m_caseOrderUpper;
-
-  /** Collator instance          */
-  Collator m_col;
-
-  /** Locale we're in          */
-  Locale m_locale;
-
-  /** Prefix resolver to use          */
-  org.apache.xml.utils.PrefixResolver m_namespaceContext;
-
-  /** Transformer instance          */
-  TransformerImpl m_processor;  // needed for error reporting.
-
-  /**
-   * Constructor NodeSortKey
-   *
-   *
-   * @param transformer non null transformer instance
-   * @param selectPat Select pattern for this key 
-   * @param treatAsNumbers Flag indicating whether the result will be a number
-   * @param descending Flag indicating whether to sort in descending order
-   * @param langValue Lang value to use to get locale
-   * @param caseOrderUpper Flag indicating whether case is relevant
-   * @param namespaceContext Prefix resolver
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  NodeSortKey(
-          TransformerImpl transformer, XPath selectPat, boolean treatAsNumbers, 
-          boolean descending, String langValue, boolean caseOrderUpper, 
-          org.apache.xml.utils.PrefixResolver namespaceContext)
-            throws javax.xml.transform.TransformerException
-  {
-
-    m_processor = transformer;
-    m_namespaceContext = namespaceContext;
-    m_selectPat = selectPat;
-    m_treatAsNumbers = treatAsNumbers;
-    m_descending = descending;
-    m_caseOrderUpper = caseOrderUpper;
-
-    if (null != langValue && m_treatAsNumbers == false)
-    {
-      // See http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2851
-      // The constructor of Locale is defined as 
-      //   public Locale(String language, String country)
-      // with
-      //   language - lowercase two-letter ISO-639 code
-      //   country - uppercase two-letter ISO-3166 code
-      // a) language must be provided as a lower-case ISO-code 
-      //    instead of an upper-case code
-      // b) country must be provided as an ISO-code 
-      //    instead of a full localized country name (e.g. "France")
-      m_locale = new Locale(langValue.toLowerCase(), 
-                  Locale.getDefault().getCountry());
-                  
-      // (old, before bug report 2851).
-      //  m_locale = new Locale(langValue.toUpperCase(),
-      //                        Locale.getDefault().getDisplayCountry());                    
-
-      if (null == m_locale)
-      {
-
-        // m_processor.warn("Could not find locale for <sort xml:lang="+langValue);
-        m_locale = Locale.getDefault();
-      }
-    }
-    else
-    {
-      m_locale = Locale.getDefault();
-    }
-
-    m_col = Collator.getInstance(m_locale);
-
-    if (null == m_col)
-    {
-      m_processor.getMsgMgr().warn(null, XSLTErrorResources.WG_CANNOT_FIND_COLLATOR,
-                                   new Object[]{ langValue });  //"Could not find Collator for <sort xml:lang="+langValue);
-
-      m_col = Collator.getInstance();
-    }
-  }
-}
diff --git a/src/org/apache/xml/dtm/ref/sax2dtm/SAX2RTFDTM.java b/src/org/apache/xml/dtm/ref/sax2dtm/SAX2RTFDTM.java
deleted file mode 100644
index bd22ded..0000000
--- a/src/org/apache/xml/dtm/ref/sax2dtm/SAX2RTFDTM.java
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 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.sax2dtm;
-
-import java.util.Hashtable;
-import java.util.Vector;
-import javax.xml.transform.Source;
-import javax.xml.transform.SourceLocator;
-import org.apache.xalan.transformer.XalanProperties;
-import org.apache.xalan.res.XSLTErrorResources;
-import org.apache.xalan.res.XSLMessages;
-
-import org.apache.xml.dtm.*;
-import org.apache.xml.dtm.ref.*;
-import org.apache.xml.utils.StringVector;
-import org.apache.xml.utils.IntVector;
-import org.apache.xml.utils.FastStringBuffer;
-import org.apache.xml.utils.IntStack;
-import org.apache.xml.utils.SuballocatedIntVector;
-import org.apache.xml.utils.SystemIDResolver;
-import org.apache.xml.utils.WrappedRuntimeException;
-import org.apache.xml.utils.XMLCharacterRecognizer;
-import org.apache.xml.utils.XMLString;
-import org.apache.xml.utils.XMLStringFactory;
-import org.xml.sax.*;
-import org.xml.sax.ext.*;
-
-/**
- * This is a subclass of SAX2DTM which has been modified to meet the needs of
- * Result Tree Frameworks (RTFs). The differences are:
- *
- * 1) Multiple XML trees may be appended to the single DTM. This means
- * that the root node of each document is _not_ node 0. Some code has
- * had to be deoptimized to support this mode of operation, and an
- * explicit mechanism for obtaining the Node Handle of the root node
- * has been provided.
- *
- * 2) A stack of these documents is maintained, allowing us to "tail-prune" the
- * most recently added trees off the end of the DTM as stylesheet elements 
- * (and thus variable contexts) are exited.
- *
- * PLEASE NOTE that this class may be _heavily_ dependent upon the
- * internals of the SAX2DTM superclass, and must be maintained in
- * parallel with that code.  Arguably, they should be conditionals
- * within a single class... but they have deen separated for
- * performance reasons. (In fact, one could even argue about which is
- * the superclass and which is the subclass; the current arrangement
- * is as much about preserving stability of existing code during
- * development as anything else.)
- * 
- * %REVIEW% In fact, since the differences are so minor, I think it
- * may be possible/practical to fold them back into the base
- * SAX2DTM. Consider that as a future code-size optimization.
- * */
-public class SAX2RTFDTM extends SAX2DTM
-{
-  /** Set true to monitor SAX events and similar diagnostic info. */
-  private static final boolean DEBUG = false;
-  
-  /** Most recently started Document, or null if the DTM is empty.  */
-  private int m_currentDocumentNode=NULL;
-  
-  /** Tail-pruning mark: Number of nodes in use */
-  IntStack mark_size=new IntStack();
-  /** Tail-pruning mark: Number of data items in use */
-  IntStack mark_data_size=new IntStack();
-  /** Tail-pruning mark: Number of size-of-data fields in use */
-  IntStack mark_char_size=new IntStack();
-  /** Tail-pruning mark: Number of dataOrQName slots in use */
-  IntStack mark_doq_size=new IntStack();
-  /** Tail-pruning mark: Number of namespace declaration sets in use
-   * %REVIEW% I don't think number of NS sets is ever different from number
-   * of NS elements. We can probabably reduce these to a single stack and save
-   * some storage.
-   * */
-  IntStack mark_nsdeclset_size=new IntStack();
-  /** Tail-pruning mark: Number of naespace declaration elements in use
-   * %REVIEW% I don't think number of NS sets is ever different from number
-   * of NS elements. We can probabably reduce these to a single stack and save
-   * some storage.
-   */
-  IntStack mark_nsdeclelem_size=new IntStack();
-  
-  public SAX2RTFDTM(DTMManager mgr, Source source, int dtmIdentity,
-                 DTMWSFilter whiteSpaceFilter,
-                 XMLStringFactory xstringfactory,
-                 boolean doIndexing)
-  {
-    super(mgr, source, dtmIdentity, whiteSpaceFilter, 
-          xstringfactory, doIndexing);
-          
-    // NEVER track source locators for RTFs; they aren't meaningful. I think.
-    // (If we did track them, we'd need to tail-prune these too.)
-    m_useSourceLocationProperty=false; //org.apache.xalan.processor.TransformerFactoryImpl.m_source_location;
-    m_sourceSystemId = (m_useSourceLocationProperty) ? new StringVector() : null;
- 	m_sourceLine = (m_useSourceLocationProperty) ?  new IntVector() : null;
-    m_sourceColumn = (m_useSourceLocationProperty) ?  new IntVector() : null;
-    
-  }
-  
-  /**
-   * Given a DTM, find the owning document node. In the case of
-   * SAX2RTFDTM, which may contain multiple documents, this returns
-   * the <b>most recently started</b> document, or null if the DTM is
-   * empty or no document is currently under construction.
-   *
-   * %REVIEW% Should we continue to report the most recent after
-   * construction has ended? I think not, given that it may have been
-   * tail-pruned.
-   *
-   *  @param nodeHandle the id of the node.
-   *  @return int Node handle of Document node, or null if this DTM does not
-   *  contain an "active" document.
-   * */
-  public int getDocument()
-  {
-    return makeNodeHandle(m_currentDocumentNode);
-  }
-
-  /**
-   * Given a node handle, find the owning document node, using DTM semantics
-   * (Document owns itself) rather than DOM semantics (Document has no owner).
-   *
-   * (I'm counting on the fact that getOwnerDocument() is implemented on top
-   * of this call, in the superclass, to avoid having to rewrite that one.
-   * Be careful if that code changes!)
-   *
-   * @param nodeHandle the id of the node.
-   * @return int Node handle of owning document
-   */
-  public int getDocumentRoot(int nodeHandle)
-  {
-    for(int id=makeNodeIdentity(nodeHandle);
-		id!=NULL;
-		id=_parent(id))
-		if(_type(id)==DTM.DOCUMENT_NODE)
-  			return makeNodeHandle(id);
-
-    return DTM.NULL; // Safety net; should never happen
-  }
-  
-  /**
-   * Given a node identifier, find the owning document node.  Unlike the DOM,
-   * this considers the owningDocument of a Document to be itself. Note that
-   * in shared DTMs this may not be zero.
-   *
-   * @param nodeIdentifier the id of the starting node.
-   * @return int Node identifier of the root of this DTM tree
-   */
-  protected int _documentRoot(int nodeIdentifier)
-  {
-  	if(nodeIdentifier==NULL) return NULL;
-  	
-    for(int parent=_parent(nodeIdentifier);
-    	parent!=NULL;
-    	nodeIdentifier=parent,parent=_parent(nodeIdentifier))
-    	;
-    
-    return nodeIdentifier;
-  }
-
-  /**
-   * Receive notification of the beginning of a new RTF document.
-   *
-   * %REVIEW% Y'know, this isn't all that much of a deoptimization. We
-   * might want to consider folding the start/endDocument changes back
-   * into the main SAX2DTM so we don't have to expose so many fields
-   * (even as Protected) and carry the additional code.
-   *
-   * @throws SAXException Any SAX exception, possibly
-   *            wrapping another exception. 
-   * @see org.xml.sax.ContentHandler#startDocument
-   * */
-  public void startDocument() throws SAXException
-  {
-    // Re-initialize the tree append process
-    m_endDocumentOccured = false;
-    m_prefixMappings = new java.util.Vector();
-    m_contextIndexes = new IntStack();
-    m_parents = new IntStack();
-    
-    m_currentDocumentNode=m_size;
-    super.startDocument();
-  }
-  
-  /**
-   * Receive notification of the end of the document.
-   *
-   * %REVIEW% Y'know, this isn't all that much of a deoptimization. We
-   * might want to consider folding the start/endDocument changes back
-   * into the main SAX2DTM so we don't have to expose so many fields
-   * (even as Protected).
-   *
-   * @throws SAXException Any SAX exception, possibly
-   *            wrapping another exception.
-   * @see org.xml.sax.ContentHandler#endDocument
-   * */
-  public void endDocument() throws SAXException
-  {
-    charactersFlush();
-
-    m_nextsib.setElementAt(NULL,m_currentDocumentNode);
-
-    if (m_firstch.elementAt(m_currentDocumentNode) == NOTPROCESSED)
-      m_firstch.setElementAt(NULL,m_currentDocumentNode);
-
-    if (DTM.NULL != m_previous)
-      m_nextsib.setElementAt(DTM.NULL,m_previous);
-
-    m_parents = null;
-    m_prefixMappings = null;
-    m_contextIndexes = null;
-
-    m_currentDocumentNode= NULL; // no longer open
-    m_endDocumentOccured = true;
-  }
-  
-
-  /** "Tail-pruning" support for RTFs.
-   * 
-   * This function pushes information about the current size of the
-   * DTM's data structures onto a stack, for use by popRewindMark()
-   * (which see).
-   * 
-   * %REVIEW% I have no idea how to rewind m_elemIndexes. However,
-   * RTFs will not be indexed, so I can simply panic if that case
-   * arises. Hey, it works...
-   * */
-  public void pushRewindMark()
-  {
-    if(m_indexing || m_elemIndexes!=null) 
-      throw new java.lang.NullPointerException("Coding error; Don't try to mark/rewind an indexed DTM");
-
-    // Values from DTMDefaultBase
-    // %REVIEW% Can the namespace stack sizes ever differ? If not, save space!
-    mark_size.push(m_size);
-    mark_nsdeclset_size.push( (m_namespaceDeclSets==null) ? 0 : m_namespaceDeclSets.size() );
-    mark_nsdeclelem_size.push( (m_namespaceDeclSetElements==null) ? 0 : m_namespaceDeclSetElements.size() );
-    
-    // Values from SAX2DTM
-    mark_data_size.push(m_data.size());
-    mark_char_size.push(m_chars.size());
-    mark_doq_size.push(m_dataOrQName.size());	
-  }
-  
-  /** "Tail-pruning" support for RTFs.
-   * 
-   * This function pops the information previously saved by
-   * pushRewindMark (which see) and uses it to discard all nodes added
-   * to the DTM after that time. We expect that this will allow us to
-   * reuse storage more effectively.
-   * 
-   * This is _not_ intended to be called while a document is still being
-   * constructed -- only between endDocument and the next startDocument
-   * 
-   * %REVIEW% WARNING: This is the first use of some of the truncation
-   * methods.  If Xalan blows up after this is called, that's a likely
-   * place to check.
-   * 
-   * %REVIEW% Our original design for DTMs permitted them to share
-   * string pools.  If there any risk that this might be happening, we
-   * can _not_ rewind and recover the string storage. One solution
-   * might to assert that DTMs used for RTFs Must Not take advantage
-   * of that feature, but this seems excessively fragile. Another, much
-   * less attractive, would be to just let them leak... Nah.
-   * 
-   * @return true if and only if the pop completely emptied the
-   * RTF. That response is used when determining how to unspool
-   * RTF-started-while-RTF-open situations.
-   * */
-  public boolean popRewindMark()
-  {
-    boolean top=mark_size.empty();
-    
-    m_size=top ? 0 : mark_size.pop();
-    m_exptype.setSize(m_size);
-    m_firstch.setSize(m_size);
-    m_nextsib.setSize(m_size);
-    m_prevsib.setSize(m_size);
-    m_parent.setSize(m_size);
-
-    m_elemIndexes=null;
-
-    int ds= top ? 0 : mark_nsdeclset_size.pop();
-    if (m_namespaceDeclSets!=null)
-      m_namespaceDeclSets.setSize(ds);
-      
-    int ds1= top ? 0 : mark_nsdeclelem_size.pop();
-    if (m_namespaceDeclSetElements!=null)
-      m_namespaceDeclSetElements.setSize(ds1);
-  
-    // Values from SAX2DTM
-    m_data.setSize(top ? 0 : mark_data_size.pop());
-    m_chars.setLength(top ? 0 : mark_char_size.pop());
-    m_dataOrQName.setSize(top ? 0 : mark_doq_size.pop());
-
-    // Return true iff DTM now empty
-    return m_size==0;
-  }
-  
-  /** @return true if a DTM tree is currently under construction.
-   * */
-  public boolean isTreeIncomplete()
-  {
-  	return !m_endDocumentOccured;
-  	
-  }
-}
diff --git a/src/org/apache/xml/utils/Hashtree2Node.java b/src/org/apache/xml/utils/Hashtree2Node.java
deleted file mode 100644
index 989ea79..0000000
--- a/src/org/apache/xml/utils/Hashtree2Node.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2002 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) 2000, 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.utils;
-
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.StringTokenizer;
-import java.util.Vector;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-/**
- * <meta name="usage" content="general"/>
- * Simple static utility to convert Hashtable to a Node.  
- *
- * Please maintain JDK 1.1.x compatibility; no Collections!
- *
- * @see org.apache.xalan.xslt.EnvironmentCheck
- * @see org.apache.xalan.lib.Extensions
- * @author shane_curcuru@us.ibm.com
- * @version $Id$
- */
-public abstract class Hashtree2Node
-{
-
-    /**
-     * Convert a Hashtable into a Node tree.  
-     * 
-     * <p>The hash may have either Hashtables as values (in which 
-     * case we recurse) or other values, in which case we print them 
-     * as &lt;item> elements, with a 'key' attribute with the value 
-     * of the key, and the element contents as the value.</p>
-     *
-     * <p>If args are null we simply return without doing anything. 
-     * If we encounter an error, we will attempt to add an 'ERROR' 
-     * Element with exception info; if that doesn't work we simply 
-     * return without doing anything else byt printStackTrace().</p>
-     *
-     * @param hash to get info from (may have sub-hashtables)
-     * @param name to use as parent element for appended node
-     * futurework could have namespace and prefix as well
-     * @param container Node to append our report to
-     * @param factory Document providing createElement, etc. services
-     */
-    public static void appendHashToNode(Hashtable hash, String name, 
-            Node container, Document factory)
-    {
-        // Required arguments must not be null
-        if ((null == container) || (null == factory) || (null == hash))
-        {
-            return;
-        }
-
-        // name we will provide a default value for
-        String elemName = null;
-        if ((null == name) || ("".equals(name)))
-            elemName = "appendHashToNode";
-        else
-            elemName = name;
-
-        try
-        {
-            Element hashNode = factory.createElement(elemName);
-            container.appendChild(hashNode);
-
-            Enumeration enum = hash.keys();
-            Vector v = new Vector();
-
-            while (enum.hasMoreElements())
-            {
-                Object key = enum.nextElement();
-                String keyStr = key.toString();
-                Object item = hash.get(key);
-
-                if (item instanceof Hashtable)
-                {
-                    // Ensure a pre-order traversal; add this hashes 
-                    //  items before recursing to child hashes
-                    // Save name and hash in two steps
-                    v.addElement(keyStr);
-                    v.addElement((Hashtable) item);
-                }
-                else
-                {
-                    try
-                    {
-                        // Add item to node
-                        Element node = factory.createElement("item");
-                        node.setAttribute("key", keyStr);
-                        node.appendChild(factory.createTextNode((String)item));
-                        hashNode.appendChild(node);
-                    }
-                    catch (Exception e)
-                    {
-                        Element node = factory.createElement("item");
-                        node.setAttribute("key", keyStr);
-                        node.appendChild(factory.createTextNode("ERROR: Reading " + key + " threw: " + e.toString()));
-                        hashNode.appendChild(node);
-                    }
-                }
-            }
-
-            // Now go back and do the saved hashes
-            enum = v.elements();
-            while (enum.hasMoreElements())
-            {
-                // Retrieve name and hash in two steps
-                String n = (String) enum.nextElement();
-                Hashtable h = (Hashtable) enum.nextElement();
-
-                appendHashToNode(h, n, hashNode, factory);
-            }
-        }
-        catch (Exception e2)
-        {
-            // Ooops, just bail (suggestions for a safe thing 
-            //  to do in this case appreciated)
-            e2.printStackTrace();
-        }
-    }    
-}
diff --git a/src/org/apache/xml/utils/XMLChar.java b/src/org/apache/xml/utils/XMLChar.java
deleted file mode 100644
index 7064878..0000000
--- a/src/org/apache/xml/utils/XMLChar.java
+++ /dev/null
@@ -1,681 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999-2002 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 "Xerces" 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, International
- * Business Machines, Inc., http://www.apache.org.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-package org.apache.xml.utils;
-
-/**
- * This class defines the basic XML character properties. The data
- * in this class can be used to verify that a character is a valid
- * XML character or if the character is a space, name start, or name
- * character.
- * <p>
- * A series of convenience methods are supplied to ease the burden
- * of the developer. Because inlining the checks can improve per
- * character performance, the tables of character properties are
- * public. Using the character as an index into the <code>CHARS</code>
- * array and applying the appropriate mask flag (e.g.
- * <code>MASK_VALID</code>), yields the same results as calling the
- * convenience methods. There is one exception: check the comments
- * for the <code>isValid</code> method for details.
- *
- * @author Glenn Marcy, IBM
- * @author Andy Clark, IBM
- * @author Eric Ye, IBM
- * @author Arnaud  Le Hors, IBM
- * @author Rahul Srivastava, Sun Microsystems Inc.
- *
- * @version $Id: XMLChar.java,v 1.7 2002/01/29 01:15:18 lehors Exp $
- */
-public class XMLChar {
-
-    //
-    // Constants
-    //
-
-    /** Character flags. */
-    public static final byte[] CHARS = new byte[1 << 16];
-
-    /** Valid character mask. */
-    public static final int MASK_VALID = 0x01;
-
-    /** Space character mask. */
-    public static final int MASK_SPACE = 0x02;
-
-    /** Name start character mask. */
-    public static final int MASK_NAME_START = 0x04;
-
-    /** Name character mask. */
-    public static final int MASK_NAME = 0x08;
-
-    /** Pubid character mask. */
-    public static final int MASK_PUBID = 0x10;
-    
-    /** 
-     * Content character mask. Special characters are those that can
-     * be considered the start of markup, such as '&lt;' and '&amp;'. 
-     * The various newline characters are considered special as well.
-     * All other valid XML characters can be considered content.
-     * <p>
-     * This is an optimization for the inner loop of character scanning.
-     */
-    public static final int MASK_CONTENT = 0x20;
-
-    /** NCName start character mask. */
-    public static final int MASK_NCNAME_START = 0x40;
-
-    /** NCName character mask. */
-    public static final int MASK_NCNAME = 0x80;
-
-    //
-    // Static initialization
-    //
-
-    static {
-        
-        //
-        // [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] |
-        //              [#xE000-#xFFFD] | [#x10000-#x10FFFF]
-        //
-
-        int charRange[] = { 
-            0x0009, 0x000A, 0x000D, 0x000D, 0x0020, 0xD7FF, 0xE000, 0xFFFD,
-        };
-
-        //
-        // [3] S ::= (#x20 | #x9 | #xD | #xA)+
-        //
-
-        int spaceChar[] = { 
-            0x0020, 0x0009, 0x000D, 0x000A,
-        };
-
-        //
-        // [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
-        //                  CombiningChar | Extender
-        //
-
-        int nameChar[] = { 
-            0x002D, 0x002E, // '-' and '.'
-        };
-
-        //
-        // [5] Name ::= (Letter | '_' | ':') (NameChar)*
-        //
-
-        int nameStartChar[] = { 
-            0x003A, 0x005F, // ':' and '_'
-        };
-
-        //
-        // [13] PubidChar ::= #x20 | 0xD | 0xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
-        //
-
-        int pubidChar[] = {
-            0x000A, 0x000D, 0x0020, 0x0021, 0x0023, 0x0024, 0x0025, 0x003D,
-            0x005F
-        };
-
-        int pubidRange[] = {
-            0x0027, 0x003B, 0x003F, 0x005A, 0x0061, 0x007A
-        };
-
-        //
-        // [84] Letter ::= BaseChar | Ideographic
-        //
-
-        int letterRange[] = {
-            // BaseChar
-            0x0041, 0x005A, 0x0061, 0x007A, 0x00C0, 0x00D6, 0x00D8, 0x00F6,
-            0x00F8, 0x0131, 0x0134, 0x013E, 0x0141, 0x0148, 0x014A, 0x017E,
-            0x0180, 0x01C3, 0x01CD, 0x01F0, 0x01F4, 0x01F5, 0x01FA, 0x0217,
-            0x0250, 0x02A8, 0x02BB, 0x02C1, 0x0388, 0x038A, 0x038E, 0x03A1,
-            0x03A3, 0x03CE, 0x03D0, 0x03D6, 0x03E2, 0x03F3, 0x0401, 0x040C,
-            0x040E, 0x044F, 0x0451, 0x045C, 0x045E, 0x0481, 0x0490, 0x04C4,
-            0x04C7, 0x04C8, 0x04CB, 0x04CC, 0x04D0, 0x04EB, 0x04EE, 0x04F5,
-            0x04F8, 0x04F9, 0x0531, 0x0556, 0x0561, 0x0586, 0x05D0, 0x05EA,
-            0x05F0, 0x05F2, 0x0621, 0x063A, 0x0641, 0x064A, 0x0671, 0x06B7,
-            0x06BA, 0x06BE, 0x06C0, 0x06CE, 0x06D0, 0x06D3, 0x06E5, 0x06E6,
-            0x0905, 0x0939, 0x0958, 0x0961, 0x0985, 0x098C, 0x098F, 0x0990,
-            0x0993, 0x09A8, 0x09AA, 0x09B0, 0x09B6, 0x09B9, 0x09DC, 0x09DD,
-            0x09DF, 0x09E1, 0x09F0, 0x09F1, 0x0A05, 0x0A0A, 0x0A0F, 0x0A10,
-            0x0A13, 0x0A28, 0x0A2A, 0x0A30, 0x0A32, 0x0A33, 0x0A35, 0x0A36,
-            0x0A38, 0x0A39, 0x0A59, 0x0A5C, 0x0A72, 0x0A74, 0x0A85, 0x0A8B,
-            0x0A8F, 0x0A91, 0x0A93, 0x0AA8, 0x0AAA, 0x0AB0, 0x0AB2, 0x0AB3,
-            0x0AB5, 0x0AB9, 0x0B05, 0x0B0C, 0x0B0F, 0x0B10, 0x0B13, 0x0B28,
-            0x0B2A, 0x0B30, 0x0B32, 0x0B33, 0x0B36, 0x0B39, 0x0B5C, 0x0B5D,
-            0x0B5F, 0x0B61, 0x0B85, 0x0B8A, 0x0B8E, 0x0B90, 0x0B92, 0x0B95,
-            0x0B99, 0x0B9A, 0x0B9E, 0x0B9F, 0x0BA3, 0x0BA4, 0x0BA8, 0x0BAA,
-            0x0BAE, 0x0BB5, 0x0BB7, 0x0BB9, 0x0C05, 0x0C0C, 0x0C0E, 0x0C10,
-            0x0C12, 0x0C28, 0x0C2A, 0x0C33, 0x0C35, 0x0C39, 0x0C60, 0x0C61,
-            0x0C85, 0x0C8C, 0x0C8E, 0x0C90, 0x0C92, 0x0CA8, 0x0CAA, 0x0CB3,
-            0x0CB5, 0x0CB9, 0x0CE0, 0x0CE1, 0x0D05, 0x0D0C, 0x0D0E, 0x0D10,
-            0x0D12, 0x0D28, 0x0D2A, 0x0D39, 0x0D60, 0x0D61, 0x0E01, 0x0E2E,
-            0x0E32, 0x0E33, 0x0E40, 0x0E45, 0x0E81, 0x0E82, 0x0E87, 0x0E88,
-            0x0E94, 0x0E97, 0x0E99, 0x0E9F, 0x0EA1, 0x0EA3, 0x0EAA, 0x0EAB,
-            0x0EAD, 0x0EAE, 0x0EB2, 0x0EB3, 0x0EC0, 0x0EC4, 0x0F40, 0x0F47,
-            0x0F49, 0x0F69, 0x10A0, 0x10C5, 0x10D0, 0x10F6, 0x1102, 0x1103,
-            0x1105, 0x1107, 0x110B, 0x110C, 0x110E, 0x1112, 0x1154, 0x1155,
-            0x115F, 0x1161, 0x116D, 0x116E, 0x1172, 0x1173, 0x11AE, 0x11AF,
-            0x11B7, 0x11B8, 0x11BC, 0x11C2, 0x1E00, 0x1E9B, 0x1EA0, 0x1EF9,
-            0x1F00, 0x1F15, 0x1F18, 0x1F1D, 0x1F20, 0x1F45, 0x1F48, 0x1F4D,
-            0x1F50, 0x1F57, 0x1F5F, 0x1F7D, 0x1F80, 0x1FB4, 0x1FB6, 0x1FBC,
-            0x1FC2, 0x1FC4, 0x1FC6, 0x1FCC, 0x1FD0, 0x1FD3, 0x1FD6, 0x1FDB,
-            0x1FE0, 0x1FEC, 0x1FF2, 0x1FF4, 0x1FF6, 0x1FFC, 0x212A, 0x212B,
-            0x2180, 0x2182, 0x3041, 0x3094, 0x30A1, 0x30FA, 0x3105, 0x312C,
-            0xAC00, 0xD7A3,
-            // Ideographic
-            0x3021, 0x3029, 0x4E00, 0x9FA5,
-        };
-        int letterChar[] = {
-            // BaseChar
-            0x0386, 0x038C, 0x03DA, 0x03DC, 0x03DE, 0x03E0, 0x0559, 0x06D5,
-            0x093D, 0x09B2, 0x0A5E, 0x0A8D, 0x0ABD, 0x0AE0, 0x0B3D, 0x0B9C,
-            0x0CDE, 0x0E30, 0x0E84, 0x0E8A, 0x0E8D, 0x0EA5, 0x0EA7, 0x0EB0,
-            0x0EBD, 0x1100, 0x1109, 0x113C, 0x113E, 0x1140, 0x114C, 0x114E,
-            0x1150, 0x1159, 0x1163, 0x1165, 0x1167, 0x1169, 0x1175, 0x119E,
-            0x11A8, 0x11AB, 0x11BA, 0x11EB, 0x11F0, 0x11F9, 0x1F59, 0x1F5B,
-            0x1F5D, 0x1FBE, 0x2126, 0x212E,
-            // Ideographic
-            0x3007,
-        };
-
-        //
-        // [87] CombiningChar ::= ...
-        //
-
-        int combiningCharRange[] = {
-            0x0300, 0x0345, 0x0360, 0x0361, 0x0483, 0x0486, 0x0591, 0x05A1,
-            0x05A3, 0x05B9, 0x05BB, 0x05BD, 0x05C1, 0x05C2, 0x064B, 0x0652,
-            0x06D6, 0x06DC, 0x06DD, 0x06DF, 0x06E0, 0x06E4, 0x06E7, 0x06E8,
-            0x06EA, 0x06ED, 0x0901, 0x0903, 0x093E, 0x094C, 0x0951, 0x0954,
-            0x0962, 0x0963, 0x0981, 0x0983, 0x09C0, 0x09C4, 0x09C7, 0x09C8,
-            0x09CB, 0x09CD, 0x09E2, 0x09E3, 0x0A40, 0x0A42, 0x0A47, 0x0A48,
-            0x0A4B, 0x0A4D, 0x0A70, 0x0A71, 0x0A81, 0x0A83, 0x0ABE, 0x0AC5,
-            0x0AC7, 0x0AC9, 0x0ACB, 0x0ACD, 0x0B01, 0x0B03, 0x0B3E, 0x0B43,
-            0x0B47, 0x0B48, 0x0B4B, 0x0B4D, 0x0B56, 0x0B57, 0x0B82, 0x0B83,
-            0x0BBE, 0x0BC2, 0x0BC6, 0x0BC8, 0x0BCA, 0x0BCD, 0x0C01, 0x0C03,
-            0x0C3E, 0x0C44, 0x0C46, 0x0C48, 0x0C4A, 0x0C4D, 0x0C55, 0x0C56,
-            0x0C82, 0x0C83, 0x0CBE, 0x0CC4, 0x0CC6, 0x0CC8, 0x0CCA, 0x0CCD,
-            0x0CD5, 0x0CD6, 0x0D02, 0x0D03, 0x0D3E, 0x0D43, 0x0D46, 0x0D48,
-            0x0D4A, 0x0D4D, 0x0E34, 0x0E3A, 0x0E47, 0x0E4E, 0x0EB4, 0x0EB9,
-            0x0EBB, 0x0EBC, 0x0EC8, 0x0ECD, 0x0F18, 0x0F19, 0x0F71, 0x0F84,
-            0x0F86, 0x0F8B, 0x0F90, 0x0F95, 0x0F99, 0x0FAD, 0x0FB1, 0x0FB7,
-            0x20D0, 0x20DC, 0x302A, 0x302F,
-        };
-
-        int combiningCharChar[] = {
-            0x05BF, 0x05C4, 0x0670, 0x093C, 0x094D, 0x09BC, 0x09BE, 0x09BF,
-            0x09D7, 0x0A02, 0x0A3C, 0x0A3E, 0x0A3F, 0x0ABC, 0x0B3C, 0x0BD7,
-            0x0D57, 0x0E31, 0x0EB1, 0x0F35, 0x0F37, 0x0F39, 0x0F3E, 0x0F3F,
-            0x0F97, 0x0FB9, 0x20E1, 0x3099, 0x309A,
-        };
-
-        //
-        // [88] Digit ::= ...
-        //
-
-        int digitRange[] = {
-            0x0030, 0x0039, 0x0660, 0x0669, 0x06F0, 0x06F9, 0x0966, 0x096F,
-            0x09E6, 0x09EF, 0x0A66, 0x0A6F, 0x0AE6, 0x0AEF, 0x0B66, 0x0B6F,
-            0x0BE7, 0x0BEF, 0x0C66, 0x0C6F, 0x0CE6, 0x0CEF, 0x0D66, 0x0D6F,
-            0x0E50, 0x0E59, 0x0ED0, 0x0ED9, 0x0F20, 0x0F29,
-        };
-
-        //
-        // [89] Extender ::= ...
-        //
-
-        int extenderRange[] = {
-            0x3031, 0x3035, 0x309D, 0x309E, 0x30FC, 0x30FE,
-        };
-
-        int extenderChar[] = {
-            0x00B7, 0x02D0, 0x02D1, 0x0387, 0x0640, 0x0E46, 0x0EC6, 0x3005,
-        };
-
-        //
-        // SpecialChar ::= '<', '&', '\n', '\r', ']'
-        //
-
-        int specialChar[] = {
-            '<', '&', '\n', '\r', ']',
-        };
-
-        //
-        // Initialize
-        //
-
-        // set valid characters
-        for (int i = 0; i < charRange.length; i += 2) {
-            for (int j = charRange[i]; j <= charRange[i + 1]; j++) {
-                CHARS[j] |= MASK_VALID | MASK_CONTENT;
-            }
-        }
-
-        // remove special characters
-        for (int i = 0; i < specialChar.length; i++) {
-            CHARS[specialChar[i]] = (byte)(CHARS[specialChar[i]] & ~MASK_CONTENT);
-        }
-
-        // set space characters
-        for (int i = 0; i < spaceChar.length; i++) {
-            CHARS[spaceChar[i]] |= MASK_SPACE;
-        }
-
-        // set name start characters
-        for (int i = 0; i < nameStartChar.length; i++) {
-            CHARS[nameStartChar[i]] |= MASK_NAME_START | MASK_NAME | 
-                                       MASK_NCNAME_START | MASK_NCNAME;
-        }
-        for (int i = 0; i < letterRange.length; i += 2) {
-            for (int j = letterRange[i]; j <= letterRange[i + 1]; j++) {
-                CHARS[j] |= MASK_NAME_START | MASK_NAME |
-                            MASK_NCNAME_START | MASK_NCNAME;
-            }
-        }
-        for (int i = 0; i < letterChar.length; i++) {
-            CHARS[letterChar[i]] |= MASK_NAME_START | MASK_NAME |
-                                    MASK_NCNAME_START | MASK_NCNAME;
-        }
-
-        // set name characters
-        for (int i = 0; i < nameChar.length; i++) {
-            CHARS[nameChar[i]] |= MASK_NAME | MASK_NCNAME;
-        }
-        for (int i = 0; i < digitRange.length; i += 2) {
-            for (int j = digitRange[i]; j <= digitRange[i + 1]; j++) {
-                CHARS[j] |= MASK_NAME | MASK_NCNAME;
-            }
-        }
-        for (int i = 0; i < combiningCharRange.length; i += 2) {
-            for (int j = combiningCharRange[i]; j <= combiningCharRange[i + 1]; j++) {
-                CHARS[j] |= MASK_NAME | MASK_NCNAME;
-            }
-        }
-        for (int i = 0; i < combiningCharChar.length; i++) {
-            CHARS[combiningCharChar[i]] |= MASK_NAME | MASK_NCNAME;
-        }
-        for (int i = 0; i < extenderRange.length; i += 2) {
-            for (int j = extenderRange[i]; j <= extenderRange[i + 1]; j++) {
-                CHARS[j] |= MASK_NAME | MASK_NCNAME;
-            }
-        }
-        for (int i = 0; i < extenderChar.length; i++) {
-            CHARS[extenderChar[i]] |= MASK_NAME | MASK_NCNAME;
-        }
-
-        // remove ':' from allowable MASK_NCNAME_START and MASK_NCNAME chars
-        CHARS[':'] &= ~(MASK_NCNAME_START | MASK_NCNAME);
-
-        // set Pubid characters
-        for (int i = 0; i < pubidChar.length; i++) {
-            CHARS[pubidChar[i]] |= MASK_PUBID;
-        }
-        for (int i = 0; i < pubidRange.length; i += 2) {
-            for (int j = pubidRange[i]; j <= pubidRange[i + 1]; j++) {
-                CHARS[j] |= MASK_PUBID;
-            }
-        }
-
-    } // <clinit>()
-
-    //
-    // Public static methods
-    //
-
-    /**
-     * Returns true if the specified character is a supplemental character.
-     *
-     * @param c The character to check.
-     */
-    public static boolean isSupplemental(int c) {
-        return (c >= 0x10000 && c <= 0x10FFFF);
-    }
-
-    /**
-     * Returns true the supplemental character corresponding to the given
-     * surrogates.
-     *
-     * @param h The high surrogate.
-     * @param l The low surrogate.
-     */
-    public static int supplemental(char h, char l) {
-        return (h - 0xD800) * 0x400 + (l - 0xDC00) + 0x10000;
-    }
-
-    /**
-     * Returns the high surrogate of a supplemental character
-     *
-     * @param c The supplemental character to "split".
-     */
-    public static char highSurrogate(int c) {
-        return (char) (((c - 0x00010000) >> 10) + 0xD800);
-    }
-
-    /**
-     * Returns the low surrogate of a supplemental character
-     *
-     * @param c The supplemental character to "split".
-     */
-    public static char lowSurrogate(int c) {
-        return (char) (((c - 0x00010000) & 0x3FF) + 0xDC00);
-    }
-
-    /**
-     * Returns whether the given character is a high surrogate
-     *
-     * @param c The character to check.
-     */
-    public static boolean isHighSurrogate(int c) {
-        return (0xD800 <= c && c <= 0xDBFF);
-    }
-
-    /**
-     * Returns whether the given character is a low surrogate
-     *
-     * @param c The character to check.
-     */
-    public static boolean isLowSurrogate(int c) {
-        return (0xDC00 <= c && c <= 0xDFFF);
-    }
-
-
-    /**
-     * Returns true if the specified character is valid. This method
-     * also checks the surrogate character range from 0x10000 to 0x10FFFF.
-     * <p>
-     * If the program chooses to apply the mask directly to the
-     * <code>CHARS</code> array, then they are responsible for checking
-     * the surrogate character range.
-     *
-     * @param c The character to check.
-     */
-    public static boolean isValid(int c) {
-        return (c < 0x10000 && (CHARS[c] & MASK_VALID) != 0) ||
-               (0x10000 <= c && c <= 0x10FFFF);
-    } // isValid(int):boolean
-
-    /**
-     * Returns true if the specified character is invalid.
-     *
-     * @param c The character to check.
-     */
-    public static boolean isInvalid(int c) {
-        return !isValid(c);
-    } // isInvalid(int):boolean
-
-    /**
-     * Returns true if the specified character can be considered content.
-     *
-     * @param c The character to check.
-     */
-    public static boolean isContent(int c) {
-        return (c < 0x10000 && (CHARS[c] & MASK_CONTENT) != 0) ||
-               (0x10000 <= c && c <= 0x10FFFF);
-    } // isContent(int):boolean
-
-    /**
-     * Returns true if the specified character can be considered markup.
-     * Markup characters include '&lt;', '&amp;', and '%'.
-     *
-     * @param c The character to check.
-     */
-    public static boolean isMarkup(int c) {
-        return c == '<' || c == '&' || c == '%';
-    } // isMarkup(int):boolean
-
-    /**
-     * Returns true if the specified character is a space character
-     * as defined by production [3] in the XML 1.0 specification.
-     *
-     * @param c The character to check.
-     */
-    public static boolean isSpace(int c) {
-        return c < 0x10000 && (CHARS[c] & MASK_SPACE) != 0;
-    } // isSpace(int):boolean
-
-    /**
-     * Returns true if the specified character is a valid name start
-     * character as defined by production [5] in the XML 1.0
-     * specification.
-     *
-     * @param c The character to check.
-     */
-    public static boolean isNameStart(int c) {
-        return c < 0x10000 && (CHARS[c] & MASK_NAME_START) != 0;
-    } // isNameStart(int):boolean
-
-    /**
-     * Returns true if the specified character is a valid name
-     * character as defined by production [4] in the XML 1.0
-     * specification.
-     *
-     * @param c The character to check.
-     */
-    public static boolean isName(int c) {
-        return c < 0x10000 && (CHARS[c] & MASK_NAME) != 0;
-    } // isName(int):boolean
-
-    /**
-     * Returns true if the specified character is a valid NCName start
-     * character as defined by production [4] in Namespaces in XML
-     * recommendation.
-     *
-     * @param c The character to check.
-     */
-    public static boolean isNCNameStart(int c) {
-        return c < 0x10000 && (CHARS[c] & MASK_NCNAME_START) != 0;
-    } // isNCNameStart(int):boolean
-
-    /**
-     * Returns true if the specified character is a valid NCName
-     * character as defined by production [5] in Namespaces in XML
-     * recommendation.
-     *
-     * @param c The character to check.
-     */
-    public static boolean isNCName(int c) {
-        return c < 0x10000 && (CHARS[c] & MASK_NCNAME) != 0;
-    } // isNCName(int):boolean
-
-    /**
-     * Returns true if the specified character is a valid Pubid
-     * character as defined by production [13] in the XML 1.0
-     * specification.
-     *
-     * @param c The character to check.
-     */
-    public static boolean isPubid(int c) {
-        return c < 0x10000 && (CHARS[c] & MASK_PUBID) != 0;
-    } // isPubid(int):boolean
-
-    /*
-     * [5] Name ::= (Letter | '_' | ':') (NameChar)*
-     */
-    /**
-     * Check to see if a string is a valid Name according to [5]
-     * in the XML 1.0 Recommendation
-     *
-     * @param name string to check
-     * @return true if name is a valid Name
-     */
-    public static boolean isValidName(String name) {
-        if (name.length() == 0)
-            return false;
-        char ch = name.charAt(0);
-        if( isNameStart(ch) == false)
-           return false;
-        for (int i = 1; i < name.length(); i++ ) {
-           ch = name.charAt(i);
-           if( isName( ch ) == false ){
-              return false;
-           }
-        }
-        return true;
-    } // isValidName(String):boolean
-    
-
-    /*
-     * from the namespace rec
-     * [4] NCName ::= (Letter | '_') (NCNameChar)*
-     */
-    /**
-     * Check to see if a string is a valid NCName according to [4]
-     * from the XML Namespaces 1.0 Recommendation
-     *
-     * @param name string to check
-     * @return true if name is a valid NCName
-     */
-    public static boolean isValidNCName(String ncName) {
-        if (ncName.length() == 0)
-            return false;
-        char ch = ncName.charAt(0);
-        if( isNCNameStart(ch) == false)
-           return false;
-        for (int i = 1; i < ncName.length(); i++ ) {
-           ch = ncName.charAt(i);
-           if( isNCName( ch ) == false ){
-              return false;
-           }
-        }
-        return true;
-    } // isValidNCName(String):boolean
-
-    /*
-     * [7] Nmtoken ::= (NameChar)+
-     */
-    /**
-     * Check to see if a string is a valid Nmtoken according to [7]
-     * in the XML 1.0 Recommendation
-     *
-     * @param nmtoken string to check
-     * @return true if nmtoken is a valid Nmtoken 
-     */
-    public static boolean isValidNmtoken(String nmtoken) {
-        if (nmtoken.length() == 0)
-            return false;
-        for (int i = 0; i < nmtoken.length(); i++ ) {
-           char ch = nmtoken.charAt(i);
-           if(  ! isName( ch ) ){
-              return false;
-           }
-        }
-        return true;
-    } // isValidName(String):boolean
-
-
-
-
-
-    // encodings
-
-    /**
-     * Returns true if the encoding name is a valid IANA encoding.
-     * This method does not verify that there is a decoder available
-     * for this encoding, only that the characters are valid for an
-     * IANA encoding name.
-     *
-     * @param ianaEncoding The IANA encoding name.
-     */
-    public static boolean isValidIANAEncoding(String ianaEncoding) {
-        if (ianaEncoding != null) {
-            int length = ianaEncoding.length();
-            if (length > 0) {
-                char c = ianaEncoding.charAt(0);
-                if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
-                    for (int i = 1; i < length; i++) {
-                        c = ianaEncoding.charAt(i);
-                        if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') &&
-                            (c < '0' || c > '9') && c != '.' && c != '_' &&
-                            c != '-') {
-                            return false;
-                        }
-                    }
-                    return true;
-                }
-            }
-        }
-        return false;
-    } // isValidIANAEncoding(String):boolean
-
-    /**
-     * Returns true if the encoding name is a valid Java encoding.
-     * This method does not verify that there is a decoder available
-     * for this encoding, only that the characters are valid for an
-     * Java encoding name.
-     *
-     * @param javaEncoding The Java encoding name.
-     */
-    public static boolean isValidJavaEncoding(String javaEncoding) {
-        if (javaEncoding != null) {
-            int length = javaEncoding.length();
-            if (length > 0) {
-                for (int i = 1; i < length; i++) {
-                    char c = javaEncoding.charAt(i);
-                    if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') &&
-                        (c < '0' || c > '9') && c != '.' && c != '_' &&
-                        c != '-') {
-                        return false;
-                    }
-                }
-                return true;
-            }
-        }
-        return false;
-    } // isValidIANAEncoding(String):boolean
-
-} // class XMLChar
diff --git a/src/org/apache/xpath/axes/NodeSequence.java b/src/org/apache/xpath/axes/NodeSequence.java
deleted file mode 100644
index e58bd3e..0000000
--- a/src/org/apache/xpath/axes/NodeSequence.java
+++ /dev/null
@@ -1,676 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 2002 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.xpath.axes;
-
-import java.io.Serializable;
-
-import java.util.Vector;
-import javax.xml.transform.TransformerException;
-import org.apache.xml.dtm.DTM;
-import org.apache.xml.dtm.DTMIterator;
-import org.apache.xml.dtm.DTMManager;
-import org.apache.xml.dtm.DTMFilter;
-import org.apache.xml.utils.NodeVector;
-import org.apache.xpath.Expression;
-import org.apache.xpath.XPathContext;
-import org.apache.xpath.objects.XObject;
-
-/**
- * This class is the dynamic wrapper for a Xalan DTMIterator instance, and 
- * provides random access capabilities.
- */
-public class NodeSequence extends XObject
-  implements DTMIterator, Cloneable, PathComponent
-{
-  /** The index of the last node in the iteration. */
-  protected int m_last = -1;
-  
-  /**
-   * The index of the next node to be fetched.  Useful if this
-   * is a cached iterator, and is being used as random access
-   * NodeList.
-   */
-  protected int m_next = 0;
-    
-  /**
-   * If this iterator needs to cache nodes that are fetched, they
-   * are stored in the Vector in the generic object.
-   */
-  protected NodeVector getVector()
-  {
-  	return (NodeVector)m_obj;
-  }
-  
-  /**
-   * Set the vector where nodes will be stored.
-   */
-  protected void SetVector(NodeVector v)
-  {
-  	m_obj = v;
-  }
-
-  
-  /**
-   * If this iterator needs to cache nodes that are fetched, they
-   * are stored here.
-   */
-  public boolean hasCache()
-  {
-  	return (m_obj != null);
-  }
-
-
-  /**
-   * The functional iterator that fetches nodes.
-   */
-  protected DTMIterator m_iter;
-  
-  /**
-   * Set the functional iterator that fetches nodes.
-   * @param iter The iterator that is to be contained.
-   */
-  public final void setIter(DTMIterator iter)
-  {
-  	m_iter = iter;
-  }
-  
-  /**
-   * Get the functional iterator that fetches nodes.
-   * @return The contained iterator.
-   */
-  public final DTMIterator getContainedIter()
-  {
-  	return m_iter;
-  }
-  
-  /**
-   * The DTMManager to use if we're using a NodeVector only.
-   * We may well want to do away with this, and store it in the NodeVector.
-   */
-  protected DTMManager m_dtmMgr;
-  
-  // ==== Constructors ====
-  
-  /**
-   * Create a new NodeSequence from a (already cloned) iterator.
-   * 
-   * @param iter Cloned (not static) DTMIterator.
-   * @param context The initial context node.
-   * @param xctxt The execution context.
-   * @param shouldCacheNodes True if this sequence can random access.
-   */
-  public NodeSequence(DTMIterator iter, int context, XPathContext xctxt, boolean shouldCacheNodes)
-  {
-  	setIter(iter);
-  	setRoot(context, xctxt);
-  	setShouldCacheNodes(shouldCacheNodes);
-  }
-  
-  /**
-   * Create a new NodeSequence from a (already cloned) iterator.
-   * 
-   * @param iter Cloned (not static) DTMIterator.
-   */
-  public NodeSequence(Object nodeVector)
-  {
-  	super(nodeVector);
-  	if(null != nodeVector)
-  	{
-  		assertion(nodeVector instanceof NodeVector, 
-  			"Must have a NodeVector as the object for NodeSequence!");
-  		if(nodeVector instanceof DTMIterator)
-  		{
-  			setIter((DTMIterator)nodeVector);
-  			m_last = ((DTMIterator)nodeVector).getLength();
-  		}
-  		
-  	}
-  }
-  
-  /**
-   * Construct an empty XNodeSet object.  This is used to create a mutable 
-   * nodeset to which random nodes may be added.
-   */
-  public NodeSequence(DTMManager dtmMgr)
-  {
-    super(new NodeVector());
-    m_last = 0;
-    m_dtmMgr = dtmMgr;
-  }
-
-  
-  /**
-   * Create a new NodeSequence in an invalid (null) state.
-   */
-  public NodeSequence()
-  {
-  }
-
-
-  /**
-   * @see DTMIterator#getDTM(int)
-   */
-  public DTM getDTM(int nodeHandle)
-  {
-  	DTMManager mgr = getDTMManager();
-  	if(null != mgr)
-    	return getDTMManager().getDTM(nodeHandle);
-    else
-    {
-    	assertion(false, "Can not get a DTM Unless a DTMManager has been set!");
-    	return null;
-    }
-  }
-
-  /**
-   * @see DTMIterator#getDTMManager()
-   */
-  public DTMManager getDTMManager()
-  {
-    return m_dtmMgr;
-  }
-
-  /**
-   * @see DTMIterator#getRoot()
-   */
-  public int getRoot()
-  {
-  	if(null != m_iter)
-    	return m_iter.getRoot();
-  	else
-  	{
-  		// NodeSetDTM will call this, and so it's not a good thing to throw 
-  		// an assertion here.
-  		// assertion(false, "Can not get the root from a non-iterated NodeSequence!");
-  		return DTM.NULL;
-  	}
-  }
-
-  /**
-   * @see DTMIterator#setRoot(int, Object)
-   */
-  public void setRoot(int nodeHandle, Object environment)
-  {
-  	if(null != m_iter)
-  	{
-  		XPathContext xctxt = (XPathContext)environment;
-  		m_dtmMgr = xctxt.getDTMManager();
-  		m_iter.setRoot(nodeHandle, environment);
-  		if(!m_iter.isDocOrdered())
-  		{
-  			if(!hasCache())
-  				setShouldCacheNodes(true);
-  			runTo(-1);
-  			m_next=0;
-  		}
-  	}
-  	else
-  		assertion(false, "Can not setRoot on a non-iterated NodeSequence!");
-  }
-
-  /**
-   * @see DTMIterator#reset()
-   */
-  public void reset()
-  {
-  	m_next = 0;
-  	// not resetting the iterator on purpose!!!
-  }
-
-  /**
-   * @see DTMIterator#getWhatToShow()
-   */
-  public int getWhatToShow()
-  {
-    return hasCache() ? (DTMFilter.SHOW_ALL & ~DTMFilter.SHOW_ENTITY_REFERENCE) 
-    	: m_iter.getWhatToShow();
-  }
-
-  /**
-   * @see DTMIterator#getExpandEntityReferences()
-   */
-  public boolean getExpandEntityReferences()
-  {
-  	if(null != m_iter)
-  		return m_iter.getExpandEntityReferences();
-  	else
-    	return true;
-  }
-
-  /**
-   * @see DTMIterator#nextNode()
-   */
-  public int nextNode()
-  {
-    // If the cache is on, and the node has already been found, then 
-    // just return from the list.
-    NodeVector vec = getVector();
-    if (null != vec)
-    {	
-    	if(m_next < vec.size())
-    	{
-			int next = vec.elementAt(m_next);
-	    	m_next++;
-	    	return next;
-    	}
-    	else if((-1 != m_last) || (null == m_iter))
-    	{
-    		m_next++;
-    		return DTM.NULL;
-    	}
-    }
-    
-  if (null == m_iter)
-    return DTM.NULL;
-  
- 	int next = m_iter.nextNode();
-    if(DTM.NULL != next)
-    {
-    	if(hasCache())
-    	{
-    		if(m_iter.isDocOrdered())
-    	    {
-    			getVector().addElement(next);
-    			m_next++;
-    		}
-    		else
-    		{
-    			int insertIndex = addNodeInDocOrder(next);
-    			if(insertIndex >= 0)
-    				m_next++;
-    		}
-    	}
-    	else
-    		m_next++;
-    }
-    else
-    {
-    	m_last = m_next;
-    	m_next++;
-    }
-    	
-    return next;
-  }
-
-  /**
-   * @see DTMIterator#previousNode()
-   */
-  public int previousNode()
-  {
-  	if(hasCache())
-  	{
-  		if(m_next <= 0)
-  			return DTM.NULL;
-  		else
-  		{
-  			m_next--;
-  			return item(m_next);
-  		}
-  	}
-  	else
-  	{
-	    int n = m_iter.previousNode();
-	    m_next = m_iter.getCurrentPos();
-	    return m_next;
-  	}
-  }
-
-  /**
-   * @see DTMIterator#detach()
-   */
-  public void detach()
-  {
-  	if(null != m_iter)
-  		m_iter.detach();
-  	super.detach();
-  }
-
-  /**
-   * Calling this with a value of false will cause the nodeset 
-   * to be cached.
-   * @see DTMIterator#allowDetachToRelease(boolean)
-   */
-  public void allowDetachToRelease(boolean allowRelease)
-  {
-  	if((false == allowRelease) && !hasCache())
-  	{
-  		setShouldCacheNodes(true);
-  	}
-  	
-  	if(null != m_iter)
-  		m_iter.allowDetachToRelease(allowRelease);
-  	super.allowDetachToRelease(allowRelease);
-  }
-
-  /**
-   * @see DTMIterator#getCurrentNode()
-   */
-  public int getCurrentNode()
-  {
-  	if(hasCache())
-  	{
-  		int currentIndex = m_next-1;
-  		NodeVector vec = getVector();
-  		if((currentIndex >= 0) && (currentIndex < vec.size()))
-  			return vec.elementAt(currentIndex);
-  		else
-  			return DTM.NULL;
-  	}
-  	
-  	if(null != m_iter)
-  	{
-    	return m_iter.getCurrentNode();
-  	}
-  	else
-  		return DTM.NULL;
-  }
-
-  /**
-   * @see DTMIterator#isFresh()
-   */
-  public boolean isFresh()
-  {
-    return (0 == m_next);
-  }
-
-  /**
-   * @see DTMIterator#setShouldCacheNodes(boolean)
-   */
-  public void setShouldCacheNodes(boolean b)
-  {
-    if (b)
-    {
-      if(!hasCache())
-      {
-        SetVector(new NodeVector());
-      }
-//	  else
-//	    getVector().RemoveAllNoClear();  // Is this good?
-    }
-    else
-      SetVector(null);
-  }
-
-  /**
-   * @see DTMIterator#isMutable()
-   */
-  public boolean isMutable()
-  {
-    return hasCache(); // though may be surprising if it also has an iterator!
-  }
-
-  /**
-   * @see DTMIterator#getCurrentPos()
-   */
-  public int getCurrentPos()
-  {
-    return m_next;
-  }
-
-  /**
-   * @see DTMIterator#runTo(int)
-   */
-  public void runTo(int index)
-  {
-    int n;
-    
-    if (-1 == index)
-    {
-      int pos = m_next;
-      while (DTM.NULL != (n = nextNode()));
-      m_next = pos;
-    }
-    else if(m_next == index)
-    {
-      return;
-    }
-    else if(hasCache() && m_next < getVector().size())
-    {
-      m_next = index;
-    }
-    else if((null == getVector()) && (index < m_next))
-    {
-      while ((m_next >= index) && DTM.NULL != (n = previousNode()));
-    }
-    else
-    {   
-      while ((m_next < index) && DTM.NULL != (n = nextNode()));
-    }
-    
-  }
-
-  /**
-   * @see DTMIterator#setCurrentPos(int)
-   */
-  public void setCurrentPos(int i)
-  {
-  	runTo(i);
-  }
-
-  /**
-   * @see DTMIterator#item(int)
-   */
-  public int item(int index)
-  {
-  	setCurrentPos(index);
-  	int n = nextNode();
-  	m_next = index;
-  	return n;
-  }
-
-  /**
-   * @see DTMIterator#setItem(int, int)
-   */
-  public void setItem(int node, int index)
-  {
-  	NodeVector vec = getVector();
-  	if(null != vec)
-  	{
-  		vec.setElementAt(node, index);
-  		m_last = vec.size();
-  	}
-  	else
-  		m_iter.setItem(node, index);
-  }
-
-  /**
-   * @see DTMIterator#getLength()
-   */
-  public int getLength()
-  {
-  	if(hasCache())
-  	{
-	  	if(-1 == m_last)
-	  	{
-	  		int pos = m_next;
-	  		runTo(-1);
-	  		m_next = pos;
-	  	}
-	    return m_last;
-  	}
-  	else
-  	{
-  		return m_iter.getLength();
-  	}
-  }
-
-  /**
-   * Note: Not a deep clone.
-   * @see DTMIterator#cloneWithReset()
-   */
-  public DTMIterator cloneWithReset() throws CloneNotSupportedException
-  {
-  	NodeSequence seq = (NodeSequence)super.clone();
-    seq.m_next = 0;
-    return seq;
-  }
-  
-  /**
-   * Get a clone of this iterator, but don't reset the iteration in the 
-   * process, so that it may be used from the current position.
-   * Note: Not a deep clone.
-   *
-   * @return A clone of this object.
-   *
-   * @throws CloneNotSupportedException
-   */
-  public Object clone() throws CloneNotSupportedException
-  {
-  	return super.clone();
-  }
-
-
-  /**
-   * @see DTMIterator#isDocOrdered()
-   */
-  public boolean isDocOrdered()
-  {
-  	if(null != m_iter)
-  		return m_iter.isDocOrdered();
-  	else
-    	return true; // can't be sure?
-  }
-
-  /**
-   * @see DTMIterator#getAxis()
-   */
-  public int getAxis()
-  {
-  	if(null != m_iter)
-    	return m_iter.getAxis();
-    else
-    {
-    	assertion(false, "Can not getAxis from a non-iterated node sequence!");
-    	return 0;
-    }
-  }
-
-  /**
-   * @see PathComponent#getAnalysisBits()
-   */
-  public int getAnalysisBits()
-  {
-  	if((null != m_iter) && (m_iter instanceof PathComponent))
-    	return ((PathComponent)m_iter).getAnalysisBits();
-    else
-    	return 0;
-  }
-
-  /**
-   * @see Expression#fixupVariables(Vector, int)
-   */
-  public void fixupVariables(Vector vars, int globalsSize)
-  {
-  	super.fixupVariables(vars, globalsSize);
-  }  
-  
-  /**
-   * Add the node into a vector of nodes where it should occur in
-   * document order.
-   * @param v Vector of nodes, presumably containing Nodes
-   * @param obj Node object.
-   *
-   * @param node The node to be added.
-   * @param test true if we should test for doc order
-   * @param support The XPath runtime context.
-   * @return insertIndex.
-   * @throws RuntimeException thrown if this NodeSetDTM is not of 
-   * a mutable type.
-   */
-   protected int addNodeInDocOrder(int node)
-   {
-      assertion(hasCache(), "addNodeInDocOrder must be done on a mutable sequence!");
-
-      int insertIndex = -1;
-      
-      NodeVector vec = getVector();
-
-      // This needs to do a binary search, but a binary search 
-      // is somewhat tough because the sequence test involves 
-      // two nodes.
-      int size = vec.size(), i;
-
-      for (i = size - 1; i >= 0; i--)
-      {
-        int child = vec.elementAt(i);
-
-        if (child == node)
-        {
-          i = -2; // Duplicate, suppress insert
-
-          break;
-        }
-
-        DTM dtm = m_dtmMgr.getDTM(node);
-        if (!dtm.isNodeAfter(node, child))
-        {
-          break;
-        }
-      }
-
-      if (i != -2)
-      {
-        insertIndex = i + 1;
-
-        vec.insertElementAt(node, insertIndex);
-      }
-
-      // checkDups();
-      return insertIndex;
-    } // end addNodeInDocOrder(Vector v, Object obj)
-}
-
diff --git a/src/org/apache/xpath/compiler/Compiler.java b/src/org/apache/xpath/compiler/Compiler.java
deleted file mode 100644
index 8e4beb5..0000000
--- a/src/org/apache/xpath/compiler/Compiler.java
+++ /dev/null
@@ -1,1268 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 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.xpath.compiler;
-
-import org.apache.xpath.operations.And;
-import org.apache.xpath.operations.Bool;
-import org.apache.xpath.operations.Div;
-import org.apache.xpath.operations.Equals;
-import org.apache.xpath.operations.Gt;
-import org.apache.xpath.operations.Gte;
-import org.apache.xpath.operations.Lt;
-import org.apache.xpath.operations.Lte;
-import org.apache.xpath.operations.Minus;
-import org.apache.xpath.operations.Mod;
-import org.apache.xpath.operations.Mult;
-import org.apache.xpath.operations.Neg;
-import org.apache.xpath.operations.NotEquals;
-import org.apache.xpath.operations.Operation;
-import org.apache.xpath.operations.Or;
-import org.apache.xpath.operations.Plus;
-import org.apache.xpath.operations.UnaryOperation;
-import org.apache.xpath.operations.Variable;
-import org.apache.xpath.objects.*;
-import org.apache.xpath.axes.*;
-import org.apache.xpath.patterns.*;
-import org.apache.xpath.functions.Function;
-import org.apache.xpath.functions.FuncExtFunction;
-import org.apache.xpath.functions.WrongNumberArgsException;
-import org.apache.xpath.*;
-import org.apache.xpath.res.XPATHErrorResources;
-import org.apache.xalan.res.XSLMessages;
-import org.apache.xml.utils.QName;
-import org.apache.xml.utils.PrefixResolver;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.SourceLocator;
-import org.apache.xml.utils.SAXSourceLocator;
-import org.apache.xml.dtm.DTMFilter;
-import org.apache.xml.dtm.DTMIterator;
-import org.apache.xml.dtm.Axis;
-
-import javax.xml.transform.ErrorListener;
-import javax.xml.transform.TransformerException;
-
-/**
- * <meta name="usage" content="advanced"/>
- * An instance of this class compiles an XPath string expression into 
- * a Expression object.  This class compiles the string into a sequence 
- * of operation codes (op map) and then builds from that into an Expression 
- * tree.
- */
-public class Compiler extends OpMap
-{
-
-  /**
-   * Construct a Compiler object with a specific ErrorListener and 
-   * SourceLocator where the expression is located.
-   *
-   * @param errorHandler Error listener where messages will be sent, or null 
-   *                     if messages should be sent to System err.
-   * @param locator The location object where the expression lives, which 
-   *                may be null, but which, if not null, must be valid over 
-   *                the long haul, in other words, it will not be cloned.
-   */
-  public Compiler(ErrorListener errorHandler, SourceLocator locator)
-  {
-    m_errorHandler = errorHandler;
-    m_locator = locator;
-  }
-
-  /**
-   * Construct a Compiler instance that has a null error listener and a 
-   * null source locator.
-   */
-  public Compiler()
-  {
-    m_errorHandler = null;
-    m_locator = null;
-  }
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * Execute the XPath object from a given opcode position.
-   * @param xctxt The execution context.
-   * @param context The current source tree context node.
-   * @param opPos The current position in the xpath.m_opMap array.
-   * @param callback Interface that implements the processLocatedNode method.
-   * @param callbackInfo Object that will be passed to the processLocatedNode method.
-   * @return The result of the XPath.
-   *
-   * @throws TransformerException if there is a syntax or other error.
-   */
-  public Expression compile(int opPos) throws TransformerException
-  {
-
-    int op = m_opMap[opPos];
-
-    Expression expr = null;
-    // System.out.println(getPatternString()+"op: "+op);
-    switch (op)
-    {
-    case OpCodes.OP_XPATH :
-      expr = compile(opPos + 2); break;
-    case OpCodes.OP_OR :
-      expr = or(opPos); break;
-    case OpCodes.OP_AND :
-      expr = and(opPos); break;
-    case OpCodes.OP_NOTEQUALS :
-      expr = notequals(opPos); break;
-    case OpCodes.OP_EQUALS :
-      expr = equals(opPos); break;
-    case OpCodes.OP_LTE :
-      expr = lte(opPos); break;
-    case OpCodes.OP_LT :
-      expr = lt(opPos); break;
-    case OpCodes.OP_GTE :
-      expr = gte(opPos); break;
-    case OpCodes.OP_GT :
-      expr = gt(opPos); break;
-    case OpCodes.OP_PLUS :
-      expr = plus(opPos); break;
-    case OpCodes.OP_MINUS :
-      expr = minus(opPos); break;
-    case OpCodes.OP_MULT :
-      expr = mult(opPos); break;
-    case OpCodes.OP_DIV :
-      expr = div(opPos); break;
-    case OpCodes.OP_MOD :
-      expr = mod(opPos); break;
-//    case OpCodes.OP_QUO :
-//      expr = quo(opPos); break;
-    case OpCodes.OP_NEG :
-      expr = neg(opPos); break;
-    case OpCodes.OP_STRING :
-      expr = string(opPos); break;
-    case OpCodes.OP_BOOL :
-      expr = bool(opPos); break;
-    case OpCodes.OP_NUMBER :
-      expr = number(opPos); break;
-    case OpCodes.OP_UNION :
-      expr = union(opPos); break;
-    case OpCodes.OP_LITERAL :
-      expr = literal(opPos); break;
-    case OpCodes.OP_VARIABLE :
-      expr = variable(opPos); break;
-    case OpCodes.OP_GROUP :
-      expr = group(opPos); break;
-    case OpCodes.OP_NUMBERLIT :
-      expr = numberlit(opPos); break;
-    case OpCodes.OP_ARGUMENT :
-      expr = arg(opPos); break;
-    case OpCodes.OP_EXTFUNCTION :
-      expr = compileExtension(opPos); break;
-    case OpCodes.OP_FUNCTION :
-      expr = compileFunction(opPos); break;
-    case OpCodes.OP_LOCATIONPATH :
-      expr = locationPath(opPos); break;
-    case OpCodes.OP_PREDICATE :
-      expr = null; break;  // should never hit this here.
-    case OpCodes.OP_MATCHPATTERN :
-      expr = matchPattern(opPos + 2); break;
-    case OpCodes.OP_LOCATIONPATHPATTERN :
-      expr = locationPathPattern(opPos); break;
-    case OpCodes.OP_QUO:
-      error(XPATHErrorResources.ER_UNKNOWN_OPCODE,
-            new Object[]{ "quo" });  //"ERROR! Unknown op code: "+m_opMap[opPos]);
-      break;
-    default :
-      error(XPATHErrorResources.ER_UNKNOWN_OPCODE,
-            new Object[]{ Integer.toString(m_opMap[opPos]) });  //"ERROR! Unknown op code: "+m_opMap[opPos]);
-    }
-//    if(null != expr)
-//      expr.setSourceLocator(m_locator);
-
-    return expr;
-  }
-
-  /**
-   * Bottle-neck compilation of an operation with left and right operands.
-   *
-   * @param operation non-null reference to parent operation.
-   * @param opPos The op map position of the parent operation.
-   *
-   * @return reference to {@link org.apache.xpath.operations.Operation} instance.
-   *
-   * @throws TransformerException if there is a syntax or other error.
-   */
-  private Expression compileOperation(Operation operation, int opPos)
-          throws TransformerException
-  {
-
-    int leftPos = getFirstChildPos(opPos);
-    int rightPos = getNextOpPos(leftPos);
-
-    operation.setLeftRight(compile(leftPos), compile(rightPos));
-
-    return operation;
-  }
-
-  /**
-   * Bottle-neck compilation of a unary operation.
-   *
-   * @param unary The parent unary operation.
-   * @param opPos The position in the op map of the parent operation.
-   *
-   * @return The unary argument.
-   *
-   * @throws TransformerException if syntax or other error occurs.
-   */
-  private Expression compileUnary(UnaryOperation unary, int opPos)
-          throws TransformerException
-  {
-
-    int rightPos = getFirstChildPos(opPos);
-
-    unary.setRight(compile(rightPos));
-
-    return unary;
-  }
-
-  /**
-   * Compile an 'or' operation.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.Or} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression or(int opPos) throws TransformerException
-  {
-    return compileOperation(new Or(), opPos);
-  }
-
-  /**
-   * Compile an 'and' operation.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.And} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression and(int opPos) throws TransformerException
-  {
-    return compileOperation(new And(), opPos);
-  }
-
-  /**
-   * Compile a '!=' operation.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.NotEquals} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression notequals(int opPos) throws TransformerException
-  {
-    return compileOperation(new NotEquals(), opPos);
-  }
-
-  /**
-   * Compile a '=' operation.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.Equals} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression equals(int opPos) throws TransformerException
-  {
-    return compileOperation(new Equals(), opPos);
-  }
-
-  /**
-   * Compile a '<=' operation.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.Lte} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression lte(int opPos) throws TransformerException
-  {
-    return compileOperation(new Lte(), opPos);
-  }
-
-  /**
-   * Compile a '<' operation.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.Lt} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression lt(int opPos) throws TransformerException
-  {
-    return compileOperation(new Lt(), opPos);
-  }
-
-  /**
-   * Compile a '>=' operation.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.Gte} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression gte(int opPos) throws TransformerException
-  {
-    return compileOperation(new Gte(), opPos);
-  }
-
-  /**
-   * Compile a '>' operation.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.Gt} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression gt(int opPos) throws TransformerException
-  {
-    return compileOperation(new Gt(), opPos);
-  }
-
-  /**
-   * Compile a '+' operation.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.Plus} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression plus(int opPos) throws TransformerException
-  {
-    return compileOperation(new Plus(), opPos);
-  }
-
-  /**
-   * Compile a '-' operation.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.Minus} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression minus(int opPos) throws TransformerException
-  {
-    return compileOperation(new Minus(), opPos);
-  }
-
-  /**
-   * Compile a '*' operation.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.Mult} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression mult(int opPos) throws TransformerException
-  {
-    return compileOperation(new Mult(), opPos);
-  }
-
-  /**
-   * Compile a 'div' operation.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.Div} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression div(int opPos) throws TransformerException
-  {
-    return compileOperation(new Div(), opPos);
-  }
-
-  /**
-   * Compile a 'mod' operation.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.Mod} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression mod(int opPos) throws TransformerException
-  {
-    return compileOperation(new Mod(), opPos);
-  }
-
-  /*
-   * Compile a 'quo' operation.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.Quo} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-//  protected Expression quo(int opPos) throws TransformerException
-//  {
-//    return compileOperation(new Quo(), opPos);
-//  }
-
-  /**
-   * Compile a unary '-' operation.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.Neg} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression neg(int opPos) throws TransformerException
-  {
-    return compileUnary(new Neg(), opPos);
-  }
-
-  /**
-   * Compile a 'string(...)' operation.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.String} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression string(int opPos) throws TransformerException
-  {
-    return compileUnary(new org.apache.xpath.operations.String(), opPos);
-  }
-
-  /**
-   * Compile a 'boolean(...)' operation.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.Bool} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression bool(int opPos) throws TransformerException
-  {
-    return compileUnary(new org.apache.xpath.operations.Bool(), opPos);
-  }
-
-  /**
-   * Compile a 'number(...)' operation.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.Number} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression number(int opPos) throws TransformerException
-  {
-    return compileUnary(new org.apache.xpath.operations.Number(), opPos);
-  }
-
-  /**
-   * Compile a literal string value.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.objects.XString} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression literal(int opPos)
-  {
-
-    opPos = getFirstChildPos(opPos);
-
-    return (XString) m_tokenQueue[m_opMap[opPos]];
-  }
-
-  /**
-   * Compile a literal number value.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.objects.XNumber} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression numberlit(int opPos)
-  {
-
-    opPos = getFirstChildPos(opPos);
-
-    return (XNumber) m_tokenQueue[m_opMap[opPos]];
-  }
-
-  /**
-   * Compile a variable reference.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.operations.Variable} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression variable(int opPos) throws TransformerException
-  {
-
-    Variable var = new Variable();
-
-    opPos = getFirstChildPos(opPos);
-
-    int nsPos = m_opMap[opPos];
-    java.lang.String namespace 
-      = (OpCodes.EMPTY == nsPos) ? null 
-                                   : (java.lang.String) m_tokenQueue[nsPos];
-    java.lang.String localname 
-      = (java.lang.String) m_tokenQueue[m_opMap[opPos+1]];
-    QName qname = new QName(namespace, localname);
-
-    var.setQName(qname);
-
-    return var;
-  }
-
-  /**
-   * Compile an expression group.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to the contained expression.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression group(int opPos) throws TransformerException
-  {
-
-    // no-op
-    return compile(opPos + 2);
-  }
-
-  /**
-   * Compile a function argument.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to the argument expression.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression arg(int opPos) throws TransformerException
-  {
-
-    // no-op
-    return compile(opPos + 2);
-  }
-
-  /**
-   * Compile a location path union. The UnionPathIterator itself may create
-   * {@link org.apache.xpath.axes.LocPathIterator} children.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.axes.LocPathIterator} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression union(int opPos) throws TransformerException
-  {
-    locPathDepth++;
-    try
-    {
-      return UnionPathIterator.createUnionIterator(this, opPos);
-    }
-    finally
-    {
-      locPathDepth--;
-    }
-  }
-  
-  private int locPathDepth = -1;
-  
-  /**
-   * Get the level of the location path or union being constructed.  
-   * @return 0 if it is a top-level path.
-   */
-  public int getLocationPathDepth()
-  {
-    return locPathDepth;
-  }
-
-  /**
-   * Compile a location path.  The LocPathIterator itself may create
-   * {@link org.apache.xpath.axes.AxesWalker} children.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.axes.LocPathIterator} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  public Expression locationPath(int opPos) throws TransformerException
-  {
-    locPathDepth++;
-    try
-    {
-      DTMIterator iter = WalkerFactory.newDTMIterator(this, opPos, (locPathDepth == 0));
-      return (Expression)iter; // cast OK, I guess.
-    }
-    finally
-    {
-      locPathDepth--;
-    }
-  }
-
-  /**
-   * Compile a location step predicate expression.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return the contained predicate expression.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  public Expression predicate(int opPos) throws TransformerException
-  {
-    return compile(opPos + 2);
-  }
-
-  /**
-   * Compile an entire match pattern expression.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.patterns.UnionPattern} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected Expression matchPattern(int opPos) throws TransformerException
-  {
-    locPathDepth++;
-    try
-    {
-      // First, count...
-      int nextOpPos = opPos;
-      int i;
-
-      for (i = 0; m_opMap[nextOpPos] == OpCodes.OP_LOCATIONPATHPATTERN; i++)
-      {
-        nextOpPos = getNextOpPos(nextOpPos);
-      }
-
-      if (i == 1)
-        return compile(opPos);
-
-      UnionPattern up = new UnionPattern();
-      StepPattern[] patterns = new StepPattern[i];
-
-      for (i = 0; m_opMap[opPos] == OpCodes.OP_LOCATIONPATHPATTERN; i++)
-      {
-        nextOpPos = getNextOpPos(opPos);
-        patterns[i] = (StepPattern) compile(opPos);
-        opPos = nextOpPos;
-      }
-
-      up.setPatterns(patterns);
-
-      return up;
-    }
-    finally
-    {
-      locPathDepth--;
-    }
-  }
-
-  /**
-   * Compile a location match pattern unit expression.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.patterns.StepPattern} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  public Expression locationPathPattern(int opPos)
-          throws TransformerException
-  {
-
-    opPos = getFirstChildPos(opPos);
-
-    return stepPattern(opPos, 0, null);
-  }
-
-  /**
-   * Get a {@link org.w3c.dom.traversal.NodeFilter} bit set that tells what 
-   * to show for a given node test.
-   *
-   * @param opPos the op map position for the location step.
-   *
-   * @return {@link org.w3c.dom.traversal.NodeFilter} bit set that tells what 
-   *         to show for a given node test.
-   */
-  public int getWhatToShow(int opPos)
-  {
-
-    int axesType = getOp(opPos);
-    int testType = getOp(opPos + 3);
-
-    // System.out.println("testType: "+testType);
-    switch (testType)
-    {
-    case OpCodes.NODETYPE_COMMENT :
-      return DTMFilter.SHOW_COMMENT;
-    case OpCodes.NODETYPE_TEXT :
-//      return DTMFilter.SHOW_TEXT | DTMFilter.SHOW_COMMENT;
-      return DTMFilter.SHOW_TEXT | DTMFilter.SHOW_CDATA_SECTION ;
-    case OpCodes.NODETYPE_PI :
-      return DTMFilter.SHOW_PROCESSING_INSTRUCTION;
-    case OpCodes.NODETYPE_NODE :
-//      return DTMFilter.SHOW_ALL;
-      switch (axesType)
-      {
-      case OpCodes.FROM_NAMESPACE:
-        return DTMFilter.SHOW_NAMESPACE;
-      case OpCodes.FROM_ATTRIBUTES :
-      case OpCodes.MATCH_ATTRIBUTE :
-        return DTMFilter.SHOW_ATTRIBUTE;
-      case OpCodes.FROM_SELF:
-      case OpCodes.FROM_ANCESTORS_OR_SELF:
-      case OpCodes.FROM_DESCENDANTS_OR_SELF:
-        return DTMFilter.SHOW_ALL;
-      default:
-        if (getOp(0) == OpCodes.OP_MATCHPATTERN)
-          return ~DTMFilter.SHOW_ATTRIBUTE
-                  & ~DTMFilter.SHOW_DOCUMENT
-                  & ~DTMFilter.SHOW_DOCUMENT_FRAGMENT;
-        else
-          return ~DTMFilter.SHOW_ATTRIBUTE;
-      }
-    case OpCodes.NODETYPE_ROOT :
-      return DTMFilter.SHOW_DOCUMENT | DTMFilter.SHOW_DOCUMENT_FRAGMENT;
-    case OpCodes.NODETYPE_FUNCTEST :
-      return NodeTest.SHOW_BYFUNCTION;
-    case OpCodes.NODENAME :
-      switch (axesType)
-      {
-      case OpCodes.FROM_NAMESPACE :
-        return DTMFilter.SHOW_NAMESPACE;
-      case OpCodes.FROM_ATTRIBUTES :
-      case OpCodes.MATCH_ATTRIBUTE :
-        return DTMFilter.SHOW_ATTRIBUTE;
-
-      // break;
-      case OpCodes.MATCH_ANY_ANCESTOR :
-      case OpCodes.MATCH_IMMEDIATE_ANCESTOR :
-        return DTMFilter.SHOW_ELEMENT;
-
-      // break;
-      default :
-        return DTMFilter.SHOW_ELEMENT;
-      }
-    default :
-      // System.err.println("We should never reach here.");
-      return DTMFilter.SHOW_ALL;
-    }
-  }
-  
-private static final boolean DEBUG = false;
-
-  /**
-   * Compile a step pattern unit expression, used for both location paths 
-   * and match patterns.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   * @param stepCount The number of steps to expect.
-   * @param ancestorPattern The owning StepPattern, which may be null.
-   *
-   * @return reference to {@link org.apache.xpath.patterns.StepPattern} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  protected StepPattern stepPattern(
-          int opPos, int stepCount, StepPattern ancestorPattern)
-            throws TransformerException
-  {
-
-    int startOpPos = opPos;
-    int stepType = getOpMap()[opPos];
-
-    if (OpCodes.ENDOP == stepType)
-    {
-      return null;
-    }
-    
-    boolean addMagicSelf = true;
-
-    int endStep = getNextOpPos(opPos);
-
-    // int nextStepType = getOpMap()[endStep];
-    StepPattern pattern;
-    
-    // boolean isSimple = ((OpCodes.ENDOP == nextStepType) && (stepCount == 0));
-    int argLen;
-
-    switch (stepType)
-    {
-    case OpCodes.OP_FUNCTION :
-      if(DEBUG)
-        System.out.println("MATCH_FUNCTION: "+m_currentPattern); 
-      addMagicSelf = false;
-      argLen = m_opMap[opPos + OpMap.MAPINDEX_LENGTH];
-      pattern = new FunctionPattern(compileFunction(opPos), Axis.PARENT, Axis.CHILD);
-      break;
-    case OpCodes.FROM_ROOT :
-      if(DEBUG)
-        System.out.println("FROM_ROOT, "+m_currentPattern);
-      addMagicSelf = false;
-      argLen = getArgLengthOfStep(opPos);
-      opPos = getFirstChildPosOfStep(opPos);
-      pattern = new StepPattern(DTMFilter.SHOW_DOCUMENT | 
-                                DTMFilter.SHOW_DOCUMENT_FRAGMENT,
-                                Axis.PARENT, Axis.CHILD);
-      break;
-    case OpCodes.MATCH_ATTRIBUTE :
-     if(DEBUG)
-        System.out.println("MATCH_ATTRIBUTE: "+getStepLocalName(startOpPos)+", "+m_currentPattern);
-      argLen = getArgLengthOfStep(opPos);
-      opPos = getFirstChildPosOfStep(opPos);
-      pattern = new StepPattern(DTMFilter.SHOW_ATTRIBUTE,
-                                getStepNS(startOpPos),
-                                getStepLocalName(startOpPos),
-                                Axis.PARENT, Axis.ATTRIBUTE);
-      break;
-    case OpCodes.MATCH_ANY_ANCESTOR :
-      if(DEBUG)
-        System.out.println("MATCH_ANY_ANCESTOR: "+getStepLocalName(startOpPos)+", "+m_currentPattern);
-      argLen = getArgLengthOfStep(opPos);
-      opPos = getFirstChildPosOfStep(opPos);
-      int what = getWhatToShow(startOpPos);
-      // bit-o-hackery, but this code is due for the morgue anyway...
-      if(0x00000500 == what)
-        addMagicSelf = false;
-      pattern = new StepPattern(getWhatToShow(startOpPos),
-                                        getStepNS(startOpPos),
-                                        getStepLocalName(startOpPos),
-                                        Axis.ANCESTOR, Axis.CHILD);
-      break;
-    case OpCodes.MATCH_IMMEDIATE_ANCESTOR :
-      if(DEBUG)
-        System.out.println("MATCH_IMMEDIATE_ANCESTOR: "+getStepLocalName(startOpPos)+", "+m_currentPattern);
-      argLen = getArgLengthOfStep(opPos);
-      opPos = getFirstChildPosOfStep(opPos);
-      pattern = new StepPattern(getWhatToShow(startOpPos),
-                                getStepNS(startOpPos),
-                                getStepLocalName(startOpPos),
-                                Axis.PARENT, Axis.CHILD);
-      break;
-    default :
-      error(XPATHErrorResources.ER_UNKNOWN_MATCH_OPERATION, null);  //"unknown match operation!");
-
-      return null;
-    }
-
-    pattern.setPredicates(getCompiledPredicates(opPos + argLen));
-    if(null == ancestorPattern)
-    {
-      // This is the magic and invisible "." at the head of every 
-      // match pattern, and corresponds to the current node in the context 
-      // list, from where predicates are counted.
-      // So, in order to calculate "foo[3]", it has to count from the 
-      // current node in the context list, so, from that current node, 
-      // the full pattern is really "self::node()/child::foo[3]".  If you 
-      // translate this to a select pattern from the node being tested, 
-      // which is really how we're treating match patterns, it works out to 
-      // self::foo/parent::node[child::foo[3]]", or close enough.
-	/*      if(addMagicSelf && pattern.getPredicateCount() > 0)
-      {
-        StepPattern selfPattern = new StepPattern(DTMFilter.SHOW_ALL, 
-                                                  Axis.PARENT, Axis.CHILD);
-        // We need to keep the new nodetest from affecting the score...
-        XNumber score = pattern.getStaticScore();
-        pattern.setRelativePathPattern(selfPattern);
-        pattern.setStaticScore(score);
-        selfPattern.setStaticScore(score);
-	}*/
-    }
-    else
-    {
-      // System.out.println("Setting "+ancestorPattern+" as relative to "+pattern);
-      pattern.setRelativePathPattern(ancestorPattern);
-    }
-
-    StepPattern relativePathPattern = stepPattern(endStep, stepCount + 1,
-                                        pattern);
-
-    return (null != relativePathPattern) ? relativePathPattern : pattern;
-  }
-
-  /**
-   * Compile a zero or more predicates for a given match pattern.
-   * 
-   * @param opPos The position of the first predicate the m_opMap array.
-   *
-   * @return reference to array of {@link org.apache.xpath.Expression} instances.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  public Expression[] getCompiledPredicates(int opPos)
-          throws TransformerException
-  {
-
-    int count = countPredicates(opPos);
-
-    if (count > 0)
-    {
-      Expression[] predicates = new Expression[count];
-
-      compilePredicates(opPos, predicates);
-
-      return predicates;
-    }
-
-    return null;
-  }
-
-  /**
-   * Count the number of predicates in the step.
-   *
-   * @param opPos The position of the first predicate the m_opMap array.
-   *
-   * @return The number of predicates for this step.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  public int countPredicates(int opPos) throws TransformerException
-  {
-
-    int count = 0;
-
-    while (OpCodes.OP_PREDICATE == getOp(opPos))
-    {
-      count++;
-
-      opPos = getNextOpPos(opPos);
-    }
-
-    return count;
-  }
-
-  /**
-   * Compiles predicates in the step.
-   *
-   * @param opPos The position of the first predicate the m_opMap array.
-   * @param predicates An empty pre-determined array of 
-   *            {@link org.apache.xpath.Expression}s, that will be filled in.
-   *
-   * @throws TransformerException
-   */
-  private void compilePredicates(int opPos, Expression[] predicates)
-          throws TransformerException
-  {
-
-    for (int i = 0; OpCodes.OP_PREDICATE == getOp(opPos); i++)
-    {
-      predicates[i] = predicate(opPos);
-      opPos = getNextOpPos(opPos);
-    }
-  }
-
-  /**
-   * Compile a built-in XPath function.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.functions.Function} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  Expression compileFunction(int opPos) throws TransformerException
-  {
-
-    int endFunc = opPos + m_opMap[opPos + 1] - 1;
-
-    opPos = getFirstChildPos(opPos);
-
-    int funcID = m_opMap[opPos];
-
-    opPos++;
-
-    if (-1 != funcID)
-    {
-      Function func = FunctionTable.getFunction(funcID);
-
-      func.postCompileStep(this);
-      
-      try
-      {
-        int i = 0;
-
-        for (int p = opPos; p < endFunc; p = getNextOpPos(p), i++)
-        {
-
-          // System.out.println("argPos: "+ p);
-          // System.out.println("argCode: "+ m_opMap[p]);
-          func.setArg(compile(p), i);
-        }
-
-        func.checkNumberArgs(i);
-      }
-      catch (WrongNumberArgsException wnae)
-      {
-        java.lang.String name = FunctionTable.m_functions[funcID].getName();
-
-        m_errorHandler.fatalError( new TransformerException(
-                  XSLMessages.createXPATHMessage(XPATHErrorResources.ER_ONLY_ALLOWS, 
-                      new Object[]{name, wnae.getMessage()}), m_locator)); 
-              //"name + " only allows " + wnae.getMessage() + " arguments", m_locator));
-      }
-
-      return func;
-    }
-    else
-    {
-      error(XPATHErrorResources.ER_FUNCTION_TOKEN_NOT_FOUND, null);  //"function token not found.");
-
-      return null;
-    }
-  }
-
-  /**
-   * Compile an extension function.
-   * 
-   * @param opPos The current position in the m_opMap array.
-   *
-   * @return reference to {@link org.apache.xpath.functions.FuncExtFunction} instance.
-   *
-   * @throws TransformerException if a error occurs creating the Expression.
-   */
-  private Expression compileExtension(int opPos)
-          throws TransformerException
-  {
-
-    int endExtFunc = opPos + m_opMap[opPos + 1] - 1;
-
-    opPos = getFirstChildPos(opPos);
-
-    java.lang.String ns = (java.lang.String) m_tokenQueue[m_opMap[opPos]];
-
-    opPos++;
-
-    java.lang.String funcName =
-      (java.lang.String) m_tokenQueue[m_opMap[opPos]];
-
-    opPos++;
-
-    // We create a method key to uniquely identify this function so that we
-    // can cache the object needed to invoke it.  This way, we only pay the
-    // reflection overhead on the first call.
-
-    Function extension = new FuncExtFunction(ns, funcName, 
-         String.valueOf(opPos)
-       + String.valueOf(hashCode())
-       + String.valueOf(System.currentTimeMillis()));
-
-    try
-    {
-      int i = 0;
-
-      while (opPos < endExtFunc)
-      {
-        int nextOpPos = getNextOpPos(opPos);
-
-        extension.setArg(this.compile(opPos), i);
-
-        opPos = nextOpPos;
-
-        i++;
-      }
-    }
-    catch (WrongNumberArgsException wnae)
-    {
-      ;  // should never happen
-    }
-
-    return extension;
-  }
-
-  /**
-   * Warn the user of an problem.
-   *
-   * @param msg An error number that corresponds to one of the numbers found 
-   *            in {@link org.apache.xpath.res.XPATHErrorResources}, which is 
-   *            a key for a format string.
-   * @param args An array of arguments represented in the format string, which 
-   *             may be null.
-   *
-   * @throws TransformerException if the current ErrorListoner determines to 
-   *                              throw an exception.
-   */
-  public void warn(int msg, Object[] args) throws TransformerException
-  {
-
-    java.lang.String fmsg = XSLMessages.createXPATHWarning(msg, args);
-
-    if (null != m_errorHandler)
-    {
-      m_errorHandler.warning(new TransformerException(fmsg, m_locator));
-    }
-    else
-    {
-      System.out.println(fmsg
-                          +"; file "+m_locator.getSystemId()
-                          +"; line "+m_locator.getLineNumber()
-                          +"; column "+m_locator.getColumnNumber());
-    }
-  }
-
-  /**
-   * Tell the user of an assertion error, and probably throw an
-   * exception.
-   *
-   * @param b  If false, a runtime exception will be thrown.
-   * @param msg The assertion message, which should be informative.
-   * 
-   * @throws RuntimeException if the b argument is false.
-   */
-  public void assertion(boolean b, java.lang.String msg)
-  {
-
-    if (!b)
-    {
-      java.lang.String fMsg = XSLMessages.createXPATHMessage(
-        XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION,
-        new Object[]{ msg });
-
-      throw new RuntimeException(fMsg);
-    }
-  }
-
-  /**
-   * Tell the user of an error, and probably throw an
-   * exception.
-   *
-   * @param msg An error number that corresponds to one of the numbers found 
-   *            in {@link org.apache.xpath.res.XPATHErrorResources}, which is 
-   *            a key for a format string.
-   * @param args An array of arguments represented in the format string, which 
-   *             may be null.
-   *
-   * @throws TransformerException if the current ErrorListoner determines to 
-   *                              throw an exception.
-   */
-  public void error(int msg, Object[] args) throws TransformerException
-  {
-
-    java.lang.String fmsg = XSLMessages.createXPATHMessage(msg, args);
-    
-
-    if (null != m_errorHandler)
-    {
-      m_errorHandler.fatalError(new TransformerException(fmsg, m_locator));
-    }
-    else
-    {
-
-      // System.out.println(te.getMessage()
-      //                    +"; file "+te.getSystemId()
-      //                    +"; line "+te.getLineNumber()
-      //                    +"; column "+te.getColumnNumber());
-      throw new TransformerException(fmsg, (SAXSourceLocator)m_locator);
-    }
-  }
-
-  /**
-   * The current prefixResolver for the execution context.
-   */
-  private PrefixResolver m_currentPrefixResolver = null;
-
-  /**
-   * Get the current namespace context for the xpath.
-   *
-   * @return The current prefix resolver, *may* be null, though hopefully not.
-   */
-  public PrefixResolver getNamespaceContext()
-  {
-    return m_currentPrefixResolver;
-  }
-
-  /**
-   * Set the current namespace context for the xpath.
-   *
-   * @param pr The resolver for prefixes in the XPath expression.
-   */
-  public void setNamespaceContext(PrefixResolver pr)
-  {
-    m_currentPrefixResolver = pr;
-  }
-
-  /** The error listener where errors will be sent.  If this is null, errors 
-   *  and warnings will be sent to System.err.  May be null.    */
-  ErrorListener m_errorHandler;
-
-  /** The source locator for the expression being compiled.  May be null. */
-  SourceLocator m_locator;
-}
diff --git a/src/org/apache/xpath/compiler/FuncLoader.java b/src/org/apache/xpath/compiler/FuncLoader.java
deleted file mode 100644
index 0f63989..0000000
--- a/src/org/apache/xpath/compiler/FuncLoader.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 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.xpath.compiler;
-
-import java.lang.Class;
-
-import org.apache.xpath.res.XPATHErrorResources;
-
-import org.w3c.dom.Node;
-
-import java.util.Vector;
-
-import org.apache.xpath.XPathContext;
-import org.apache.xpath.XPath;
-import org.apache.xpath.objects.XObject;
-import org.apache.xpath.functions.Function;
-
-/**
- * <meta name="usage" content="advanced"/>
- * Lazy load of functions into the function table as needed, so we don't 
- * have to load all the functions allowed in XPath and XSLT on startup.
- */
-public class FuncLoader
-{
-
-  /** The function ID, which may correspond to one of the FUNC_XXX values 
-   *  found in {@link org.apache.xpath.compiler.FunctionTable}, but may 
-   *  be a value installed by an external module.  */
-  private int m_funcID;
-
-  /** The class name of the function.  Must not be null.   */
-  private String m_funcName;
-
-  /**
-   * Get the local class name of the function class.  If function name does 
-   * not have a '.' in it, it is assumed to be relative to 
-   * 'org.apache.xpath.functions'.
-   *
-   * @return The class name of the {org.apache.xpath.functions.Function} class.
-   */
-  public String getName()
-  {
-    return m_funcName;
-  }
-
-  /**
-   * Construct a function loader
-   *
-   * @param funcName The class name of the {org.apache.xpath.functions.Function} 
-   *             class, which, if it does not have a '.' in it, is assumed to 
-   *             be relative to 'org.apache.xpath.functions'. 
-   * @param funcID  The function ID, which may correspond to one of the FUNC_XXX 
-   *    values found in {@link org.apache.xpath.compiler.FunctionTable}, but may 
-   *    be a value installed by an external module. 
-   */
-  public FuncLoader(String funcName, int funcID)
-  {
-
-    super();
-
-    m_funcID = funcID;
-    m_funcName = funcName;
-  }
-
-  /**
-   * Get a Function instance that this instance is liaisoning for.
-   *
-   * @return non-null reference to Function derivative.
-   *
-   * @throws javax.xml.transform.TransformerException if ClassNotFoundException, 
-   *    IllegalAccessException, or InstantiationException is thrown.
-   */
-  public Function getFunction() throws javax.xml.transform.TransformerException
-  {
-
-    try
-    {
-      Class function;
-
-      // first get package name if necessary
-      if (m_funcName.indexOf(".") < 0)
-      {
-
-        // String thisName = this.getClass().getName();
-        // int lastdot = thisName.lastIndexOf(".");
-        // String classname = thisName.substring(0,lastdot+1) + m_funcName; 
-        String classname = "org.apache.xpath.functions." + m_funcName;
-
-        function = Class.forName(classname);
-      }
-      else
-        function = Class.forName(m_funcName);
-
-      Function func = (Function) function.newInstance();
-
-      return func;
-    }
-    catch (ClassNotFoundException e)
-    {
-      throw new javax.xml.transform.TransformerException(e);
-    }
-    catch (IllegalAccessException e)
-    {
-      throw new javax.xml.transform.TransformerException(e);
-    }
-    catch (InstantiationException e)
-    {
-      throw new javax.xml.transform.TransformerException(e);
-    }
-  }
-}
diff --git a/src/org/apache/xpath/compiler/FunctionTable.java b/src/org/apache/xpath/compiler/FunctionTable.java
deleted file mode 100644
index 40f4878..0000000
--- a/src/org/apache/xpath/compiler/FunctionTable.java
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 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.xpath.compiler;
-
-import org.apache.xpath.Expression;
-import org.apache.xpath.functions.Function;
-
-/**
- * The function table for XPath.
- */
-public class FunctionTable
-{
-
-  /** The 'current()' id. */
-  public static final int FUNC_CURRENT = 0;
-
-  /** The 'last()' id. */
-  public static final int FUNC_LAST = 1;
-
-  /** The 'position()' id. */
-  public static final int FUNC_POSITION = 2;
-
-  /** The 'count()' id. */
-  public static final int FUNC_COUNT = 3;
-
-  /** The 'id()' id. */
-  public static final int FUNC_ID = 4;
-
-  /** The 'key()' id (XSLT). */
-  public static final int FUNC_KEY = 5;
-
-  /** The 'local-name()' id. */
-  public static final int FUNC_LOCAL_PART = 7;
-
-  /** The 'namespace-uri()' id. */
-  public static final int FUNC_NAMESPACE = 8;
-
-  /** The 'name()' id. */
-  public static final int FUNC_QNAME = 9;
-
-  /** The 'generate-id()' id. */
-  public static final int FUNC_GENERATE_ID = 10;
-
-  /** The 'not()' id. */
-  public static final int FUNC_NOT = 11;
-
-  /** The 'true()' id. */
-  public static final int FUNC_TRUE = 12;
-
-  /** The 'false()' id. */
-  public static final int FUNC_FALSE = 13;
-
-  /** The 'boolean()' id. */
-  public static final int FUNC_BOOLEAN = 14;
-
-  /** The 'number()' id. */
-  public static final int FUNC_NUMBER = 15;
-
-  /** The 'floor()' id. */
-  public static final int FUNC_FLOOR = 16;
-
-  /** The 'ceiling()' id. */
-  public static final int FUNC_CEILING = 17;
-
-  /** The 'round()' id. */
-  public static final int FUNC_ROUND = 18;
-
-  /** The 'sum()' id. */
-  public static final int FUNC_SUM = 19;
-
-  /** The 'string()' id. */
-  public static final int FUNC_STRING = 20;
-
-  /** The 'starts-with()' id. */
-  public static final int FUNC_STARTS_WITH = 21;
-
-  /** The 'contains()' id. */
-  public static final int FUNC_CONTAINS = 22;
-
-  /** The 'substring-before()' id. */
-  public static final int FUNC_SUBSTRING_BEFORE = 23;
-
-  /** The 'substring-after()' id. */
-  public static final int FUNC_SUBSTRING_AFTER = 24;
-
-  /** The 'normalize-space()' id. */
-  public static final int FUNC_NORMALIZE_SPACE = 25;
-
-  /** The 'translate()' id. */
-  public static final int FUNC_TRANSLATE = 26;
-
-  /** The 'concat()' id. */
-  public static final int FUNC_CONCAT = 27;
-
-  /** The 'substring()' id. */
-  public static final int FUNC_SUBSTRING = 29;
-
-  /** The 'string-length()' id. */
-  public static final int FUNC_STRING_LENGTH = 30;
-
-  /** The 'system-property()' id. */
-  public static final int FUNC_SYSTEM_PROPERTY = 31;
-
-  /** The 'lang()' id. */
-  public static final int FUNC_LANG = 32;
-
-  /** The 'function-available()' id (XSLT). */
-  public static final int FUNC_EXT_FUNCTION_AVAILABLE = 33;
-
-  /** The 'element-available()' id (XSLT). */
-  public static final int FUNC_EXT_ELEM_AVAILABLE = 34;
-
-  /** The 'unparsed-entity-uri()' id (XSLT). */
-  public static final int FUNC_UNPARSED_ENTITY_URI = 36;
-
-  // Proprietary
-
-  /** The 'document-location()' id (Proprietary). */
-  public static final int FUNC_DOCLOCATION = 35;
-
-  /**
-   * The function table.
-   */
-  public static FuncLoader m_functions[];
-
-  /**
-   * Number of built in functions.  Be sure to update this as
-   * built-in functions are added.
-   */
-  private static final int NUM_BUILT_IN_FUNCS = 37;
-
-  /**
-   * Number of built-in functions that may be added.
-   */
-  private static final int NUM_ALLOWABLE_ADDINS = 30;
-
-  /**
-   * The index to the next free function index.
-   */
-  static int m_funcNextFreeIndex = NUM_BUILT_IN_FUNCS;
-
-  static
-  {
-    m_functions = new FuncLoader[NUM_BUILT_IN_FUNCS + NUM_ALLOWABLE_ADDINS];
-    m_functions[FUNC_CURRENT] = new FuncLoader("FuncCurrent", FUNC_CURRENT);
-    m_functions[FUNC_LAST] = new FuncLoader("FuncLast", FUNC_LAST);
-    m_functions[FUNC_POSITION] = new FuncLoader("FuncPosition",
-                                                FUNC_POSITION);
-    m_functions[FUNC_COUNT] = new FuncLoader("FuncCount", FUNC_COUNT);
-    m_functions[FUNC_ID] = new FuncLoader("FuncId", FUNC_ID);
-    m_functions[FUNC_KEY] =
-      new FuncLoader("org.apache.xalan.templates.FuncKey", FUNC_KEY);
-
-    // m_functions[FUNC_DOC] = new FuncDoc();
-    m_functions[FUNC_LOCAL_PART] = new FuncLoader("FuncLocalPart",
-            FUNC_LOCAL_PART);
-    m_functions[FUNC_NAMESPACE] = new FuncLoader("FuncNamespace",
-            FUNC_NAMESPACE);
-    m_functions[FUNC_QNAME] = new FuncLoader("FuncQname", FUNC_QNAME);
-    m_functions[FUNC_GENERATE_ID] = new FuncLoader("FuncGenerateId",
-            FUNC_GENERATE_ID);
-    m_functions[FUNC_NOT] = new FuncLoader("FuncNot", FUNC_NOT);
-    m_functions[FUNC_TRUE] = new FuncLoader("FuncTrue", FUNC_TRUE);
-    m_functions[FUNC_FALSE] = new FuncLoader("FuncFalse", FUNC_FALSE);
-    m_functions[FUNC_BOOLEAN] = new FuncLoader("FuncBoolean", FUNC_BOOLEAN);
-    m_functions[FUNC_LANG] = new FuncLoader("FuncLang", FUNC_LANG);
-    m_functions[FUNC_NUMBER] = new FuncLoader("FuncNumber", FUNC_NUMBER);
-    m_functions[FUNC_FLOOR] = new FuncLoader("FuncFloor", FUNC_FLOOR);
-    m_functions[FUNC_CEILING] = new FuncLoader("FuncCeiling", FUNC_CEILING);
-    m_functions[FUNC_ROUND] = new FuncLoader("FuncRound", FUNC_ROUND);
-    m_functions[FUNC_SUM] = new FuncLoader("FuncSum", FUNC_SUM);
-    m_functions[FUNC_STRING] = new FuncLoader("FuncString", FUNC_STRING);
-    m_functions[FUNC_STARTS_WITH] = new FuncLoader("FuncStartsWith",
-            FUNC_STARTS_WITH);
-    m_functions[FUNC_CONTAINS] = new FuncLoader("FuncContains",
-                                                FUNC_CONTAINS);
-    m_functions[FUNC_SUBSTRING_BEFORE] = new FuncLoader("FuncSubstringBefore",
-            FUNC_SUBSTRING_BEFORE);
-    m_functions[FUNC_SUBSTRING_AFTER] = new FuncLoader("FuncSubstringAfter",
-            FUNC_SUBSTRING_AFTER);
-    m_functions[FUNC_NORMALIZE_SPACE] = new FuncLoader("FuncNormalizeSpace",
-            FUNC_NORMALIZE_SPACE);
-    m_functions[FUNC_TRANSLATE] = new FuncLoader("FuncTranslate",
-            FUNC_TRANSLATE);
-    m_functions[FUNC_CONCAT] = new FuncLoader("FuncConcat", FUNC_CONCAT);
-
-    //m_functions[FUNC_FORMAT_NUMBER] = new FuncFormatNumber();
-    m_functions[FUNC_SYSTEM_PROPERTY] = new FuncLoader("FuncSystemProperty",
-            FUNC_SYSTEM_PROPERTY);
-    m_functions[FUNC_EXT_FUNCTION_AVAILABLE] =
-      new FuncLoader("FuncExtFunctionAvailable", FUNC_EXT_FUNCTION_AVAILABLE);
-    m_functions[FUNC_EXT_ELEM_AVAILABLE] =
-      new FuncLoader("FuncExtElementAvailable", FUNC_EXT_ELEM_AVAILABLE);
-    m_functions[FUNC_SUBSTRING] = new FuncLoader("FuncSubstring",
-            FUNC_SUBSTRING);
-    m_functions[FUNC_STRING_LENGTH] = new FuncLoader("FuncStringLength",
-            FUNC_STRING_LENGTH);
-    m_functions[FUNC_DOCLOCATION] = new FuncLoader("FuncDoclocation",
-            FUNC_DOCLOCATION);
-    m_functions[FUNC_UNPARSED_ENTITY_URI] =
-      new FuncLoader("FuncUnparsedEntityURI", FUNC_UNPARSED_ENTITY_URI);
-  }
-
-  /**
-   * Obtain a new Function object from a function ID.
-   *
-   * @param which  The function ID, which may correspond to one of the FUNC_XXX 
-   *    values found in {@link org.apache.xpath.compiler.FunctionTable}, but may 
-   *    be a value installed by an external module. 
-   *
-   * @return a a new Function instance.
-   *
-   * @throws javax.xml.transform.TransformerException if ClassNotFoundException, 
-   *    IllegalAccessException, or InstantiationException is thrown.
-   */
-  public static Function getFunction(int which)
-          throws javax.xml.transform.TransformerException
-  {
-    return m_functions[which].getFunction();
-  }
-
-  /**
-   * Install a built-in function.
-   * @param name The unqualified name of the function.
-   * @param func A Implementation of an XPath Function object.
-   * @return the position of the function in the internal index.
-   */
-  public static int installFunction(String name, Expression func)
-  {
-
-    int funcIndex;
-    Object funcIndexObj = Keywords.m_functions.get(name);
-
-    if (null != funcIndexObj)
-    {
-      funcIndex = ((Integer) funcIndexObj).intValue();
-    }
-    else
-    {
-      funcIndex = m_funcNextFreeIndex;
-
-      m_funcNextFreeIndex++;
-
-      Keywords.m_functions.put(name, new Integer(funcIndex));
-    }
-
-    FuncLoader loader = new FuncLoader(func.getClass().getName(), funcIndex);
-
-    m_functions[funcIndex] = loader;
-
-    return funcIndex;
-  }
-
-  /**
-   * Install a function loader at a specific index.
-   * @param func A Implementation of an XPath Function object.
-   * @param which  The function ID, which may correspond to one of the FUNC_XXX 
-   *    values found in {@link org.apache.xpath.compiler.FunctionTable}, but may 
-   *    be a value installed by an external module. 
-   * @return the position of the function in the internal index.
-   */
-  public static void installFunction(Expression func, int funcIndex)
-  {
-
-    FuncLoader loader = new FuncLoader(func.getClass().getName(), funcIndex);
-
-    m_functions[funcIndex] = loader;
-  }
-}
diff --git a/src/org/apache/xpath/compiler/Keywords.java b/src/org/apache/xpath/compiler/Keywords.java
deleted file mode 100644
index 14e1a44..0000000
--- a/src/org/apache/xpath/compiler/Keywords.java
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 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.xpath.compiler;
-
-import java.util.Hashtable;
-
-/**
- * <meta name="usage" content="internal"/>
- * Table of strings to operation code lookups.
- */
-public class Keywords
-{
-
-  /** Table of keywords to opcode associations. */
-  static Hashtable m_keywords = new Hashtable();
-
-  /** Table of axes names to opcode associations. */
-  static Hashtable m_axisnames = new Hashtable();
-
-  /** Table of function name to function ID associations. */
-  static Hashtable m_functions = new Hashtable();
-
-  /** Table of node type strings to opcode associations. */
-  static Hashtable m_nodetypes = new Hashtable();
-
-  /** ancestor axes string. */
-  private static final String FROM_ANCESTORS_STRING = "ancestor";
-
-  /** ancestor-or-self axes string. */
-  private static final String FROM_ANCESTORS_OR_SELF_STRING =
-    "ancestor-or-self";
-
-  /** attribute axes string. */
-  private static final String FROM_ATTRIBUTES_STRING = "attribute";
-
-  /** child axes string. */
-  private static final String FROM_CHILDREN_STRING = "child";
-
-  /** descendant-or-self axes string. */
-  private static final String FROM_DESCENDANTS_STRING = "descendant";
-
-  /** ancestor axes string. */
-  private static final String FROM_DESCENDANTS_OR_SELF_STRING =
-    "descendant-or-self";
-
-  /** following axes string. */
-  private static final String FROM_FOLLOWING_STRING = "following";
-
-  /** following-sibling axes string. */
-  private static final String FROM_FOLLOWING_SIBLINGS_STRING =
-    "following-sibling";
-
-  /** parent axes string. */
-  private static final String FROM_PARENT_STRING = "parent";
-
-  /** preceding axes string. */
-  private static final String FROM_PRECEDING_STRING = "preceding";
-
-  /** preceding-sibling axes string. */
-  private static final String FROM_PRECEDING_SIBLINGS_STRING =
-    "preceding-sibling";
-
-  /** self axes string. */
-  private static final String FROM_SELF_STRING = "self";
-
-  /** namespace axes string. */
-  private static final String FROM_NAMESPACE_STRING = "namespace";
-
-  /** self axes abreviated string. */
-  private static final String FROM_SELF_ABBREVIATED_STRING = ".";
-
-  /** comment node test string. */
-  private static final String NODETYPE_COMMENT_STRING = "comment";
-
-  /** text node test string. */
-  private static final String NODETYPE_TEXT_STRING = "text";
-
-  /** processing-instruction node test string. */
-  private static final String NODETYPE_PI_STRING = "processing-instruction";
-
-  /** Any node test string. */
-  private static final String NODETYPE_NODE_STRING = "node";
-
-  /** Wildcard element string. */
-  private static final String NODETYPE_ANYELEMENT_STRING = "*";
-
-  /** current function string. */
-  private static final String FUNC_CURRENT_STRING = "current";
-
-  /** last function string. */
-  private static final String FUNC_LAST_STRING = "last";
-
-  /** position function string. */
-  private static final String FUNC_POSITION_STRING = "position";
-
-  /** count function string. */
-  private static final String FUNC_COUNT_STRING = "count";
-
-  /** id function string. */
-  static final String FUNC_ID_STRING = "id";
-
-  /** key function string (XSLT). */
-  public static final String FUNC_KEY_STRING = "key";
-
-  /** local-name function string. */
-  private static final String FUNC_LOCAL_PART_STRING = "local-name";
-
-  /** namespace-uri function string. */
-  private static final String FUNC_NAMESPACE_STRING = "namespace-uri";
-
-  /** name function string. */
-  private static final String FUNC_NAME_STRING = "name";
-
-  /** generate-id function string (XSLT). */
-  private static final String FUNC_GENERATE_ID_STRING = "generate-id";
-
-  /** not function string. */
-  private static final String FUNC_NOT_STRING = "not";
-
-  /** true function string. */
-  private static final String FUNC_TRUE_STRING = "true";
-
-  /** false function string. */
-  private static final String FUNC_FALSE_STRING = "false";
-
-  /** boolean function string. */
-  private static final String FUNC_BOOLEAN_STRING = "boolean";
-
-  /** lang function string. */
-  private static final String FUNC_LANG_STRING = "lang";
-
-  /** number function string. */
-  private static final String FUNC_NUMBER_STRING = "number";
-
-  /** floor function string. */
-  private static final String FUNC_FLOOR_STRING = "floor";
-
-  /** ceiling function string. */
-  private static final String FUNC_CEILING_STRING = "ceiling";
-
-  /** round function string. */
-  private static final String FUNC_ROUND_STRING = "round";
-
-  /** sum function string. */
-  private static final String FUNC_SUM_STRING = "sum";
-
-  /** string function string. */
-  private static final String FUNC_STRING_STRING = "string";
-
-  /** starts-with function string. */
-  private static final String FUNC_STARTS_WITH_STRING = "starts-with";
-
-  /** contains function string. */
-  private static final String FUNC_CONTAINS_STRING = "contains";
-
-  /** substring-before function string. */
-  private static final String FUNC_SUBSTRING_BEFORE_STRING =
-    "substring-before";
-
-  /** substring-after function string. */
-  private static final String FUNC_SUBSTRING_AFTER_STRING = "substring-after";
-
-  /** normalize-space function string. */
-  private static final String FUNC_NORMALIZE_SPACE_STRING = "normalize-space";
-
-  /** translate function string. */
-  private static final String FUNC_TRANSLATE_STRING = "translate";
-
-  /** concat function string. */
-  private static final String FUNC_CONCAT_STRING = "concat";
-
-  /** system-property function string. */
-  private static final String FUNC_SYSTEM_PROPERTY_STRING = "system-property";
-
-  /** function-available function string (XSLT). */
-  private static final String FUNC_EXT_FUNCTION_AVAILABLE_STRING =
-    "function-available";
-
-  /** element-available function string (XSLT). */
-  private static final String FUNC_EXT_ELEM_AVAILABLE_STRING =
-    "element-available";
-
-  /** substring function string. */
-  private static final String FUNC_SUBSTRING_STRING = "substring";
-
-  /** string-length function string. */
-  private static final String FUNC_STRING_LENGTH_STRING = "string-length";
-
-  /** unparsed-entity-uri function string (XSLT). */
-  private static final String FUNC_UNPARSED_ENTITY_URI_STRING =
-    "unparsed-entity-uri";
-
-  // Proprietary, built in functions
-
-  /** current function string (Proprietary). */
-  private static final String FUNC_DOCLOCATION_STRING = "document-location";
-
-  static
-  {
-    m_axisnames.put(FROM_ANCESTORS_STRING,
-                    new Integer(OpCodes.FROM_ANCESTORS));
-    m_axisnames.put(FROM_ANCESTORS_OR_SELF_STRING,
-                    new Integer(OpCodes.FROM_ANCESTORS_OR_SELF));
-    m_axisnames.put(FROM_ATTRIBUTES_STRING,
-                    new Integer(OpCodes.FROM_ATTRIBUTES));
-    m_axisnames.put(FROM_CHILDREN_STRING,
-                    new Integer(OpCodes.FROM_CHILDREN));
-    m_axisnames.put(FROM_DESCENDANTS_STRING,
-                    new Integer(OpCodes.FROM_DESCENDANTS));
-    m_axisnames.put(FROM_DESCENDANTS_OR_SELF_STRING,
-                    new Integer(OpCodes.FROM_DESCENDANTS_OR_SELF));
-    m_axisnames.put(FROM_FOLLOWING_STRING,
-                    new Integer(OpCodes.FROM_FOLLOWING));
-    m_axisnames.put(FROM_FOLLOWING_SIBLINGS_STRING,
-                    new Integer(OpCodes.FROM_FOLLOWING_SIBLINGS));
-    m_axisnames.put(FROM_PARENT_STRING,
-                    new Integer(OpCodes.FROM_PARENT));
-    m_axisnames.put(FROM_PRECEDING_STRING,
-                    new Integer(OpCodes.FROM_PRECEDING));
-    m_axisnames.put(FROM_PRECEDING_SIBLINGS_STRING,
-                    new Integer(OpCodes.FROM_PRECEDING_SIBLINGS));
-    m_axisnames.put(FROM_SELF_STRING,
-                    new Integer(OpCodes.FROM_SELF));
-    m_axisnames.put(FROM_NAMESPACE_STRING,
-                    new Integer(OpCodes.FROM_NAMESPACE));
-    m_nodetypes.put(NODETYPE_COMMENT_STRING,
-                    new Integer(OpCodes.NODETYPE_COMMENT));
-    m_nodetypes.put(NODETYPE_TEXT_STRING,
-                    new Integer(OpCodes.NODETYPE_TEXT));
-    m_nodetypes.put(NODETYPE_PI_STRING,
-                    new Integer(OpCodes.NODETYPE_PI));
-    m_nodetypes.put(NODETYPE_NODE_STRING,
-                    new Integer(OpCodes.NODETYPE_NODE));
-    m_nodetypes.put(NODETYPE_ANYELEMENT_STRING,
-                    new Integer(OpCodes.NODETYPE_ANYELEMENT));
-    m_keywords.put(FROM_SELF_ABBREVIATED_STRING,
-                   new Integer(OpCodes.FROM_SELF));
-    m_keywords.put(FUNC_ID_STRING,
-                   new Integer(FunctionTable.FUNC_ID));
-    m_keywords.put(FUNC_KEY_STRING,
-                   new Integer(FunctionTable.FUNC_KEY));
-    m_functions.put(FUNC_CURRENT_STRING,
-                    new Integer(FunctionTable.FUNC_CURRENT));
-    m_functions.put(FUNC_LAST_STRING,
-                    new Integer(FunctionTable.FUNC_LAST));
-    m_functions.put(FUNC_POSITION_STRING,
-                    new Integer(FunctionTable.FUNC_POSITION));
-    m_functions.put(FUNC_COUNT_STRING,
-                    new Integer(FunctionTable.FUNC_COUNT));
-    m_functions.put(FUNC_ID_STRING,
-                    new Integer(FunctionTable.FUNC_ID));
-    m_functions.put(FUNC_KEY_STRING,
-                    new Integer(FunctionTable.FUNC_KEY));
-    m_functions.put(FUNC_LOCAL_PART_STRING,
-                    new Integer(FunctionTable.FUNC_LOCAL_PART));
-    m_functions.put(FUNC_NAMESPACE_STRING,
-                    new Integer(FunctionTable.FUNC_NAMESPACE));
-    m_functions.put(FUNC_NAME_STRING,
-                    new Integer(FunctionTable.FUNC_QNAME));
-    m_functions.put(FUNC_GENERATE_ID_STRING,
-                    new Integer(FunctionTable.FUNC_GENERATE_ID));
-    m_functions.put(FUNC_NOT_STRING,
-                    new Integer(FunctionTable.FUNC_NOT));
-    m_functions.put(FUNC_TRUE_STRING,
-                    new Integer(FunctionTable.FUNC_TRUE));
-    m_functions.put(FUNC_FALSE_STRING,
-                    new Integer(FunctionTable.FUNC_FALSE));
-    m_functions.put(FUNC_BOOLEAN_STRING,
-                    new Integer(FunctionTable.FUNC_BOOLEAN));
-    m_functions.put(FUNC_LANG_STRING,
-                    new Integer(FunctionTable.FUNC_LANG));
-    m_functions.put(FUNC_NUMBER_STRING,
-                    new Integer(FunctionTable.FUNC_NUMBER));
-    m_functions.put(FUNC_FLOOR_STRING,
-                    new Integer(FunctionTable.FUNC_FLOOR));
-    m_functions.put(FUNC_CEILING_STRING,
-                    new Integer(FunctionTable.FUNC_CEILING));
-    m_functions.put(FUNC_ROUND_STRING,
-                    new Integer(FunctionTable.FUNC_ROUND));
-    m_functions.put(FUNC_SUM_STRING,
-                    new Integer(FunctionTable.FUNC_SUM));
-    m_functions.put(FUNC_STRING_STRING,
-                    new Integer(FunctionTable.FUNC_STRING));
-    m_functions.put(FUNC_STARTS_WITH_STRING,
-                    new Integer(FunctionTable.FUNC_STARTS_WITH));
-    m_functions.put(FUNC_CONTAINS_STRING,
-                    new Integer(FunctionTable.FUNC_CONTAINS));
-    m_functions.put(FUNC_SUBSTRING_BEFORE_STRING,
-                    new Integer(FunctionTable.FUNC_SUBSTRING_BEFORE));
-    m_functions.put(FUNC_SUBSTRING_AFTER_STRING,
-                    new Integer(FunctionTable.FUNC_SUBSTRING_AFTER));
-    m_functions.put(FUNC_NORMALIZE_SPACE_STRING,
-                    new Integer(FunctionTable.FUNC_NORMALIZE_SPACE));
-    m_functions.put(FUNC_TRANSLATE_STRING,
-                    new Integer(FunctionTable.FUNC_TRANSLATE));
-    m_functions.put(FUNC_CONCAT_STRING,
-                    new Integer(FunctionTable.FUNC_CONCAT));
-
-    //m_functions.put(FUNC_FORMAT_NUMBER_STRING, new Integer(FunctionTable.FUNC_FORMAT_NUMBER));
-    m_functions.put(FUNC_SYSTEM_PROPERTY_STRING,
-                    new Integer(FunctionTable.FUNC_SYSTEM_PROPERTY));
-    m_functions.put(FUNC_EXT_FUNCTION_AVAILABLE_STRING,
-                    new Integer(FunctionTable.FUNC_EXT_FUNCTION_AVAILABLE));
-    m_functions.put(FUNC_EXT_ELEM_AVAILABLE_STRING,
-                    new Integer(FunctionTable.FUNC_EXT_ELEM_AVAILABLE));
-    m_functions.put(FUNC_SUBSTRING_STRING,
-                    new Integer(FunctionTable.FUNC_SUBSTRING));
-    m_functions.put(FUNC_STRING_LENGTH_STRING,
-                    new Integer(FunctionTable.FUNC_STRING_LENGTH));
-    m_functions.put(FUNC_UNPARSED_ENTITY_URI_STRING,
-                    new Integer(FunctionTable.FUNC_UNPARSED_ENTITY_URI));
-
-    // These aren't really functions.
-    m_functions.put(NODETYPE_COMMENT_STRING,
-                    new Integer(OpCodes.NODETYPE_COMMENT));
-    m_functions.put(NODETYPE_TEXT_STRING,
-                    new Integer(OpCodes.NODETYPE_TEXT));
-    m_functions.put(NODETYPE_PI_STRING,
-                    new Integer(OpCodes.NODETYPE_PI));
-    m_functions.put(NODETYPE_NODE_STRING,
-                    new Integer(OpCodes.NODETYPE_NODE));
-    m_functions.put(FUNC_DOCLOCATION_STRING,
-                    new Integer(FunctionTable.FUNC_DOCLOCATION));
-  }
-
-  /**
-   * Tell if a built-in, non-namespaced function is available.
-   *
-   * @param methName The local name of the function.
-   *
-   * @return True if the function can be executed.
-   */
-  public static boolean functionAvailable(String methName)
-  {
-
-    try
-    {
-      Object tblEntry = m_functions.get(methName);
-
-      if (null == tblEntry)
-        return false;
-
-      int funcType = ((Integer) tblEntry).intValue();
-
-      switch (funcType)
-      {
-      case OpCodes.NODETYPE_COMMENT :
-      case OpCodes.NODETYPE_TEXT :
-      case OpCodes.NODETYPE_PI :
-      case OpCodes.NODETYPE_NODE :
-        return false;  // These look like functions but they're NodeTests.
-      default :
-        return true;
-      }
-    }
-    catch (Exception e)
-    {
-      return false;
-    }
-  }
-}
diff --git a/src/org/apache/xpath/compiler/Lexer.java b/src/org/apache/xpath/compiler/Lexer.java
deleted file mode 100644
index 6a31e7e..0000000
--- a/src/org/apache/xpath/compiler/Lexer.java
+++ /dev/null
@@ -1,697 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 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.xpath.compiler;
-
-import org.apache.xml.utils.PrefixResolver;
-
-import java.util.Vector;
-
-import org.apache.xpath.res.XPATHErrorResources;
-import org.apache.xpath.XPath;
-import org.apache.xpath.compiler.Compiler;
-import org.apache.xpath.compiler.OpCodes;
-import org.apache.xpath.compiler.XPathParser;
-
-/**
- * This class is in charge of lexical processing of the XPath
- * expression into tokens.
- */
-class Lexer
-{
-
-  /**
-   * The target XPath.
-   */
-  private Compiler m_compiler;
-
-  /**
-   * The prefix resolver to map prefixes to namespaces in the XPath.
-   */
-  PrefixResolver m_namespaceContext;
-
-  /**
-   * The XPath processor object.
-   */
-  XPathParser m_processor;
-
-  /**
-   * This value is added to each element name in the TARGETEXTRA
-   * that is a 'target' (right-most top-level element name).
-   */
-  static final int TARGETEXTRA = 10000;
-
-  /**
-   * Ignore this, it is going away.
-   * This holds a map to the m_tokenQueue that tells where the top-level elements are.
-   * It is used for pattern matching so the m_tokenQueue can be walked backwards.
-   * Each element that is a 'target', (right-most top level element name) has
-   * TARGETEXTRA added to it.
-   *
-   */
-  private int m_patternMap[] = new int[100];
-
-  /**
-   * Ignore this, it is going away.
-   * The number of elements that m_patternMap maps;
-   */
-  private int m_patternMapSize;
-
-  /**
-   * Create a Lexer object.
-   *
-   * @param compiler The owning compiler for this lexer.
-   * @param resolver The prefix resolver for mapping qualified name prefixes 
-   *                 to namespace URIs.
-   * @param xpathProcessor The parser that is processing strings to opcodes.
-   */
-  Lexer(Compiler compiler, PrefixResolver resolver,
-        XPathParser xpathProcessor)
-  {
-
-    m_compiler = compiler;
-    m_namespaceContext = resolver;
-    m_processor = xpathProcessor;
-  }
-
-  /**
-   * Walk through the expression and build a token queue, and a map of the top-level
-   * elements.
-   * @param pat XSLT Expression.
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  void tokenize(String pat) throws javax.xml.transform.TransformerException
-  {
-    tokenize(pat, null);
-  }
-
-  /**
-   * Walk through the expression and build a token queue, and a map of the top-level
-   * elements.
-   * @param pat XSLT Expression.
-   * @param targetStrings Vector to hold Strings, may be null.
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  void tokenize(String pat, Vector targetStrings)
-          throws javax.xml.transform.TransformerException
-  {
-
-    m_compiler.m_tokenQueueSize = 0;
-    m_compiler.m_currentPattern = pat;
-    m_patternMapSize = 0;
-    m_compiler.m_opMap = new int[OpMap.MAXTOKENQUEUESIZE * 5];
-
-    int nChars = pat.length();
-    int startSubstring = -1;
-    int posOfNSSep = -1;
-    boolean isStartOfPat = true;
-    boolean isAttrName = false;
-    boolean isNum = false;
-
-    // Nesting of '[' so we can know if the given element should be
-    // counted inside the m_patternMap.
-    int nesting = 0;
-
-    // char[] chars = pat.toCharArray();
-    for (int i = 0; i < nChars; i++)
-    {
-      char c = pat.charAt(i);
-
-      switch (c)
-      {
-      case '\"' :
-      {
-        if (startSubstring != -1)
-        {
-          isNum = false;
-          isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);
-          isAttrName = false;
-
-          if (-1 != posOfNSSep)
-          {
-            posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, i);
-          }
-          else
-          {
-            addToTokenQueue(pat.substring(startSubstring, i));
-          }
-        }
-
-        startSubstring = i;
-
-        for (i++; (i < nChars) && ((c = pat.charAt(i)) != '\"'); i++);
-
-        if (c == '\"' && i < nChars)
-        {
-          addToTokenQueue(pat.substring(startSubstring, i + 1));
-
-          startSubstring = -1;
-        }
-        else
-        {
-          m_processor.error(XPATHErrorResources.ER_EXPECTED_DOUBLE_QUOTE,
-                            null);  //"misquoted literal... expected double quote!");
-        }
-      }
-      break;
-      case '\'' :
-        if (startSubstring != -1)
-        {
-          isNum = false;
-          isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);
-          isAttrName = false;
-
-          if (-1 != posOfNSSep)
-          {
-            posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, i);
-          }
-          else
-          {
-            addToTokenQueue(pat.substring(startSubstring, i));
-          }
-        }
-
-        startSubstring = i;
-
-        for (i++; (i < nChars) && ((c = pat.charAt(i)) != '\''); i++);
-
-        if (c == '\'' && i < nChars)
-        {
-          addToTokenQueue(pat.substring(startSubstring, i + 1));
-
-          startSubstring = -1;
-        }
-        else
-        {
-          m_processor.error(XPATHErrorResources.ER_EXPECTED_SINGLE_QUOTE,
-                            null);  //"misquoted literal... expected single quote!");
-        }
-        break;
-      case 0x0A :
-      case 0x0D :
-      case ' ' :
-      case '\t' :
-        if (startSubstring != -1)
-        {
-          isNum = false;
-          isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);
-          isAttrName = false;
-
-          if (-1 != posOfNSSep)
-          {
-            posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, i);
-          }
-          else
-          {
-            addToTokenQueue(pat.substring(startSubstring, i));
-          }
-
-          startSubstring = -1;
-        }
-        break;
-      case '@' :
-        isAttrName = true;
-
-      // fall-through on purpose
-      case '-' :
-        if ('-' == c)
-        {
-          if (!(isNum || (startSubstring == -1)))
-          {
-            break;
-          }
-
-          isNum = false;
-        }
-
-      // fall-through on purpose
-      case '(' :
-      case '[' :
-      case ')' :
-      case ']' :
-      case '|' :
-      case '/' :
-      case '*' :
-      case '+' :
-      case '=' :
-      case ',' :
-      case '\\' :  // Unused at the moment
-      case '^' :  // Unused at the moment
-      case '!' :  // Unused at the moment
-      case '$' :
-      case '<' :
-      case '>' :
-        if (startSubstring != -1)
-        {
-          isNum = false;
-          isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);
-          isAttrName = false;
-
-          if (-1 != posOfNSSep)
-          {
-            posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, i);
-          }
-          else
-          {
-            addToTokenQueue(pat.substring(startSubstring, i));
-          }
-
-          startSubstring = -1;
-        }
-        else if (('/' == c) && isStartOfPat)
-        {
-          isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);
-        }
-        else if ('*' == c)
-        {
-          isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);
-          isAttrName = false;
-        }
-
-        if (0 == nesting)
-        {
-          if ('|' == c)
-          {
-            if (null != targetStrings)
-            {
-              recordTokenString(targetStrings);
-            }
-
-            isStartOfPat = true;
-          }
-        }
-
-        if ((')' == c) || (']' == c))
-        {
-          nesting--;
-        }
-        else if (('(' == c) || ('[' == c))
-        {
-          nesting++;
-        }
-
-        addToTokenQueue(pat.substring(i, i + 1));
-        break;
-      case ':' :
-        if (i>0)
-        {
-          if (posOfNSSep == (i - 1))
-          {
-            if (startSubstring != -1)
-            {
-              if (startSubstring < (i - 1))
-                addToTokenQueue(pat.substring(startSubstring, i - 1));
-            }
-
-            isNum = false;
-            isAttrName = false;
-            startSubstring = -1;
-            posOfNSSep = -1;
-
-            addToTokenQueue(pat.substring(i - 1, i + 1));
-
-            break;
-          }
-          else
-          {
-            posOfNSSep = i;
-          }
-        }
-
-      // fall through on purpose
-      default :
-        if (-1 == startSubstring)
-        {
-          startSubstring = i;
-          isNum = Character.isDigit(c);
-        }
-        else if (isNum)
-        {
-          isNum = Character.isDigit(c);
-        }
-      }
-    }
-
-    if (startSubstring != -1)
-    {
-      isNum = false;
-      isStartOfPat = mapPatternElemPos(nesting, isStartOfPat, isAttrName);
-
-      if ((-1 != posOfNSSep) || 
-         ((m_namespaceContext != null) && (m_namespaceContext.handlesNullPrefixes())))
-      {
-        posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, nChars);
-      }
-      else
-      {
-        addToTokenQueue(pat.substring(startSubstring, nChars));
-      }
-    }
-
-    if (0 == m_compiler.m_tokenQueueSize)
-    {
-      m_processor.error(XPATHErrorResources.ER_EMPTY_EXPRESSION, null);  //"Empty expression!");
-    }
-    else if (null != targetStrings)
-    {
-      recordTokenString(targetStrings);
-    }
-
-    m_processor.m_queueMark = 0;
-  }
-
-  /**
-   * Record the current position on the token queue as long as
-   * this is a top-level element.  Must be called before the
-   * next token is added to the m_tokenQueue.
-   *
-   * @param nesting The nesting count for the pattern element.
-   * @param isStart true if this is the start of a pattern.
-   * @param isAttrName true if we have determined that this is an attribute name.
-   *
-   * @return true if this is the start of a pattern.
-   */
-  private boolean mapPatternElemPos(int nesting, boolean isStart,
-                                    boolean isAttrName)
-  {
-
-    if (0 == nesting)
-    {
-      if(m_patternMapSize >= m_patternMap.length)
-      {
-        int patternMap[] = m_patternMap;
-        int len = m_patternMap.length;
-        m_patternMap = new int[m_patternMapSize + 100];
-        System.arraycopy(patternMap, 0, m_patternMap, 0, len);
-      } 
-      if (!isStart)
-      {
-        m_patternMap[m_patternMapSize - 1] -= TARGETEXTRA;
-      }
-      m_patternMap[m_patternMapSize] =
-        (m_compiler.m_tokenQueueSize - (isAttrName ? 1 : 0)) + TARGETEXTRA;
-
-      m_patternMapSize++;
-
-      isStart = false;
-    }
-
-    return isStart;
-  }
-
-  /**
-   * Given a map pos, return the corresponding token queue pos.
-   *
-   * @param i The index in the m_patternMap.
-   *
-   * @return the token queue position.
-   */
-  private int getTokenQueuePosFromMap(int i)
-  {
-
-    int pos = m_patternMap[i];
-
-    return (pos >= TARGETEXTRA) ? (pos - TARGETEXTRA) : pos;
-  }
-
-  /**
-   * Reset token queue mark and m_token to a
-   * given position.
-   * @param mark The new position.
-   */
-  private final void resetTokenMark(int mark)
-  {
-
-    int qsz = m_compiler.m_tokenQueueSize;
-
-    m_processor.m_queueMark = (mark > 0)
-                              ? ((mark <= qsz) ? mark - 1 : mark) : 0;
-
-    if (m_processor.m_queueMark < qsz)
-    {
-      m_processor.m_token =
-        (String) m_compiler.m_tokenQueue[m_processor.m_queueMark++];
-      m_processor.m_tokenChar = m_processor.m_token.charAt(0);
-    }
-    else
-    {
-      m_processor.m_token = null;
-      m_processor.m_tokenChar = 0;
-    }
-  }
-
-  /**
-   * Given a string, return the corresponding keyword token.
-   *
-   * @param key The keyword.
-   *
-   * @return An opcode value.
-   */
-  final int getKeywordToken(String key)
-  {
-
-    int tok;
-
-    try
-    {
-      Integer itok = (Integer) Keywords.m_keywords.get(key);
-
-      tok = (null != itok) ? itok.intValue() : 0;
-    }
-    catch (NullPointerException npe)
-    {
-      tok = 0;
-    }
-    catch (ClassCastException cce)
-    {
-      tok = 0;
-    }
-
-    return tok;
-  }
-
-  /**
-   * Record the current token in the passed vector.
-   *
-   * @param targetStrings Vector of string.
-   */
-  private void recordTokenString(Vector targetStrings)
-  {
-
-    int tokPos = getTokenQueuePosFromMap(m_patternMapSize - 1);
-
-    resetTokenMark(tokPos + 1);
-
-    if (m_processor.lookahead('(', 1))
-    {
-      int tok = getKeywordToken(m_processor.m_token);
-
-      switch (tok)
-      {
-      case OpCodes.NODETYPE_COMMENT :
-        targetStrings.addElement(PsuedoNames.PSEUDONAME_COMMENT);
-        break;
-      case OpCodes.NODETYPE_TEXT :
-        targetStrings.addElement(PsuedoNames.PSEUDONAME_TEXT);
-        break;
-      case OpCodes.NODETYPE_NODE :
-        targetStrings.addElement(PsuedoNames.PSEUDONAME_ANY);
-        break;
-      case OpCodes.NODETYPE_ROOT :
-        targetStrings.addElement(PsuedoNames.PSEUDONAME_ROOT);
-        break;
-      case OpCodes.NODETYPE_ANYELEMENT :
-        targetStrings.addElement(PsuedoNames.PSEUDONAME_ANY);
-        break;
-      case OpCodes.NODETYPE_PI :
-        targetStrings.addElement(PsuedoNames.PSEUDONAME_ANY);
-        break;
-      default :
-        targetStrings.addElement(PsuedoNames.PSEUDONAME_ANY);
-      }
-    }
-    else
-    {
-      if (m_processor.tokenIs('@'))
-      {
-        tokPos++;
-
-        resetTokenMark(tokPos + 1);
-      }
-
-      if (m_processor.lookahead(':', 1))
-      {
-        tokPos += 2;
-      }
-
-      targetStrings.addElement(m_compiler.m_tokenQueue[tokPos]);
-    }
-  }
-
-  /**
-   * Add a token to the token queue.
-   *
-   *
-   * @param s The token.
-   */
-  private final void addToTokenQueue(String s)
-  {
-    m_compiler.m_tokenQueue[m_compiler.m_tokenQueueSize++] = s;
-  }
-
-  /**
-   * When a seperator token is found, see if there's a element name or
-   * the like to map.
-   *
-   * @param pat The XPath name string.
-   * @param startSubstring The start of the name string.
-   * @param posOfNSSep The position of the namespace seperator (':').
-   * @param posOfScan The end of the name index.
-   *
-   * @throws javax.xml.transform.TransformerException
-   *
-   * @return -1 always.
-   */
-  private int mapNSTokens(String pat, int startSubstring, int posOfNSSep,
-                          int posOfScan)
-           throws javax.xml.transform.TransformerException
- {
-
-    String prefix = "";
-    
-    if ((startSubstring >= 0) && (posOfNSSep >= 0))
-    {
-       prefix = pat.substring(startSubstring, posOfNSSep);
-    }
-    String uName;
-
-    if ((null != m_namespaceContext) &&!prefix.equals("*")
-            &&!prefix.equals("xmlns"))
-    {
-      try
-      {
-        if (prefix.length() > 0)
-          uName = ((PrefixResolver) m_namespaceContext).getNamespaceForPrefix(
-            prefix);
-        else
-        {
-
-          // Assume last was wildcard. This is not legal according
-          // to the draft. Set the below to true to make namespace
-          // wildcards work.
-          if (false)
-          {
-            addToTokenQueue(":");
-
-            String s = pat.substring(posOfNSSep + 1, posOfScan);
-
-            if (s.length() > 0)
-              addToTokenQueue(s);
-
-            return -1;
-          }
-          else
-          {
-            uName =
-              ((PrefixResolver) m_namespaceContext).getNamespaceForPrefix(
-                prefix);
-          }
-        }
-      }
-      catch (ClassCastException cce)
-      {
-        uName = m_namespaceContext.getNamespaceForPrefix(prefix);
-      }
-    }
-    else
-    {
-      uName = prefix;
-    }
-
-    if ((null != uName) && (uName.length() > 0))
-    {
-      addToTokenQueue(uName);
-      addToTokenQueue(":");
-
-      String s = pat.substring(posOfNSSep + 1, posOfScan);
-
-      if (s.length() > 0)
-        addToTokenQueue(s);
-    }
-    else
-    {
-
-      // error("Could not locate namespace for prefix: "+prefix);
-      m_processor.error(XPATHErrorResources.ER_PREFIX_MUST_RESOLVE,
-                 new String[] {prefix});  //"Prefix must resolve to a namespace: {0}";
-
-
-      /***  Old code commented out 10-Jan-2001
-      addToTokenQueue(prefix);
-      addToTokenQueue(":");
-
-      String s = pat.substring(posOfNSSep + 1, posOfScan);
-
-      if (s.length() > 0)
-        addToTokenQueue(s);
-      ***/
-    }
-
-    return -1;
-  }
-}
diff --git a/src/org/apache/xpath/compiler/OpCodes.java b/src/org/apache/xpath/compiler/OpCodes.java
deleted file mode 100644
index bac0a68..0000000
--- a/src/org/apache/xpath/compiler/OpCodes.java
+++ /dev/null
@@ -1,668 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 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.xpath.compiler;
-
-/**
- * Operations codes for XPath.
- *
- * Code for the descriptions of the operations codes:
- * [UPPER CASE] indicates a literal value,
- * [lower case] is a description of a value,
- *      ([length] always indicates the length of the operation,
- *       including the operations code and the length integer.)
- * {UPPER CASE} indicates the given production,
- * {description} is the description of a new production,
- *      (For instance, {boolean expression} means some expression
- *       that should be resolved to a boolean.)
- *  * means that it occurs zero or more times,
- *  + means that it occurs one or more times,
- *  ? means that it is optional.
- *
- * returns: indicates what the production should return.
- */
-public class OpCodes
-{
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [ENDOP]
-   * Some operators may like to have a terminator.
-   */
-  public static final int ENDOP = -1;
-
-  /**
-   * [EMPTY]
-   * Empty slot to indicate NULL.
-   */
-  public static final int EMPTY = -2;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [ELEMWILDCARD]
-   * Means ELEMWILDCARD ("*"), used instead
-   * of string index in some places.
-   */
-  public static final int ELEMWILDCARD = -3;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_XPATH]
-   * [length]
-   *  {expression}
-   *
-   * returns:
-   *  XNodeSet
-   *  XNumber
-   *  XString
-   *  XBoolean
-   *  XRTree
-   *  XObject
-   */
-  public static final int OP_XPATH = 1;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_OR]
-   * [length]
-   *  {boolean expression}
-   *  {boolean expression}
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int OP_OR = 2;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_AND]
-   * [length]
-   *  {boolean expression}
-   *  {boolean expression}
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int OP_AND = 3;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_NOTEQUALS]
-   * [length]
-   *  {expression}
-   *  {expression}
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int OP_NOTEQUALS = 4;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_EQUALS]
-   * [length]
-   *  {expression}
-   *  {expression}
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int OP_EQUALS = 5;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_LTE] (less-than-or-equals)
-   * [length]
-   *  {number expression}
-   *  {number expression}
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int OP_LTE = 6;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_LT] (less-than)
-   * [length]
-   *  {number expression}
-   *  {number expression}
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int OP_LT = 7;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_GTE] (greater-than-or-equals)
-   * [length]
-   *  {number expression}
-   *  {number expression}
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int OP_GTE = 8;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_GT] (greater-than)
-   * [length]
-   *  {number expression}
-   *  {number expression}
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int OP_GT = 9;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_PLUS]
-   * [length]
-   *  {number expression}
-   *  {number expression}
-   *
-   * returns:
-   *  XNumber
-   */
-  public static final int OP_PLUS = 10;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_MINUS]
-   * [length]
-   *  {number expression}
-   *  {number expression}
-   *
-   * returns:
-   *  XNumber
-   */
-  public static final int OP_MINUS = 11;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_MULT]
-   * [length]
-   *  {number expression}
-   *  {number expression}
-   *
-   * returns:
-   *  XNumber
-   */
-  public static final int OP_MULT = 12;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_DIV]
-   * [length]
-   *  {number expression}
-   *  {number expression}
-   *
-   * returns:
-   *  XNumber
-   */
-  public static final int OP_DIV = 13;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_MOD]
-   * [length]
-   *  {number expression}
-   *  {number expression}
-   *
-   * returns:
-   *  XNumber
-   */
-  public static final int OP_MOD = 14;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_QUO]
-   * [length]
-   *  {number expression}
-   *  {number expression}
-   *
-   * returns:
-   *  XNumber
-   */
-  public static final int OP_QUO = 15;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_NEG]
-   * [length]
-   *  {number expression}
-   *
-   * returns:
-   *  XNumber
-   */
-  public static final int OP_NEG = 16;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_STRING] (cast operation)
-   * [length]
-   *  {expression}
-   *
-   * returns:
-   *  XString
-   */
-  public static final int OP_STRING = 17;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_BOOL] (cast operation)
-   * [length]
-   *  {expression}
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int OP_BOOL = 18;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_NUMBER] (cast operation)
-   * [length]
-   *  {expression}
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int OP_NUMBER = 19;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_UNION]
-   * [length]
-   *  {PathExpr}+
-   *
-   * returns:
-   *  XNodeSet
-   */
-  public static final int OP_UNION = 20;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_LITERAL]
-   * [3]
-   * [index to token]
-   *
-   * returns:
-   *  XString
-   */
-  public static final int OP_LITERAL = 21;
-
-  /** The low opcode for nodesets, needed by getFirstPredicateOpPos and 
-   *  getNextStepPos.          */
-  static final int FIRST_NODESET_OP = 22;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_VARIABLE]
-   * [4]
-   * [index to namespace token, or EMPTY]
-   * [index to function name token]
-   *
-   * returns:
-   *  XString
-   */
-  public static final int OP_VARIABLE = 22;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_GROUP]
-   * [length]
-   *  {expression}
-   *
-   * returns:
-   *  XNodeSet
-   *  XNumber
-   *  XString
-   *  XBoolean
-   *  XRTree
-   *  XObject
-   */
-  public static final int OP_GROUP = 23;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_EXTFUNCTION] (Extension function.)
-   * [length]
-   * [index to namespace token]
-   * [index to function name token]
-   *  {OP_ARGUMENT}
-   *
-   * returns:
-   *  XNodeSet
-   *  XNumber
-   *  XString
-   *  XBoolean
-   *  XRTree
-   *  XObject
-   */
-  public static final int OP_EXTFUNCTION = 24;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_FUNCTION]
-   * [length]
-   * [FUNC_name]
-   *  {OP_ARGUMENT}
-   * [ENDOP]
-   *
-   * returns:
-   *  XNodeSet
-   *  XNumber
-   *  XString
-   *  XBoolean
-   *  XRTree
-   *  XObject
-   */
-  public static final int OP_FUNCTION = 25;
-
-  /** The last opcode for stuff that can be a nodeset.         */
-  static final int LAST_NODESET_OP = 25;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_ARGUMENT] (Function argument.)
-   * [length]
-   *  {expression}
-   *
-   * returns:
-   *  XNodeSet
-   *  XNumber
-   *  XString
-   *  XBoolean
-   *  XRTree
-   *  XObject
-   */
-  public static final int OP_ARGUMENT = 26;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_NUMBERLIT] (Number literal.)
-   * [3]
-   * [index to token]
-   *
-   * returns:
-   *  XString
-   */
-  public static final int OP_NUMBERLIT = 27;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_LOCATIONPATH]
-   * [length]
-   *   {FROM_stepType}
-   * | {function}
-   * {predicate}
-   * [ENDOP]
-   *
-   * (Note that element and attribute namespaces and
-   * names can be wildcarded '*'.)
-   *
-   * returns:
-   *  XNodeSet
-   */
-  public static final int OP_LOCATIONPATH = 28;
-
-  // public static final int LOCATIONPATHEX_MASK = 0x0000FFFF;
-  // public static final int LOCATIONPATHEX_ISSIMPLE = 0x00010000;
-  // public static final int OP_LOCATIONPATH_EX = (28 | 0x00010000);
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_PREDICATE]
-   * [length]
-   *  {expression}
-   * [ENDOP] (For safety)
-   *
-   * returns:
-   *  XBoolean or XNumber
-   */
-  public static final int OP_PREDICATE = 29;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_MATCHPATTERN]
-   * [length]
-   *  {PathExpr}+
-   *
-   * returns:
-   *  XNodeSet
-   */
-  public static final int OP_MATCHPATTERN = 30;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [OP_LOCATIONPATHPATTERN]
-   * [length]
-   *   {FROM_stepType}
-   * | {function}{predicate}
-   * [ENDOP]
-   * returns:
-   *  XNodeSet
-   */
-  public static final int OP_LOCATIONPATHPATTERN = 31;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [NODETYPE_COMMENT]
-   * No size or arguments.
-   * Note: must not overlap function OP number!
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int NODETYPE_COMMENT = 1030;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [NODETYPE_TEXT]
-   * No size or arguments.
-   * Note: must not overlap function OP number!
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int NODETYPE_TEXT = 1031;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [NODETYPE_PI]
-   * [index to token]
-   * Note: must not overlap function OP number!
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int NODETYPE_PI = 1032;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [NODETYPE_NODE]
-   * No size or arguments.
-   * Note: must not overlap function OP number!
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int NODETYPE_NODE = 1033;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [NODENAME]
-   * [index to ns token or EMPTY]
-   * [index to name token]
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int NODENAME = 34;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [NODETYPE_ROOT]
-   * No size or arguments.
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int NODETYPE_ROOT = 35;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [NODETYPE_ANY]
-   * No size or arguments.
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int NODETYPE_ANYELEMENT = 36;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [NODETYPE_ANY]
-   * No size or arguments.
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int NODETYPE_FUNCTEST = 1034;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * [FROM_stepType]
-   * [length, including predicates]
-   * [length of just the step, without the predicates]
-   * {node test}
-   * {predicates}?
-   *
-   * returns:
-   *  XBoolean
-   */
-  public static final int AXES_START_TYPES = 37;
-
-  /** ancestor axes opcode.         */
-  public static final int FROM_ANCESTORS = 37;
-
-  /** ancestor-or-self axes opcode.         */
-  public static final int FROM_ANCESTORS_OR_SELF = 38;
-
-  /** attribute axes opcode.         */
-  public static final int FROM_ATTRIBUTES = 39;
-
-  /** children axes opcode.         */
-  public static final int FROM_CHILDREN = 40;
-
-  /** descendants axes opcode.         */
-  public static final int FROM_DESCENDANTS = 41;
-
-  /** descendants-of-self axes opcode.         */
-  public static final int FROM_DESCENDANTS_OR_SELF = 42;
-
-  /** following axes opcode.         */
-  public static final int FROM_FOLLOWING = 43;
-
-  /** following-siblings axes opcode.         */
-  public static final int FROM_FOLLOWING_SIBLINGS = 44;
-
-  /** parent axes opcode.         */
-  public static final int FROM_PARENT = 45;
-
-  /** preceding axes opcode.         */
-  public static final int FROM_PRECEDING = 46;
-
-  /** preceding-sibling axes opcode.         */
-  public static final int FROM_PRECEDING_SIBLINGS = 47;
-
-  /** self axes opcode.         */
-  public static final int FROM_SELF = 48;
-
-  /** namespace axes opcode.         */
-  public static final int FROM_NAMESPACE = 49;
-
-  /** '/' axes opcode.         */
-  public static final int FROM_ROOT = 50;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * For match patterns.
-   */
-  public static final int MATCH_ATTRIBUTE = 51;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * For match patterns.
-   */
-  public static final int MATCH_ANY_ANCESTOR = 52;
-
-  /**
-   * <meta name="usage" content="advanced"/>
-   * For match patterns.
-   */
-  public static final int MATCH_IMMEDIATE_ANCESTOR = 53;
-
-  /** The end of the axes types.    */
-  public static final int AXES_END_TYPES = 53;
-
-  /** The next free ID.  Please keep this up to date.  */
-  private static final int NEXT_FREE_ID = 99;
-}
diff --git a/src/org/apache/xpath/compiler/OpMap.java b/src/org/apache/xpath/compiler/OpMap.java
deleted file mode 100644
index c1702e1..0000000
--- a/src/org/apache/xpath/compiler/OpMap.java
+++ /dev/null
@@ -1,492 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 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.xpath.compiler;
-
-import java.util.Vector;
-
-import org.apache.xml.utils.QName;
-import org.apache.xpath.patterns.NodeTest;
-import org.apache.xpath.res.XPATHErrorResources;
-import org.apache.xalan.res.XSLMessages;
-
-/**
- * This class represents the data structure basics of the XPath
- * object.
- */
-public class OpMap
-{
-
-  /**
-   * The current pattern string, for diagnostics purposes
-   */
-  protected String m_currentPattern;
-
-  /**
-   * Return the expression as a string for diagnostics.
-   *
-   * @return The expression string.
-   */
-  public String toString()
-  {
-    return m_currentPattern;
-  }
-
-  /**
-   * Return the expression as a string for diagnostics.
-   *
-   * @return The expression string.
-   */
-  public String getPatternString()
-  {
-    return m_currentPattern;
-  }
-
-  /**
-   * The max size that the token queue can grow to.
-   */
-  static final int MAXTOKENQUEUESIZE = 500;
-
-  /**
-   *  TokenStack is the queue of used tokens. The current token is the token at the
-   * end of the m_tokenQueue. The idea is that the queue can be marked and a sequence
-   * of tokens can be reused.
-   */
-  public Object[] m_tokenQueue = new Object[MAXTOKENQUEUESIZE];
-
-  /**
-   * Get the XPath as a list of tokens.
-   *
-   * @return an array of string tokens.
-   */
-  public Object[] getTokenQueue()
-  {
-    return m_tokenQueue;
-  }
-
-  /**
-   * Get the XPath as a list of tokens.
-   *
-   * @param pos index into token queue.
-   *
-   * @return The token, normally a string.
-   */
-  public Object getToken(int pos)
-  {
-    return m_tokenQueue[pos];
-  }
-
-  /**
-   * The current size of the token queue.
-   */
-  public int m_tokenQueueSize = 0;
-
-  /**
-    * Get size of the token queue.
-   *
-   * @return The size of the token queue.
-   */
-  public int getTokenQueueSize()
-  {
-    return m_tokenQueueSize;
-  }
-
-  /**
-   * An operations map is used instead of a proper parse tree.  It contains
-   * operations codes and indexes into the m_tokenQueue.
-   * I use an array instead of a full parse tree in order to cut down
-   * on the number of objects created.
-   */
-  public int m_opMap[] = null;
-
-  /**
-    * Get the opcode list that describes the XPath operations.  It contains
-   * operations codes and indexes into the m_tokenQueue.
-   * I use an array instead of a full parse tree in order to cut down
-   * on the number of objects created.
-   *
-   * @return An array of integers that is the opcode list that describes the XPath operations.
-   */
-  public int[] getOpMap()
-  {
-    return m_opMap;
-  }
-
-  // Position indexes
-
-  /**
-   * The length is always the opcode position + 1.
-   * Length is always expressed as the opcode+length bytes,
-   * so it is always 2 or greater.
-   */
-  public static final int MAPINDEX_LENGTH = 1;
-
-  /**
-   * Replace the large arrays
-   * with a small array.
-   */
-  void shrink()
-  {
-
-    int map[] = m_opMap;
-    int n = m_opMap[MAPINDEX_LENGTH];
-    ;
-
-    m_opMap = new int[n + 4];
-
-    int i;
-
-    for (i = 0; i < n; i++)
-    {
-      m_opMap[i] = map[i];
-    }
-
-    m_opMap[i] = 0;
-    m_opMap[i + 1] = 0;
-    m_opMap[i + 2] = 0;
-
-    Object[] tokens = m_tokenQueue;
-
-    n = m_tokenQueueSize;
-    m_tokenQueue = new Object[n + 4];
-
-    for (i = 0; i < n; i++)
-    {
-      m_tokenQueue[i] = tokens[i];
-    }
-
-    m_tokenQueue[i] = null;
-    m_tokenQueue[i + 1] = null;
-    m_tokenQueue[i + 2] = null;
-  }
-
-  /**
-  * Given an operation position, return the current op.
-   *
-   * @param opPos index into op map.
-   * @return the op that corresponds to the opPos argument.
-   */
-  public int getOp(int opPos)
-  {
-    return m_opMap[opPos];
-  }
-
-  /**
-   * Given an operation position, return the end position, i.e. the
-   * beginning of the next operation.
-   *
-   * @param opPos An op position of an operation for which there is a size 
-   *              entry following.
-   * @return position of next operation in m_opMap.
-   */
-  public int getNextOpPos(int opPos)
-  {
-    return opPos + m_opMap[opPos + 1];
-  }
-
-  /**
-   * Given a location step position, return the end position, i.e. the
-   * beginning of the next step.
-   *
-   * @param opPos the position of a location step.
-   * @return the position of the next location step.
-   */
-  public int getNextStepPos(int opPos)
-  {
-
-    int stepType = getOp(opPos);
-
-    if ((stepType >= OpCodes.AXES_START_TYPES)
-            && (stepType <= OpCodes.AXES_END_TYPES))
-    {
-      return getNextOpPos(opPos);
-    }
-    else if ((stepType >= OpCodes.FIRST_NODESET_OP)
-             && (stepType <= OpCodes.LAST_NODESET_OP))
-    {
-      int newOpPos = getNextOpPos(opPos);
-
-      while (OpCodes.OP_PREDICATE == getOp(newOpPos))
-      {
-        newOpPos = getNextOpPos(newOpPos);
-      }
-
-      stepType = getOp(newOpPos);
-
-      if (!((stepType >= OpCodes.AXES_START_TYPES)
-            && (stepType <= OpCodes.AXES_END_TYPES)))
-      {
-        return OpCodes.ENDOP;
-      }
-
-      return newOpPos;
-    }
-    else
-    {
-      throw new RuntimeException(
-        XSLMessages.createXPATHMessage(XPATHErrorResources.ER_UNKNOWN_STEP, new Object[]{new Integer(stepType).toString()})); 
-      //"Programmer's assertion in getNextStepPos: unknown stepType: " + stepType);
-    }
-  }
-
-  /**
-   * Given an operation position, return the end position, i.e. the
-   * beginning of the next operation.
-   *
-   * @param opMap The operations map.
-   * @param opPos index to operation, for which there is a size entry following.
-   * @return position of next operation in m_opMap.
-   */
-  public static int getNextOpPos(int[] opMap, int opPos)
-  {
-    return opPos + opMap[opPos + 1];
-  }
-
-  /**
-   * Given an FROM_stepType position, return the position of the
-   * first predicate, if there is one, or else this will point
-   * to the end of the FROM_stepType.
-   * Example:
-   *  int posOfPredicate = xpath.getNextOpPos(stepPos);
-   *  boolean hasPredicates =
-   *            OpCodes.OP_PREDICATE == xpath.getOp(posOfPredicate);
-   *
-   * @param opPos position of FROM_stepType op. 
-   * @return position of predicate in FROM_stepType structure.
-   */
-  public int getFirstPredicateOpPos(int opPos)
-     throws javax.xml.transform.TransformerException
-  {
-
-    int stepType = m_opMap[opPos];
-
-    if ((stepType >= OpCodes.AXES_START_TYPES)
-            && (stepType <= OpCodes.AXES_END_TYPES))
-    {
-      return opPos + m_opMap[opPos + 2];
-    }
-    else if ((stepType >= OpCodes.FIRST_NODESET_OP)
-             && (stepType <= OpCodes.LAST_NODESET_OP))
-    {
-      return opPos + m_opMap[opPos + 1];
-    }
-    else if(-2 == stepType)
-    {
-      return -2;
-    }
-    else
-    {
-      error(org.apache.xpath.res.XPATHErrorResources.ER_UNKNOWN_OPCODE,
-            new Object[]{ String.valueOf(stepType) });  //"ERROR! Unknown op code: "+m_opMap[opPos]);
-      return -1;
-    }
-  }
-  
-  /**
-   * Tell the user of an error, and probably throw an
-   * exception.
-   *
-   * @param msg An error number that corresponds to one of the numbers found 
-   *            in {@link org.apache.xpath.res.XPATHErrorResources}, which is 
-   *            a key for a format string.
-   * @param args An array of arguments represented in the format string, which 
-   *             may be null.
-   *
-   * @throws TransformerException if the current ErrorListoner determines to 
-   *                              throw an exception.
-   */
-  public void error(int msg, Object[] args) throws javax.xml.transform.TransformerException
-  {
-
-    java.lang.String fmsg = org.apache.xalan.res.XSLMessages.createXPATHMessage(msg, args);
-    
-
-    throw new javax.xml.transform.TransformerException(fmsg);
-  }
-
-
-  /**
-   * Go to the first child of a given operation.
-   *
-   * @param opPos position of operation.
-   *
-   * @return The position of the first child of the operation.
-   */
-  public static int getFirstChildPos(int opPos)
-  {
-    return opPos + 2;
-  }
-
-  /**
-   * Get the length of an operation.
-   *
-   * @param opPos The position of the operation in the op map.
-   *
-   * @return The size of the operation.
-   */
-  public int getArgLength(int opPos)
-  {
-    return m_opMap[opPos + MAPINDEX_LENGTH];
-  }
-
-  /**
-   * Given a location step, get the length of that step.
-   *
-   * @param opPos Position of location step in op map.
-   *
-   * @return The length of the step.
-   */
-  public int getArgLengthOfStep(int opPos)
-  {
-    return m_opMap[opPos + MAPINDEX_LENGTH + 1] - 3;
-  }
-
-  /**
-   * Get the first child position of a given location step.
-   *
-   * @param opPos Position of location step in the location map.
-   *
-   * @return The first child position of the step.
-   */
-  public static int getFirstChildPosOfStep(int opPos)
-  {
-    return opPos + 3;
-  }
-
-  /**
-   * Get the test type of the step, i.e. NODETYPE_XXX value.
-   * 
-   * @param opPosOfStep The position of the FROM_XXX step.
-   *
-   * @return NODETYPE_XXX value.
-   */
-  public int getStepTestType(int opPosOfStep)
-  {
-    return m_opMap[opPosOfStep + 3];  // skip past op, len, len without predicates
-  }
-
-  /**
-   * Get the namespace of the step.
-   * 
-   * @param opPosOfStep The position of the FROM_XXX step.
-   *
-   * @return The step's namespace, NodeTest.WILD, or null for null namespace.
-   */
-  public String getStepNS(int opPosOfStep)
-  {
-
-    int argLenOfStep = getArgLengthOfStep(opPosOfStep);
-
-    // System.out.println("getStepNS.argLenOfStep: "+argLenOfStep);
-    if (argLenOfStep == 3)
-    {
-      int index = m_opMap[opPosOfStep + 4];
-
-      if (index >= 0)
-        return (String) m_tokenQueue[index];
-      else if (OpCodes.ELEMWILDCARD == index)
-        return NodeTest.WILD;
-      else
-        return null;
-    }
-    else
-      return null;
-  }
-
-  /**
-   * Get the local name of the step.
-   * @param opPosOfStep The position of the FROM_XXX step.
-   *
-   * @return OpCodes.EMPTY, OpCodes.ELEMWILDCARD, or the local name.
-   */
-  public String getStepLocalName(int opPosOfStep)
-  {
-
-    int argLenOfStep = getArgLengthOfStep(opPosOfStep);
-
-    // System.out.println("getStepLocalName.argLenOfStep: "+argLenOfStep);
-    int index;
-
-    switch (argLenOfStep)
-    {
-    case 0 :
-      index = OpCodes.EMPTY;
-      break;
-    case 1 :
-      index = OpCodes.ELEMWILDCARD;
-      break;
-    case 2 :
-      index = m_opMap[opPosOfStep + 4];
-      break;
-    case 3 :
-      index = m_opMap[opPosOfStep + 5];
-      break;
-    default :
-      index = OpCodes.EMPTY;
-      break;  // Should assert error
-    }
-
-    // int index = (argLenOfStep == 3) ? m_opMap[opPosOfStep+5] 
-    //                                  : ((argLenOfStep == 1) ? -3 : -2);
-    if (index >= 0)
-      return (String) m_tokenQueue[index].toString();
-    else if (OpCodes.ELEMWILDCARD == index)
-      return NodeTest.WILD;
-    else
-      return null;
-  }
-
-}
diff --git a/src/org/apache/xpath/compiler/PsuedoNames.java b/src/org/apache/xpath/compiler/PsuedoNames.java
deleted file mode 100644
index f80d1d9..0000000
--- a/src/org/apache/xpath/compiler/PsuedoNames.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 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.xpath.compiler;
-
-/**
- * This is used to represent names of nodes that may not be named, like a 
- * comment node.
- */
-public class PsuedoNames
-{
-
-  /**
-   * Psuedo name for a wild card pattern ('*').
-   */
-  public static final String PSEUDONAME_ANY = "*";
-
-  /**
-   * Psuedo name for the root node.
-   */
-  public static final String PSEUDONAME_ROOT = "/";
-
-  /**
-   * Psuedo name for a text node.
-   */
-  public static final String PSEUDONAME_TEXT = "#text";
-
-  /**
-   * Psuedo name for a comment node.
-   */
-  public static final String PSEUDONAME_COMMENT = "#comment";
-
-  /**
-   * Psuedo name for a processing instruction node.
-   */
-  public static final String PSEUDONAME_PI = "#pi";
-
-  /**
-   * Psuedo name for an unknown type value.
-   */
-  public static final String PSEUDONAME_OTHER = "*";
-}
diff --git a/src/org/apache/xpath/compiler/XPathDumper.java b/src/org/apache/xpath/compiler/XPathDumper.java
deleted file mode 100644
index d660a75..0000000
--- a/src/org/apache/xpath/compiler/XPathDumper.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 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.xpath.compiler;
-
-import org.apache.xalan.res.XSLMessages;
-import org.apache.xpath.res.XPATHErrorResources;
-import org.apache.xpath.XPath;
-import org.apache.xpath.compiler.XPathParser;
-
-/**
- * Class for XPath diagnostic functions.
- */
-public class XPathDumper
-{
-
-  // deleted for the time being.
-}
diff --git a/src/org/apache/xpath/compiler/XPathParser.java b/src/org/apache/xpath/compiler/XPathParser.java
deleted file mode 100644
index d4d9d32..0000000
--- a/src/org/apache/xpath/compiler/XPathParser.java
+++ /dev/null
@@ -1,2404 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 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.xpath.compiler;
-
-import java.util.Vector;
-import java.util.Hashtable;
-
-import org.apache.xml.utils.PrefixResolver;
-import org.apache.xpath.XPathProcessorException;
-import org.apache.xpath.res.XPATHErrorResources;
-import org.apache.xpath.compiler.Compiler;
-import org.apache.xpath.objects.XString;
-import org.apache.xpath.objects.XNumber;
-import org.apache.xalan.res.XSLMessages;
-
-import javax.xml.transform.TransformerException;
-import org.xml.sax.Locator;
-import org.xml.sax.helpers.LocatorImpl;
-
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.ErrorListener;
-
-/**
- * <meta name="usage" content="general"/>
- * Tokenizes and parses XPath expressions. This should really be named
- * XPathParserImpl, and may be renamed in the future.
- */
-public class XPathParser
-{
-	// %REVIEW% Is there a better way of doing this?
-	// Upside is minimum object churn. Downside is that we don't have a useful
-	// backtrace in the exception itself -- but we don't expect to need one.
-	static public final String CONTINUE_AFTER_FATAL_ERROR="CONTINUE_AFTER_FATAL_ERROR";
-
-  /**
-   * The XPath to be processed.
-   */
-  private OpMap m_ops;
-
-  /**
-   * The next token in the pattern.
-   */
-  transient String m_token;
-
-  /**
-   * The first char in m_token, the theory being that this
-   * is an optimization because we won't have to do charAt(0) as
-   * often.
-   */
-  transient char m_tokenChar = 0;
-
-  /**
-   * The position in the token queue is tracked by m_queueMark.
-   */
-  int m_queueMark = 0;
-
-  /**
-   * Results from checking FilterExpr syntax
-   */
-  protected final static int FILTER_MATCH_FAILED     = 0;
-  protected final static int FILTER_MATCH_PRIMARY    = 1;
-  protected final static int FILTER_MATCH_PREDICATES = 2;
-
-  /**
-   * The parser constructor.
-   */
-  public XPathParser(ErrorListener errorListener, javax.xml.transform.SourceLocator sourceLocator)
-  {
-    m_errorListener = errorListener;
-    m_sourceLocator = sourceLocator;
-  }
-
-  /**
-   * The prefix resolver to map prefixes to namespaces in the OpMap.
-   */
-  PrefixResolver m_namespaceContext;
-
-  /**
-   * Given an string, init an XPath object for selections,
-   * in order that a parse doesn't
-   * have to be done each time the expression is evaluated.
-   * 
-   * @param compiler The compiler object.
-   * @param expression A string conforming to the XPath grammar.
-   * @param namespaceContext An object that is able to resolve prefixes in
-   * the XPath to namespaces.
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  public void initXPath(
-          Compiler compiler, String expression, PrefixResolver namespaceContext)
-            throws javax.xml.transform.TransformerException
-  {
-
-    m_ops = compiler;
-    m_namespaceContext = namespaceContext;
-
-    Lexer lexer = new Lexer(compiler, namespaceContext, this);
-
-    lexer.tokenize(expression);
-
-    m_ops.m_opMap[0] = OpCodes.OP_XPATH;
-    m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] = 2;
-    
-    
-	// Patch for Christine's gripe. She wants her errorHandler to return from
-	// a fatal error and continue trying to parse, rather than throwing an exception.
-	// Without the patch, that put us into an endless loop.
-	//
-	// %REVIEW% Is there a better way of doing this?
-	// %REVIEW% Are there any other cases which need the safety net?
-	// 	(and if so do we care right now, or should we rewrite the XPath
-	//	grammar engine and can fix it at that time?)
-	try {
-
-      nextToken();
-      Expr();
-
-      if (null != m_token)
-      {
-        String extraTokens = "";
-
-        while (null != m_token)
-        {
-          extraTokens += "'" + m_token + "'";
-
-          nextToken();
-
-          if (null != m_token)
-            extraTokens += ", ";
-        }
-
-        error(XPATHErrorResources.ER_EXTRA_ILLEGAL_TOKENS,
-              new Object[]{ extraTokens });  //"Extra illegal tokens: "+extraTokens);
-      }
-
-    } 
-    catch (org.apache.xpath.XPathProcessorException e)
-    {
-	  if(CONTINUE_AFTER_FATAL_ERROR.equals(e.getMessage()))
-	  {
-		// What I _want_ to do is null out this XPath.
-		// I doubt this has the desired effect, but I'm not sure what else to do.
-		// %REVIEW%!!!
-		initXPath(compiler, "/..",  namespaceContext);
-	  }
-	  else
-		throw e;
-    }
-
-    compiler.shrink();
-  }
-
-  /**
-   * Given an string, init an XPath object for pattern matches,
-   * in order that a parse doesn't
-   * have to be done each time the expression is evaluated.
-   * @param compiler The XPath object to be initialized.
-   * @param expression A String representing the XPath.
-   * @param namespaceContext An object that is able to resolve prefixes in
-   * the XPath to namespaces.
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  public void initMatchPattern(
-          Compiler compiler, String expression, PrefixResolver namespaceContext)
-            throws javax.xml.transform.TransformerException
-  {
-
-    m_ops = compiler;
-    m_namespaceContext = namespaceContext;
-
-    Lexer lexer = new Lexer(compiler, namespaceContext, this);
-
-    lexer.tokenize(expression);
-
-    m_ops.m_opMap[0] = OpCodes.OP_MATCHPATTERN;
-    m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] = 2;
-
-    nextToken();
-    Pattern();
-
-    if (null != m_token)
-    {
-      String extraTokens = "";
-
-      while (null != m_token)
-      {
-        extraTokens += "'" + m_token + "'";
-
-        nextToken();
-
-        if (null != m_token)
-          extraTokens += ", ";
-      }
-
-      error(XPATHErrorResources.ER_EXTRA_ILLEGAL_TOKENS,
-            new Object[]{ extraTokens });  //"Extra illegal tokens: "+extraTokens);
-    }
-
-    // Terminate for safety.
-    m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = OpCodes.ENDOP;
-    m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-
-    m_ops.shrink();
-  }
-
-  /** The error listener where syntax errors are to be sent.
-   */
-  private ErrorListener m_errorListener;
-  
-  /** The source location of the XPath. */
-  javax.xml.transform.SourceLocator m_sourceLocator;
-
-  /**
-   * Allow an application to register an error event handler, where syntax 
-   * errors will be sent.  If the error listener is not set, syntax errors 
-   * will be sent to System.err.
-   * 
-   * @param handler Reference to error listener where syntax errors will be 
-   *                sent.
-   */
-  public void setErrorHandler(ErrorListener handler)
-  {
-    m_errorListener = handler;
-  }
-
-  /**
-   * Return the current error listener.
-   *
-   * @return The error listener, which should not normally be null, but may be.
-   */
-  public ErrorListener getErrorListener()
-  {
-    return m_errorListener;
-  }
-
-  /**
-   * Check whether m_token matches the target string. 
-   *
-   * @param s A string reference or null.
-   *
-   * @return If m_token is null, returns false (or true if s is also null), or 
-   * return true if the current token matches the string, else false.
-   */
-  final boolean tokenIs(String s)
-  {
-    return (m_token != null) ? (m_token.equals(s)) : (s == null);
-  }
-
-  /**
-   * Check whether m_tokenChar==c. 
-   *
-   * @param c A character to be tested.
-   *
-   * @return If m_token is null, returns false, or return true if c matches 
-   *         the current token.
-   */
-  final boolean tokenIs(char c)
-  {
-    return (m_token != null) ? (m_tokenChar == c) : false;
-  }
-
-  /**
-   * Look ahead of the current token in order to
-   * make a branching decision.
-   *
-   * @param c the character to be tested for.
-   * @param n number of tokens to look ahead.  Must be
-   * greater than 1.
-   *
-   * @return true if the next token matches the character argument.
-   */
-  final boolean lookahead(char c, int n)
-  {
-
-    int pos = (m_queueMark + n);
-    boolean b;
-
-    if ((pos <= m_ops.m_tokenQueueSize) && (pos > 0)
-            && (m_ops.m_tokenQueueSize != 0))
-    {
-      String tok = ((String) m_ops.m_tokenQueue[pos - 1]);
-
-      b = (tok.length() == 1) ? (tok.charAt(0) == c) : false;
-    }
-    else
-    {
-      b = false;
-    }
-
-    return b;
-  }
-
-  /**
-   * Look behind the first character of the current token in order to
-   * make a branching decision.
-   * 
-   * @param c the character to compare it to.
-   * @param n number of tokens to look behind.  Must be
-   * greater than 1.  Note that the look behind terminates
-   * at either the beginning of the string or on a '|'
-   * character.  Because of this, this method should only
-   * be used for pattern matching.
-   *
-   * @return true if the token behind the current token matches the character 
-   *         argument.
-   */
-  private final boolean lookbehind(char c, int n)
-  {
-
-    boolean isToken;
-    int lookBehindPos = m_queueMark - (n + 1);
-
-    if (lookBehindPos >= 0)
-    {
-      String lookbehind = (String) m_ops.m_tokenQueue[lookBehindPos];
-
-      if (lookbehind.length() == 1)
-      {
-        char c0 = (lookbehind == null) ? '|' : lookbehind.charAt(0);
-
-        isToken = (c0 == '|') ? false : (c0 == c);
-      }
-      else
-      {
-        isToken = false;
-      }
-    }
-    else
-    {
-      isToken = false;
-    }
-
-    return isToken;
-  }
-
-  /**
-   * look behind the current token in order to
-   * see if there is a useable token.
-   * 
-   * @param n number of tokens to look behind.  Must be
-   * greater than 1.  Note that the look behind terminates
-   * at either the beginning of the string or on a '|'
-   * character.  Because of this, this method should only
-   * be used for pattern matching.
-   * 
-   * @return true if look behind has a token, false otherwise.
-   */
-  private final boolean lookbehindHasToken(int n)
-  {
-
-    boolean hasToken;
-
-    if ((m_queueMark - n) > 0)
-    {
-      String lookbehind = (String) m_ops.m_tokenQueue[m_queueMark - (n - 1)];
-      char c0 = (lookbehind == null) ? '|' : lookbehind.charAt(0);
-
-      hasToken = (c0 == '|') ? false : true;
-    }
-    else
-    {
-      hasToken = false;
-    }
-
-    return hasToken;
-  }
-
-  /**
-   * Look ahead of the current token in order to
-   * make a branching decision.
-   * 
-   * @param s the string to compare it to.
-   * @param n number of tokens to lookahead.  Must be
-   * greater than 1.
-   *
-   * @return true if the token behind the current token matches the string 
-   *         argument.
-   */
-  private final boolean lookahead(String s, int n)
-  {
-
-    boolean isToken;
-
-    if ((m_queueMark + n) <= m_ops.m_tokenQueueSize)
-    {
-      String lookahead = (String) m_ops.m_tokenQueue[m_queueMark + (n - 1)];
-
-      isToken = (lookahead != null) ? lookahead.equals(s) : (s == null);
-    }
-    else
-    {
-      isToken = (null == s);
-    }
-
-    return isToken;
-  }
-
-  /**
-   * Retrieve the next token from the command and
-   * store it in m_token string.
-   */
-  private final void nextToken()
-  {
-
-    if (m_queueMark < m_ops.m_tokenQueueSize)
-    {
-      m_token = (String) m_ops.m_tokenQueue[m_queueMark++];
-      m_tokenChar = m_token.charAt(0);
-    }
-    else
-    {
-      m_token = null;
-      m_tokenChar = 0;
-    }
-  }
-
-  /**
-   * Retrieve a token relative to the current token.
-   * 
-   * @param i Position relative to current token.
-   *
-   * @return The string at the given index, or null if the index is out 
-   *         of range.
-   */
-  private final String getTokenRelative(int i)
-  {
-
-    String tok;
-    int relative = m_queueMark + i;
-
-    if ((relative > 0) && (relative < m_ops.m_tokenQueueSize))
-    {
-      tok = (String) m_ops.m_tokenQueue[relative];
-    }
-    else
-    {
-      tok = null;
-    }
-
-    return tok;
-  }
-
-  /**
-   * Retrieve the previous token from the command and
-   * store it in m_token string.
-   */
-  private final void prevToken()
-  {
-
-    if (m_queueMark > 0)
-    {
-      m_queueMark--;
-
-      m_token = (String) m_ops.m_tokenQueue[m_queueMark];
-      m_tokenChar = m_token.charAt(0);
-    }
-    else
-    {
-      m_token = null;
-      m_tokenChar = 0;
-    }
-  }
-
-  /**
-   * Consume an expected token, throwing an exception if it
-   * isn't there.
-   *
-   * @param expected The string to be expected.
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  private final void consumeExpected(String expected)
-          throws javax.xml.transform.TransformerException
-  {
-
-    if (tokenIs(expected))
-    {
-      nextToken();
-    }
-    else
-    {
-      error(XPATHErrorResources.ER_EXPECTED_BUT_FOUND, new Object[]{ expected,
-                                                                     m_token });  //"Expected "+expected+", but found: "+m_token);
-
-	  // Patch for Christina's gripe. She wants her errorHandler to return from
-	  // this error and continue trying to parse, rather than throwing an exception.
-	  // Without the patch, that put us into an endless loop.
-		throw new XPathProcessorException(CONTINUE_AFTER_FATAL_ERROR);
-	}
-  }
-
-  /**
-   * Consume an expected token, throwing an exception if it
-   * isn't there.
-   *
-   * @param expected the character to be expected.
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  private final void consumeExpected(char expected)
-          throws javax.xml.transform.TransformerException
-  {
-
-    if (tokenIs(expected))
-    {
-      nextToken();
-    }
-    else
-    {
-      error(XPATHErrorResources.ER_EXPECTED_BUT_FOUND,
-            new Object[]{ String.valueOf(expected),
-                          m_token });  //"Expected "+expected+", but found: "+m_token);
-
-	  // Patch for Christina's gripe. She wants her errorHandler to return from
-	  // this error and continue trying to parse, rather than throwing an exception.
-	  // Without the patch, that put us into an endless loop.
-		throw new XPathProcessorException(CONTINUE_AFTER_FATAL_ERROR);
-    }
-  }
-
-  /**
-   * Warn the user of a problem.
-   *
-   * @param msg An error number that corresponds to one of the numbers found 
-   *            in {@link org.apache.xpath.res.XPATHErrorResources}, which is 
-   *            a key for a format string.
-   * @param args An array of arguments represented in the format string, which 
-   *             may be null.
-   *
-   * @throws TransformerException if the current ErrorListoner determines to 
-   *                              throw an exception.
-   */
-  void warn(int msg, Object[] args) throws TransformerException
-  {
-
-    String fmsg = XSLMessages.createXPATHWarning(msg, args);
-    ErrorListener ehandler = this.getErrorListener();
-
-    if (null != ehandler)
-    {
-      // TO DO: Need to get stylesheet Locator from here.
-      ehandler.warning(new TransformerException(fmsg, m_sourceLocator));
-    }
-    else
-    {
-      // Should never happen.
-      System.err.println(fmsg);
-    }
-  }
-
-  /**
-   * Notify the user of an assertion error, and probably throw an
-   * exception.
-   *
-   * @param b  If false, a runtime exception will be thrown.
-   * @param msg The assertion message, which should be informative.
-   * 
-   * @throws RuntimeException if the b argument is false.
-   */
-  private void assertion(boolean b, String msg)
-  {
-
-    if (!b)
-    {
-      String fMsg = XSLMessages.createXPATHMessage(
-        XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION,
-        new Object[]{ msg });
-
-      throw new RuntimeException(fMsg);
-    }
-  }
-
-  /**
-   * Notify the user of an error, and probably throw an
-   * exception.
-   *
-   * @param msg An error number that corresponds to one of the numbers found 
-   *            in {@link org.apache.xpath.res.XPATHErrorResources}, which is 
-   *            a key for a format string.
-   * @param args An array of arguments represented in the format string, which 
-   *             may be null.
-   *
-   * @throws TransformerException if the current ErrorListoner determines to 
-   *                              throw an exception.
-   */
-  void error(int msg, Object[] args) throws TransformerException
-  {
-
-    String fmsg = XSLMessages.createXPATHMessage(msg, args);
-    ErrorListener ehandler = this.getErrorListener();
-
-    TransformerException te = new TransformerException(fmsg, m_sourceLocator);
-    if (null != ehandler)
-    {
-      // TO DO: Need to get stylesheet Locator from here.
-      ehandler.fatalError(te);
-    }
-    else
-    {
-      // System.err.println(fmsg);
-      throw te;
-    }
-  }
-
-  /**
-   * Dump the remaining token queue.
-   * Thanks to Craig for this.
-   *
-   * @return A dump of the remaining token queue, which may be appended to 
-   *         an error message.
-   */
-  protected String dumpRemainingTokenQueue()
-  {
-
-    int q = m_queueMark;
-    String returnMsg;
-
-    if (q < m_ops.m_tokenQueueSize)
-    {
-      String msg = "\n Remaining tokens: (";
-
-      while (q < m_ops.m_tokenQueueSize)
-      {
-        String t = (String) m_ops.m_tokenQueue[q++];
-
-        msg += (" '" + t + "'");
-      }
-
-      returnMsg = msg + ")";
-    }
-    else
-    {
-      returnMsg = "";
-    }
-
-    return returnMsg;
-  }
-
-  /**
-   * Given a string, return the corresponding function token.
-   *
-   * @param key A local name of a function.
-   *
-   * @return   The function ID, which may correspond to one of the FUNC_XXX 
-   *    values found in {@link org.apache.xpath.compiler.FunctionTable}, but may 
-   *    be a value installed by an external module.
-   */
-  final int getFunctionToken(String key)
-  {
-
-    int tok;
-
-    try
-    {
-      tok = ((Integer) (Keywords.m_functions.get(key))).intValue();
-    }
-    catch (NullPointerException npe)
-    {
-      tok = -1;
-    }
-    catch (ClassCastException cce)
-    {
-      tok = -1;
-    }
-
-    return tok;
-  }
-
-  /**
-   * Insert room for operation.  This will NOT set
-   * the length value of the operation, but will update
-   * the length value for the total expression.
-   *
-   * @param pos The position where the op is to be inserted.
-   * @param length The length of the operation space in the op map.
-   * @param op The op code to the inserted.
-   */
-  void insertOp(int pos, int length, int op)
-  {
-
-    int totalLen = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    for (int i = totalLen - 1; i >= pos; i--)
-    {
-      m_ops.m_opMap[i + length] = m_ops.m_opMap[i];
-    }
-
-    m_ops.m_opMap[pos] = op;
-    m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] = totalLen + length;
-  }
-
-  /**
-   * Insert room for operation.  This WILL set
-   * the length value of the operation, and will update
-   * the length value for the total expression.
-   *
-   * @param length The length of the operation.
-   * @param op The op code to the inserted.
-   */
-  void appendOp(int length, int op)
-  {
-
-    int totalLen = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    m_ops.m_opMap[totalLen] = op;
-    m_ops.m_opMap[totalLen + OpMap.MAPINDEX_LENGTH] = length;
-    m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] = totalLen + length;
-  }
-
-  // ============= EXPRESSIONS FUNCTIONS =================
-
-  /**
-   *
-   *
-   * Expr  ::=  OrExpr
-   *
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void Expr() throws javax.xml.transform.TransformerException
-  {
-    OrExpr();
-  }
-
-  /**
-   *
-   *
-   * OrExpr  ::=  AndExpr
-   * | OrExpr 'or' AndExpr
-   *
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void OrExpr() throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    AndExpr();
-
-    if ((null != m_token) && tokenIs("or"))
-    {
-      nextToken();
-      insertOp(opPos, 2, OpCodes.OP_OR);
-      OrExpr();
-
-      m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-        m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-    }
-  }
-
-  /**
-   *
-   *
-   * AndExpr  ::=  EqualityExpr
-   * | AndExpr 'and' EqualityExpr
-   *
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void AndExpr() throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    EqualityExpr(-1);
-
-    if ((null != m_token) && tokenIs("and"))
-    {
-      nextToken();
-      insertOp(opPos, 2, OpCodes.OP_AND);
-      AndExpr();
-
-      m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-        m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-    }
-  }
-
-  /**
-   *
-   * @returns an Object which is either a String, a Number, a Boolean, or a vector
-   * of nodes.
-   *
-   * EqualityExpr  ::=  RelationalExpr
-   * | EqualityExpr '=' RelationalExpr
-   *
-   *
-   * @param addPos Position where expression is to be added, or -1 for append.
-   *
-   * @return the position at the end of the equality expression.
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected int EqualityExpr(int addPos) throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    if (-1 == addPos)
-      addPos = opPos;
-
-    RelationalExpr(-1);
-
-    if (null != m_token)
-    {
-      if (tokenIs('!') && lookahead('=', 1))
-      {
-        nextToken();
-        nextToken();
-        insertOp(addPos, 2, OpCodes.OP_NOTEQUALS);
-
-        int opPlusLeftHandLen = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - addPos;
-
-        addPos = EqualityExpr(addPos);
-        m_ops.m_opMap[addPos + OpMap.MAPINDEX_LENGTH] =
-          m_ops.m_opMap[addPos + opPlusLeftHandLen + 1] + opPlusLeftHandLen;
-        addPos += 2;
-      }
-      else if (tokenIs('='))
-      {
-        nextToken();
-        insertOp(addPos, 2, OpCodes.OP_EQUALS);
-
-        int opPlusLeftHandLen = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - addPos;
-
-        addPos = EqualityExpr(addPos);
-        m_ops.m_opMap[addPos + OpMap.MAPINDEX_LENGTH] =
-          m_ops.m_opMap[addPos + opPlusLeftHandLen + 1] + opPlusLeftHandLen;
-        addPos += 2;
-      }
-    }
-
-    return addPos;
-  }
-
-  /**
-   * .
-   * @returns an Object which is either a String, a Number, a Boolean, or a vector
-   * of nodes.
-   *
-   * RelationalExpr  ::=  AdditiveExpr
-   * | RelationalExpr '<' AdditiveExpr
-   * | RelationalExpr '>' AdditiveExpr
-   * | RelationalExpr '<=' AdditiveExpr
-   * | RelationalExpr '>=' AdditiveExpr
-   *
-   *
-   * @param addPos Position where expression is to be added, or -1 for append.
-   *
-   * @return the position at the end of the relational expression.
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected int RelationalExpr(int addPos) throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    if (-1 == addPos)
-      addPos = opPos;
-
-    AdditiveExpr(-1);
-
-    if (null != m_token)
-    {
-      if (tokenIs('<'))
-      {
-        nextToken();
-
-        if (tokenIs('='))
-        {
-          nextToken();
-          insertOp(addPos, 2, OpCodes.OP_LTE);
-        }
-        else
-        {
-          insertOp(addPos, 2, OpCodes.OP_LT);
-        }
-
-        int opPlusLeftHandLen = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - addPos;
-
-        addPos = RelationalExpr(addPos);
-        m_ops.m_opMap[addPos + OpMap.MAPINDEX_LENGTH] =
-          m_ops.m_opMap[addPos + opPlusLeftHandLen + 1] + opPlusLeftHandLen;
-        addPos += 2;
-      }
-      else if (tokenIs('>'))
-      {
-        nextToken();
-
-        if (tokenIs('='))
-        {
-          nextToken();
-          insertOp(addPos, 2, OpCodes.OP_GTE);
-        }
-        else
-        {
-          insertOp(addPos, 2, OpCodes.OP_GT);
-        }
-
-        int opPlusLeftHandLen = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - addPos;
-
-        addPos = RelationalExpr(addPos);
-        m_ops.m_opMap[addPos + OpMap.MAPINDEX_LENGTH] =
-          m_ops.m_opMap[addPos + opPlusLeftHandLen + 1] + opPlusLeftHandLen;
-        addPos += 2;
-      }
-    }
-
-    return addPos;
-  }
-
-  /**
-   * This has to handle construction of the operations so that they are evaluated
-   * in pre-fix order.  So, for 9+7-6, instead of |+|9|-|7|6|, this needs to be
-   * evaluated as |-|+|9|7|6|.
-   *
-   * AdditiveExpr  ::=  MultiplicativeExpr
-   * | AdditiveExpr '+' MultiplicativeExpr
-   * | AdditiveExpr '-' MultiplicativeExpr
-   *
-   *
-   * @param addPos Position where expression is to be added, or -1 for append.
-   *
-   * @return the position at the end of the equality expression.
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected int AdditiveExpr(int addPos) throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    if (-1 == addPos)
-      addPos = opPos;
-
-    MultiplicativeExpr(-1);
-
-    if (null != m_token)
-    {
-      if (tokenIs('+'))
-      {
-        nextToken();
-        insertOp(addPos, 2, OpCodes.OP_PLUS);
-
-        int opPlusLeftHandLen = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - addPos;
-
-        addPos = AdditiveExpr(addPos);
-        m_ops.m_opMap[addPos + OpMap.MAPINDEX_LENGTH] =
-          m_ops.m_opMap[addPos + opPlusLeftHandLen + 1] + opPlusLeftHandLen;
-        addPos += 2;
-      }
-      else if (tokenIs('-'))
-      {
-        nextToken();
-        insertOp(addPos, 2, OpCodes.OP_MINUS);
-
-        int opPlusLeftHandLen = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - addPos;
-
-        addPos = AdditiveExpr(addPos);
-        m_ops.m_opMap[addPos + OpMap.MAPINDEX_LENGTH] =
-          m_ops.m_opMap[addPos + opPlusLeftHandLen + 1] + opPlusLeftHandLen;
-        addPos += 2;
-      }
-    }
-
-    return addPos;
-  }
-
-  /**
-   * This has to handle construction of the operations so that they are evaluated
-   * in pre-fix order.  So, for 9+7-6, instead of |+|9|-|7|6|, this needs to be
-   * evaluated as |-|+|9|7|6|.
-   *
-   * MultiplicativeExpr  ::=  UnaryExpr
-   * | MultiplicativeExpr MultiplyOperator UnaryExpr
-   * | MultiplicativeExpr 'div' UnaryExpr
-   * | MultiplicativeExpr 'mod' UnaryExpr
-   * | MultiplicativeExpr 'quo' UnaryExpr
-   *
-   * @param addPos Position where expression is to be added, or -1 for append.
-   *
-   * @return the position at the end of the equality expression.
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected int MultiplicativeExpr(int addPos) throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    if (-1 == addPos)
-      addPos = opPos;
-
-    UnaryExpr();
-
-    if (null != m_token)
-    {
-      if (tokenIs('*'))
-      {
-        nextToken();
-        insertOp(addPos, 2, OpCodes.OP_MULT);
-
-        int opPlusLeftHandLen = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - addPos;
-
-        addPos = MultiplicativeExpr(addPos);
-        m_ops.m_opMap[addPos + OpMap.MAPINDEX_LENGTH] =
-          m_ops.m_opMap[addPos + opPlusLeftHandLen + 1] + opPlusLeftHandLen;
-        addPos += 2;
-      }
-      else if (tokenIs("div"))
-      {
-        nextToken();
-        insertOp(addPos, 2, OpCodes.OP_DIV);
-
-        int opPlusLeftHandLen = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - addPos;
-
-        addPos = MultiplicativeExpr(addPos);
-        m_ops.m_opMap[addPos + OpMap.MAPINDEX_LENGTH] =
-          m_ops.m_opMap[addPos + opPlusLeftHandLen + 1] + opPlusLeftHandLen;
-        addPos += 2;
-      }
-      else if (tokenIs("mod"))
-      {
-        nextToken();
-        insertOp(addPos, 2, OpCodes.OP_MOD);
-
-        int opPlusLeftHandLen = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - addPos;
-
-        addPos = MultiplicativeExpr(addPos);
-        m_ops.m_opMap[addPos + OpMap.MAPINDEX_LENGTH] =
-          m_ops.m_opMap[addPos + opPlusLeftHandLen + 1] + opPlusLeftHandLen;
-        addPos += 2;
-      }
-      else if (tokenIs("quo"))
-      {
-        nextToken();
-        insertOp(addPos, 2, OpCodes.OP_QUO);
-
-        int opPlusLeftHandLen = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - addPos;
-
-        addPos = MultiplicativeExpr(addPos);
-        m_ops.m_opMap[addPos + OpMap.MAPINDEX_LENGTH] =
-          m_ops.m_opMap[addPos + opPlusLeftHandLen + 1] + opPlusLeftHandLen;
-        addPos += 2;
-      }
-    }
-
-    return addPos;
-  }
-
-  /**
-   *
-   * UnaryExpr  ::=  UnionExpr
-   * | '-' UnaryExpr
-   *
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void UnaryExpr() throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-    boolean isNeg = false;
-
-    if (m_tokenChar == '-')
-    {
-      nextToken();
-      appendOp(2, OpCodes.OP_NEG);
-
-      isNeg = true;
-    }
-
-    UnionExpr();
-
-    if (isNeg)
-      m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-        m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-  }
-
-  /**
-   *
-   * StringExpr  ::=  Expr
-   *
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void StringExpr() throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    appendOp(2, OpCodes.OP_STRING);
-    Expr();
-
-    m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-  }
-
-  /**
-   *
-   *
-   * StringExpr  ::=  Expr
-   *
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void BooleanExpr() throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    appendOp(2, OpCodes.OP_BOOL);
-    Expr();
-
-    int opLen = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-
-    if (opLen == 2)
-    {
-      error(XPATHErrorResources.ER_BOOLEAN_ARG_NO_LONGER_OPTIONAL, null);  //"boolean(...) argument is no longer optional with 19990709 XPath draft.");
-    }
-
-    m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] = opLen;
-  }
-
-  /**
-   *
-   *
-   * NumberExpr  ::=  Expr
-   *
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void NumberExpr() throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    appendOp(2, OpCodes.OP_NUMBER);
-    Expr();
-
-    m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-  }
-
-  /**
-   * The context of the right hand side expressions is the context of the
-   * left hand side expression. The results of the right hand side expressions
-   * are node sets. The result of the left hand side UnionExpr is the union
-   * of the results of the right hand side expressions.
-   *
-   *
-   * UnionExpr    ::=    PathExpr
-   * | UnionExpr '|' PathExpr
-   *
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void UnionExpr() throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-    boolean continueOrLoop = true;
-    boolean foundUnion = false;
-
-    do
-    {
-      PathExpr();
-
-      if (tokenIs('|'))
-      {
-        if (false == foundUnion)
-        {
-          foundUnion = true;
-
-          insertOp(opPos, 2, OpCodes.OP_UNION);
-        }
-
-        nextToken();
-      }
-      else
-      {
-        break;
-      }
-
-      // this.m_testForDocOrder = true;
-    }
-    while (continueOrLoop);
-
-    m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-  }
-
-  /**
-   * PathExpr  ::=  LocationPath
-   * | FilterExpr
-   * | FilterExpr '/' RelativeLocationPath
-   * | FilterExpr '//' RelativeLocationPath
-   *
-   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
-   * the error condition is severe enough to halt processing.
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void PathExpr() throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    int filterExprMatch = FilterExpr();
-
-    if (filterExprMatch != FILTER_MATCH_FAILED)
-    {
-      // If FilterExpr had Predicates, a OP_LOCATIONPATH opcode would already
-      // have been inserted.
-      boolean locationPathStarted = (filterExprMatch==FILTER_MATCH_PREDICATES);
-
-      if (tokenIs('/'))
-      {
-        nextToken();
-
-        if (!locationPathStarted)
-        {
-          // int locationPathOpPos = opPos;
-          insertOp(opPos, 2, OpCodes.OP_LOCATIONPATH);
-
-          locationPathStarted = true;
-        }
-
-        if (!RelativeLocationPath())
-        {
-          // "Relative location path expected following '/' or '//'"
-          error(XPATHErrorResources.ER_EXPECTED_REL_LOC_PATH, null);
-        }
-
-      }
-
-      // Terminate for safety.
-      if (locationPathStarted)
-      {
-        m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = OpCodes.ENDOP;
-        m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-        m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-          m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-      }
-    }
-    else
-    {
-      LocationPath();
-    }
-  }
-
-  /**
-   *
-   *
-   * FilterExpr  ::=  PrimaryExpr
-   * | FilterExpr Predicate
-   *
-   * @throws XSLProcessorException thrown if the active ProblemListener and XPathContext decide
-   * the error condition is severe enough to halt processing.
-   *
-   * @return  FILTER_MATCH_PREDICATES, if this method successfully matched a
-   *          FilterExpr with one or more Predicates;
-   *          FILTER_MATCH_PRIMARY, if this method successfully matched a
-   *          FilterExpr that was just a PrimaryExpr; or
-   *          FILTER_MATCH_FAILED, if this method did not match a FilterExpr
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected int FilterExpr() throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    int filterMatch;
-
-    if (PrimaryExpr())
-    {
-      if (tokenIs('['))
-      {
-
-        // int locationPathOpPos = opPos;
-        insertOp(opPos, 2, OpCodes.OP_LOCATIONPATH);
-
-        while (tokenIs('['))
-        {
-          Predicate();
-        }
-
-        filterMatch = FILTER_MATCH_PREDICATES;
-      }
-      else
-      {
-        filterMatch = FILTER_MATCH_PRIMARY;
-      }
-    }
-    else
-    {
-      filterMatch = FILTER_MATCH_FAILED;
-    }
-
-    return filterMatch;
-
-    /*
-     * if(tokenIs('['))
-     * {
-     *   Predicate();
-     *   m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-     * }
-     */
-  }
-
-  /**
-   *
-   * PrimaryExpr  ::=  VariableReference
-   * | '(' Expr ')'
-   * | Literal
-   * | Number
-   * | FunctionCall
-   *
-   * @return true if this method successfully matched a PrimaryExpr
-   *
-   * @throws javax.xml.transform.TransformerException
-   *
-   */
-  protected boolean PrimaryExpr() throws javax.xml.transform.TransformerException
-  {
-
-    boolean matchFound;
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    if ((m_tokenChar == '\'') || (m_tokenChar == '"'))
-    {
-      appendOp(2, OpCodes.OP_LITERAL);
-      Literal();
-
-      m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-        m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-
-      matchFound = true;
-    }
-    else if (m_tokenChar == '$')
-    {
-      nextToken();  // consume '$'
-      appendOp(2, OpCodes.OP_VARIABLE);
-      QName();
-      
-      m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-        m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-
-      matchFound = true;
-    }
-    else if (m_tokenChar == '(')
-    {
-      nextToken();
-      appendOp(2, OpCodes.OP_GROUP);
-      Expr();
-      consumeExpected(')');
-
-      m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-        m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-
-      matchFound = true;
-    }
-    else if ((null != m_token) && ((('.' == m_tokenChar) && (m_token.length() > 1) && Character.isDigit(
-            m_token.charAt(1))) || Character.isDigit(m_tokenChar)))
-    {
-      appendOp(2, OpCodes.OP_NUMBERLIT);
-      Number();
-
-      m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-        m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-
-      matchFound = true;
-    }
-    else if (lookahead('(', 1) || (lookahead(':', 1) && lookahead('(', 3)))
-    {
-      matchFound = FunctionCall();
-    }
-    else
-    {
-      matchFound = false;
-    }
-
-    return matchFound;
-  }
-
-  /**
-   *
-   * Argument    ::=    Expr
-   *
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void Argument() throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    appendOp(2, OpCodes.OP_ARGUMENT);
-    Expr();
-
-    m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-  }
-
-  /**
-   *
-   * FunctionCall    ::=    FunctionName '(' ( Argument ( ',' Argument)*)? ')'
-   *
-   * @return true if, and only if, a FunctionCall was matched
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected boolean FunctionCall() throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    if (lookahead(':', 1))
-    {
-      appendOp(4, OpCodes.OP_EXTFUNCTION);
-
-      m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH + 1] = m_queueMark - 1;
-
-      nextToken();
-      consumeExpected(':');
-
-      m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH + 2] = m_queueMark - 1;
-
-      nextToken();
-    }
-    else
-    {
-      int funcTok = getFunctionToken(m_token);
-
-      if (-1 == funcTok)
-      {
-        error(XPATHErrorResources.ER_COULDNOT_FIND_FUNCTION,
-              new Object[]{ m_token });  //"Could not find function: "+m_token+"()");
-      }
-
-      switch (funcTok)
-      {
-      case OpCodes.NODETYPE_PI :
-      case OpCodes.NODETYPE_COMMENT :
-      case OpCodes.NODETYPE_TEXT :
-      case OpCodes.NODETYPE_NODE :
-        // Node type tests look like function calls, but they're not
-        return false;
-      default :
-        appendOp(3, OpCodes.OP_FUNCTION);
-
-        m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH + 1] = funcTok;
-      }
-
-      nextToken();
-    }
-
-    consumeExpected('(');
-
-    while (!tokenIs(')') && m_token != null)
-    {
-      if (tokenIs(','))
-      {
-        error(XPATHErrorResources.ER_FOUND_COMMA_BUT_NO_PRECEDING_ARG, null);  //"Found ',' but no preceding argument!");
-      }
-
-      Argument();
-
-      if (!tokenIs(')'))
-      {
-        consumeExpected(',');
-
-        if (tokenIs(')'))
-        {
-          error(XPATHErrorResources.ER_FOUND_COMMA_BUT_NO_FOLLOWING_ARG,
-                null);  //"Found ',' but no following argument!");
-        }
-      }
-    }
-
-    consumeExpected(')');
-
-    // Terminate for safety.
-    m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = OpCodes.ENDOP;
-    m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-    m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-
-    return true;
-  }
-
-  // ============= GRAMMAR FUNCTIONS =================
-
-  /**
-   *
-   * LocationPath ::= RelativeLocationPath
-   * | AbsoluteLocationPath
-   *
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void LocationPath() throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    // int locationPathOpPos = opPos;
-    appendOp(2, OpCodes.OP_LOCATIONPATH);
-
-    boolean seenSlash = tokenIs('/');
-
-    if (seenSlash)
-    {
-      appendOp(4, OpCodes.FROM_ROOT);
-
-      // Tell how long the step is without the predicate
-      m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - 2] = 4;
-      m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - 1] =
-        OpCodes.NODETYPE_ROOT;
-
-      nextToken();
-    }
-
-    if (m_token != null)
-    {
-      if (!RelativeLocationPath() && !seenSlash)
-      {
-        // Neither a '/' nor a RelativeLocationPath - i.e., matched nothing
-        // "Location path expected, but found "+m_token+" was encountered."
-        error(XPATHErrorResources.ER_EXPECTED_LOC_PATH, 
-              new Object [] {m_token});
-      }
-    }
-
-    // Terminate for safety.
-    m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = OpCodes.ENDOP;
-    m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-    m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-  }
-
-  /**
-   *
-   * RelativeLocationPath ::= Step
-   * | RelativeLocationPath '/' Step
-   * | AbbreviatedRelativeLocationPath
-   *
-   * @returns true if, and only if, a RelativeLocationPath was matched
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected boolean RelativeLocationPath()
-               throws javax.xml.transform.TransformerException
-  {
-    if (!Step())
-    {
-      return false;
-    }
-
-    while (tokenIs('/'))
-    {
-      nextToken();
-
-      if (!Step())
-      {
-        // RelativeLocationPath can't end with a trailing '/'
-        // "Location step expected following '/' or '//'"
-        error(XPATHErrorResources.ER_EXPECTED_LOC_STEP, null);
-      }
-    }
-
-    return true;
-  }
-
-  /**
-   *
-   * Step    ::=    Basis Predicate
-   * | AbbreviatedStep
-   *
-   * @returns false if step was empty (or only a '/'); true, otherwise
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected boolean Step() throws javax.xml.transform.TransformerException
-  {
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    boolean doubleSlash = tokenIs('/');
-
-    // At most a single '/' before each Step is consumed by caller; if the
-    // first thing is a '/', that means we had '//' and the Step must not
-    // be empty.
-    if (doubleSlash)
-    {
-      nextToken();
-
-      appendOp(2, OpCodes.FROM_DESCENDANTS_OR_SELF);
-
-      // Have to fix up for patterns such as '//@foo' or '//attribute::foo',
-      // which translate to 'descendant-or-self::node()/attribute::foo'.
-      // notice I leave the '/' on the queue, so the next will be processed
-      // by a regular step pattern.
-
-      // Make room for telling how long the step is without the predicate
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-      m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] =
-        OpCodes.NODETYPE_NODE;
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-
-      // Tell how long the step is without the predicate
-      m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH + 1] =
-          m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-
-      // Tell how long the step is with the predicate
-      m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-          m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-
-      opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-    }
-
-    if (tokenIs("."))
-    {
-      nextToken();
-
-      if (tokenIs('['))
-      {
-        error(XPATHErrorResources.ER_PREDICATE_ILLEGAL_SYNTAX, null);  //"'..[predicate]' or '.[predicate]' is illegal syntax.  Use 'self::node()[predicate]' instead.");
-      }
-
-      appendOp(4, OpCodes.FROM_SELF);
-
-      // Tell how long the step is without the predicate
-      m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - 2] = 4;
-      m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - 1] =
-        OpCodes.NODETYPE_NODE;
-    }
-    else if (tokenIs(".."))
-    {
-      nextToken();
-      appendOp(4, OpCodes.FROM_PARENT);
-
-      // Tell how long the step is without the predicate
-      m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - 2] = 4;
-      m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - 1] =
-        OpCodes.NODETYPE_NODE;
-    }
-
-    // There is probably a better way to test for this 
-    // transition... but it gets real hairy if you try 
-    // to do it in basis().
-    else if (tokenIs('*') || tokenIs('@') || tokenIs('_')
-             || (m_token!= null && Character.isLetter(m_token.charAt(0))))
-    {
-      Basis();
-
-      while (tokenIs('['))
-      {
-        Predicate();
-      }
-
-      // Tell how long the entire step is.
-      m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-        m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-    }
-    else
-    {
-      // No Step matched - that's an error if previous thing was a '//'
-      if (doubleSlash)
-      {
-        // "Location step expected following '/' or '//'"
-        error(XPATHErrorResources.ER_EXPECTED_LOC_STEP, null);
-      }
-
-      return false;
-    }
-
-    return true;
-  }
-
-  /**
-   *
-   * Basis    ::=    AxisName '::' NodeTest
-   * | AbbreviatedBasis
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void Basis() throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-    int axesType;
-
-    // The next blocks guarantee that a FROM_XXX will be added.
-    if (lookahead("::", 1))
-    {
-      axesType = AxisName();
-
-      nextToken();
-      nextToken();
-    }
-    else if (tokenIs('@'))
-    {
-      axesType = OpCodes.FROM_ATTRIBUTES;
-
-      appendOp(2, axesType);
-      nextToken();
-    }
-    else
-    {
-      axesType = OpCodes.FROM_CHILDREN;
-
-      appendOp(2, axesType);
-    }
-
-    // Make room for telling how long the step is without the predicate
-    m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-
-    NodeTest(axesType);
-
-    // Tell how long the step is without the predicate
-    m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH + 1] =
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-  }
-
-  /**
-   *
-   * Basis    ::=    AxisName '::' NodeTest
-   * | AbbreviatedBasis
-   *
-   * @return FROM_XXX axes type, found in {@link org.apache.xpath.compiler.Keywords}.
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected int AxisName() throws javax.xml.transform.TransformerException
-  {
-
-    Object val = Keywords.m_axisnames.get(m_token);
-
-    if (null == val)
-    {
-      error(XPATHErrorResources.ER_ILLEGAL_AXIS_NAME,
-            new Object[]{ m_token });  //"illegal axis name: "+m_token);
-    }
-
-    int axesType = ((Integer) val).intValue();
-
-    appendOp(2, axesType);
-
-    return axesType;
-  }
-
-  /**
-   *
-   * NodeTest    ::=    WildcardName
-   * | NodeType '(' ')'
-   * | 'processing-instruction' '(' Literal ')'
-   *
-   * @param axesType FROM_XXX axes type, found in {@link org.apache.xpath.compiler.Keywords}.
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void NodeTest(int axesType) throws javax.xml.transform.TransformerException
-  {
-
-    if (lookahead('(', 1))
-    {
-      Object nodeTestOp = Keywords.m_nodetypes.get(m_token);
-
-      if (null == nodeTestOp)
-      {
-        error(XPATHErrorResources.ER_UNKNOWN_NODETYPE,
-              new Object[]{ m_token });  //"Unknown nodetype: "+m_token);
-      }
-      else
-      {
-        nextToken();
-
-        int nt = ((Integer) nodeTestOp).intValue();
-
-        m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = nt;
-        m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-
-        consumeExpected('(');
-
-        if (OpCodes.NODETYPE_PI == nt)
-        {
-          if (!tokenIs(')'))
-          {
-            Literal();
-          }
-        }
-
-        consumeExpected(')');
-      }
-    }
-    else
-    {
-
-      // Assume name of attribute or element.
-      m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = OpCodes.NODENAME;
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-
-      if (lookahead(':', 1))
-      {
-        if (tokenIs('*'))
-        {
-          m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] =
-            OpCodes.ELEMWILDCARD;
-        }
-        else
-        {
-          m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = m_queueMark
-                  - 1;
-
-          // Minimalist check for an NCName - just check first character
-          // to distinguish from other possible tokens
-          if (!Character.isLetter(m_tokenChar) && !tokenIs('_'))
-          {
-            // "Node test that matches either NCName:* or QName was expected."
-            error(XPATHErrorResources.ER_EXPECTED_NODE_TEST, null);
-          }
-        }
-
-        nextToken();
-        consumeExpected(':');
-      }
-      else
-      {
-        m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = OpCodes.EMPTY;
-      }
-
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-
-      if (tokenIs('*'))
-      {
-        m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] =
-          OpCodes.ELEMWILDCARD;
-      }
-      else
-      {
-        if (OpCodes.FROM_NAMESPACE == axesType)
-        {
-          String prefix = (String) this.m_ops.m_tokenQueue[m_queueMark - 1];
-          String namespace =
-            ((PrefixResolver) m_namespaceContext).getNamespaceForPrefix(
-              prefix);
-
-          this.m_ops.m_tokenQueue[m_queueMark - 1] = namespace;
-        }
-
-        m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = m_queueMark - 1;
-
-        // Minimalist check for an NCName - just check first character
-        // to distinguish from other possible tokens
-        if (!Character.isLetter(m_tokenChar) && !tokenIs('_'))
-        {
-          // "Node test that matches either NCName:* or QName was expected."
-          error(XPATHErrorResources.ER_EXPECTED_NODE_TEST, null);
-        }
-      }
-
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-
-      nextToken();
-    }
-  }
-
-  /**
-   *
-   * Predicate ::= '[' PredicateExpr ']'
-   *
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void Predicate() throws javax.xml.transform.TransformerException
-  {
-
-    if (tokenIs('['))
-    {
-      nextToken();
-      PredicateExpr();
-      consumeExpected(']');
-    }
-  }
-
-  /**
-   *
-   * PredicateExpr ::= Expr
-   *
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void PredicateExpr() throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    appendOp(2, OpCodes.OP_PREDICATE);
-    Expr();
-
-    // Terminate for safety.
-    m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = OpCodes.ENDOP;
-    m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-    m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-  }
-
-  /**
-   * QName ::=  (Prefix ':')? LocalPart
-   * Prefix ::=  NCName
-   * LocalPart ::=  NCName
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void QName() throws javax.xml.transform.TransformerException
-  {
-    // Namespace
-    if(lookahead(':', 1))
-    {
-      m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = m_queueMark - 1;
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-
-      nextToken();
-      consumeExpected(':');
-    }
-    else
-    {
-      m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = OpCodes.EMPTY;
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-    }
-    
-    // Local name
-    m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = m_queueMark - 1;
-    m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-
-    nextToken();
-  }
-
-  /**
-   * NCName ::=  (Letter | '_') (NCNameChar)
-   * NCNameChar ::=  Letter | Digit | '.' | '-' | '_' | CombiningChar | Extender
-   */
-  protected void NCName()
-  {
-
-    m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = m_queueMark - 1;
-    m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-
-    nextToken();
-  }
-
-  /**
-   * The value of the Literal is the sequence of characters inside
-   * the " or ' characters>.
-   *
-   * Literal  ::=  '"' [^"]* '"'
-   * | "'" [^']* "'"
-   *
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void Literal() throws javax.xml.transform.TransformerException
-  {
-
-    int last = m_token.length() - 1;
-    char c0 = m_tokenChar;
-    char cX = m_token.charAt(last);
-
-    if (((c0 == '\"') && (cX == '\"')) || ((c0 == '\'') && (cX == '\'')))
-    {
-
-      // Mutate the token to remove the quotes and have the XString object
-      // already made.
-      int tokenQueuePos = m_queueMark - 1;
-
-      m_ops.m_tokenQueue[tokenQueuePos] = null;
-
-      Object obj = new XString(m_token.substring(1, last));
-
-      m_ops.m_tokenQueue[tokenQueuePos] = obj;
-
-      // lit = m_token.substring(1, last);
-      m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = tokenQueuePos;
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-
-      nextToken();
-    }
-    else
-    {
-      error(XPATHErrorResources.ER_PATTERN_LITERAL_NEEDS_BE_QUOTED,
-            new Object[]{ m_token });  //"Pattern literal ("+m_token+") needs to be quoted!");
-    }
-  }
-
-  /**
-   *
-   * Number ::= [0-9]+('.'[0-9]+)? | '.'[0-9]+
-   *
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void Number() throws javax.xml.transform.TransformerException
-  {
-
-    if (null != m_token)
-    {
-
-      // Mutate the token to remove the quotes and have the XNumber object
-      // already made.
-      double num;
-
-      try
-      {
-        num = Double.valueOf(m_token).doubleValue();
-      }
-      catch (NumberFormatException nfe)
-      {
-        num = 0.0;  // to shut up compiler.
-
-        error(XPATHErrorResources.ER_COULDNOT_BE_FORMATTED_TO_NUMBER,
-              new Object[]{ m_token });  //m_token+" could not be formatted to a number!");
-      }
-
-      m_ops.m_tokenQueue[m_queueMark - 1] = new XNumber(num);
-      m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = m_queueMark - 1;
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-
-      nextToken();
-    }
-  }
-
-  // ============= PATTERN FUNCTIONS =================
-
-  /**
-   *
-   * Pattern  ::=  LocationPathPattern
-   * | Pattern '|' LocationPathPattern
-   *
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void Pattern() throws javax.xml.transform.TransformerException
-  {
-
-    while (true)
-    {
-      LocationPathPattern();
-
-      if (tokenIs('|'))
-      {
-        nextToken();
-      }
-      else
-      {
-        break;
-      }
-    }
-  }
-
-  /**
-   *
-   *
-   * LocationPathPattern  ::=  '/' RelativePathPattern?
-   * | IdKeyPattern (('/' | '//') RelativePathPattern)?
-   * | '//'? RelativePathPattern
-   *
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void LocationPathPattern() throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-
-    final int RELATIVE_PATH_NOT_PERMITTED = 0;
-    final int RELATIVE_PATH_PERMITTED     = 1;
-    final int RELATIVE_PATH_REQUIRED      = 2;
-
-    int relativePathStatus = RELATIVE_PATH_NOT_PERMITTED;
-
-    appendOp(2, OpCodes.OP_LOCATIONPATHPATTERN);
-
-    if (lookahead('(', 1)
-            && (tokenIs(Keywords.FUNC_ID_STRING)
-                || tokenIs(Keywords.FUNC_KEY_STRING)))
-    {
-      IdKeyPattern();
-
-      if (tokenIs('/'))
-      {
-        nextToken();
-
-        if (tokenIs('/'))
-        {
-          appendOp(4, OpCodes.MATCH_ANY_ANCESTOR);
-
-          nextToken();
-        }
-        else
-        {
-          appendOp(4, OpCodes.MATCH_IMMEDIATE_ANCESTOR);
-        }
-
-        // Tell how long the step is without the predicate
-        m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - 2] = 4;
-        m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - 1] =
-          OpCodes.NODETYPE_FUNCTEST;
-
-        relativePathStatus = RELATIVE_PATH_REQUIRED;
-      }
-    }
-    else if (tokenIs('/'))
-    {
-      if (lookahead('/', 1))
-      {
-        appendOp(4, OpCodes.MATCH_ANY_ANCESTOR);
-        
-        // Added this to fix bug reported by Myriam for match="//x/a"
-        // patterns.  If you don't do this, the 'x' step will think it's part
-        // of a '//' pattern, and so will cause 'a' to be matched when it has
-        // any ancestor that is 'x'.
-        nextToken();
-
-        relativePathStatus = RELATIVE_PATH_REQUIRED;
-      }
-      else
-      {
-        appendOp(4, OpCodes.FROM_ROOT);
-
-        relativePathStatus = RELATIVE_PATH_PERMITTED;
-      }
-
-
-      // Tell how long the step is without the predicate
-      m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - 2] = 4;
-      m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - 1] =
-        OpCodes.NODETYPE_ROOT;
-
-      nextToken();
-    }
-    else
-    {
-      relativePathStatus = RELATIVE_PATH_REQUIRED;
-    }
-
-    if (relativePathStatus != RELATIVE_PATH_NOT_PERMITTED)
-    {
-      if (!tokenIs('|') && (null != m_token))
-      {
-        RelativePathPattern();
-      }
-      else if (relativePathStatus == RELATIVE_PATH_REQUIRED)
-      {
-        // "A relative path pattern was expected."
-        error(XPATHErrorResources.ER_EXPECTED_REL_PATH_PATTERN, null);
-      }
-    }
-
-    // Terminate for safety.
-    m_ops.m_opMap[m_ops.m_opMap[OpMap.MAPINDEX_LENGTH]] = OpCodes.ENDOP;
-    m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-    m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-  }
-
-  /**
-   *
-   * IdKeyPattern  ::=  'id' '(' Literal ')'
-   * | 'key' '(' Literal ',' Literal ')'
-   * (Also handle doc())
-   *
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void IdKeyPattern() throws javax.xml.transform.TransformerException
-  {
-    FunctionCall();
-  }
-
-  /**
-   *
-   * RelativePathPattern  ::=  StepPattern
-   * | RelativePathPattern '/' StepPattern
-   * | RelativePathPattern '//' StepPattern
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected void RelativePathPattern()
-              throws javax.xml.transform.TransformerException
-  {
-
-    // Caller will have consumed any '/' or '//' preceding the
-    // RelativePathPattern, so let StepPattern know it can't begin with a '/'
-    boolean trailingSlashConsumed = StepPattern(false);
-
-    while (tokenIs('/'))
-    {
-      nextToken();
-
-      // StepPattern() may consume first slash of pair in "a//b" while
-      // processing StepPattern "a".  On next iteration, let StepPattern know
-      // that happened, so it doesn't match ill-formed patterns like "a///b".
-      trailingSlashConsumed = StepPattern(!trailingSlashConsumed);
-    }
-  }
-
-  /**
-   *
-   * StepPattern  ::=  AbbreviatedNodeTestStep
-   *
-   * @param isLeadingSlashPermitted a boolean indicating whether a slash can
-   *        appear at the start of this step
-   *
-   * @return boolean indicating whether a slash following the step was consumed
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected boolean StepPattern(boolean isLeadingSlashPermitted)
-            throws javax.xml.transform.TransformerException
-  {
-    return AbbreviatedNodeTestStep(isLeadingSlashPermitted);
-  }
-
-  /**
-   *
-   * AbbreviatedNodeTestStep    ::=    '@'? NodeTest Predicate
-   *
-   * @param isLeadingSlashPermitted a boolean indicating whether a slash can
-   *        appear at the start of this step
-   *
-   * @return boolean indicating whether a slash following the step was consumed
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  protected boolean AbbreviatedNodeTestStep(boolean isLeadingSlashPermitted)
-            throws javax.xml.transform.TransformerException
-  {
-
-    int opPos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-    int axesType;
-
-    // The next blocks guarantee that a MATCH_XXX will be added.
-    int matchTypePos = -1;
-
-    if (tokenIs('@'))
-    {
-      axesType = OpCodes.MATCH_ATTRIBUTE;
-
-      appendOp(2, axesType);
-      nextToken();
-    }
-    else if (this.lookahead("::", 1))
-    {
-      if (tokenIs("attribute"))
-      {
-        axesType = OpCodes.MATCH_ATTRIBUTE;
-
-        appendOp(2, axesType);
-      }
-      else if (tokenIs("child"))
-      {
-        matchTypePos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-        axesType = OpCodes.MATCH_IMMEDIATE_ANCESTOR;
-
-        appendOp(2, axesType);
-      }
-      else
-      {
-        axesType = -1;
-
-        this.error(XPATHErrorResources.ER_AXES_NOT_ALLOWED,
-                   new Object[]{ this.m_token });
-      }
-
-      nextToken();
-      nextToken();
-    }
-    else if (tokenIs('/'))
-    {
-      if (!isLeadingSlashPermitted)
-      {
-        // "A step was expected in the pattern, but '/' was encountered."
-        error(XPATHErrorResources.ER_EXPECTED_STEP_PATTERN, null);
-      }
-      axesType = OpCodes.MATCH_ANY_ANCESTOR;
-
-      appendOp(2, axesType);
-      nextToken();
-    }
-    else
-    {
-      matchTypePos = m_ops.m_opMap[OpMap.MAPINDEX_LENGTH];
-      axesType = OpCodes.MATCH_IMMEDIATE_ANCESTOR;
-
-      appendOp(2, axesType);
-    }
-
-    // Make room for telling how long the step is without the predicate
-    m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] += 1;
-
-    NodeTest(axesType);
-
-    // Tell how long the step is without the predicate
-    m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH + 1] =
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-
-    while (tokenIs('['))
-    {
-      Predicate();
-    }
-
-    boolean trailingSlashConsumed;
-
-    // For "a//b", where "a" is current step, we need to mark operation of
-    // current step as "MATCH_ANY_ANCESTOR".  Then we'll consume the first
-    // slash and subsequent step will be treated as a MATCH_IMMEDIATE_ANCESTOR
-    // (unless it too is followed by '//'.)
-    //
-    // %REVIEW%  Following is what happens today, but I'm not sure that's
-    // %REVIEW%  correct behaviour.  Perhaps no valid case could be constructed
-    // %REVIEW%  where it would matter?
-    //
-    // If current step is on the attribute axis (e.g., "@x//b"), we won't
-    // change the current step, and let following step be marked as
-    // MATCH_ANY_ANCESTOR on next call instead.
-    if ((matchTypePos > -1) && tokenIs('/') && lookahead('/', 1))
-    {
-      m_ops.m_opMap[matchTypePos] = OpCodes.MATCH_ANY_ANCESTOR;
-
-      nextToken();
-
-      trailingSlashConsumed = true;
-    }
-    else
-    {
-      trailingSlashConsumed = false;
-    }
-
-    // Tell how long the entire step is.
-    m_ops.m_opMap[opPos + OpMap.MAPINDEX_LENGTH] =
-      m_ops.m_opMap[OpMap.MAPINDEX_LENGTH] - opPos;
-
-    return trailingSlashConsumed;
-  }
-}
diff --git a/src/org/apache/xpath/compiler/package.html b/src/org/apache/xpath/compiler/package.html
deleted file mode 100644
index 43dd328..0000000
--- a/src/org/apache/xpath/compiler/package.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
-  <title>XPath parsing and compilation support Package.</title>
-  <body>
-    <p>Implements an XPath parser which produces an OpMap, and a so-called Compiler
-    which produces an expression tree for fast evaluation.<p>
- </body>
-</html>
-
-
diff --git a/src/org/apache/xpath/objects/XBooleanStatic.java b/src/org/apache/xpath/objects/XBooleanStatic.java
deleted file mode 100644
index c56898a..0000000
--- a/src/org/apache/xpath/objects/XBooleanStatic.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 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.xpath.objects;
-
-import org.w3c.dom.*;
-
-import org.apache.xpath.res.XPATHErrorResources;
-import org.apache.xalan.res.XSLMessages;
-
-/**
- * <meta name="usage" content="internal"/>
- * This class doesn't have any XPathContext, so override
- * whatever to ensure it works OK.
- */
-public class XBooleanStatic extends XBoolean
-{
-
-  /** The value of the object.
-   *  @serial          */
-  boolean m_val;
-
-  /**
-   * Construct a XBooleanStatic object.
-   *
-   * @param b The value of the object
-   */
-  public XBooleanStatic(boolean b)
-  {
-
-    super(b);
-
-    m_val = b;
-  }
-
-  /**
-   * Tell if two objects are functionally equal.
-   *
-   * @param obj2 Object to compare to this 
-   *
-   * @return True if the two objects are equal
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  public boolean equals(XObject obj2)
-  {
-    try
-    {
-      return m_val == obj2.bool();
-    }
-    catch(javax.xml.transform.TransformerException te)
-    {
-      throw new org.apache.xml.utils.WrappedRuntimeException(te);
-    }
-  }
-}
diff --git a/src/org/apache/xpath/operations/Minus.java b/src/org/apache/xpath/operations/Minus.java
deleted file mode 100644
index 24ee655..0000000
--- a/src/org/apache/xpath/operations/Minus.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 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.xpath.operations;
-
-import org.apache.xpath.objects.XObject;
-import org.apache.xpath.objects.XNumber;
-import org.apache.xpath.XPathContext;
-
-/**
- * The binary '-' operation expression executer.
- */
-public class Minus extends Operation
-{
-
-  /**
-   * Apply the operation to two operands, and return the result.
-   *
-   *
-   * @param left non-null reference to the evaluated left operand.
-   * @param right non-null reference to the evaluated right operand.
-   *
-   * @return non-null reference to the XObject that represents the 
-   *         result of the operation.
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  public XObject operate(XObject left, XObject right)
-          throws javax.xml.transform.TransformerException
-  {
-    return new XNumber(left.num() - right.num());
-  }
-  
-  /**
-   * Evaluate this operation directly to a double.
-   *
-   * @param xctxt The runtime execution context.
-   *
-   * @return The result of the operation as a double.
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  public double num(XPathContext xctxt)
-          throws javax.xml.transform.TransformerException
-  {
-
-    return (m_left.num(xctxt) - m_right.num(xctxt));
-  }
-
-}
diff --git a/src/org/apache/xpath/operations/Plus.java b/src/org/apache/xpath/operations/Plus.java
deleted file mode 100644
index 7783aa5..0000000
--- a/src/org/apache/xpath/operations/Plus.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999 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.xpath.operations;
-
-import org.apache.xpath.objects.XObject;
-import org.apache.xpath.objects.XNumber;
-import org.apache.xpath.XPathContext;
-
-/**
- * The '+' operation expression executer.
- */
-public class Plus extends Operation
-{
-
-  /**
-   * Apply the operation to two operands, and return the result.
-   *
-   *
-   * @param left non-null reference to the evaluated left operand.
-   * @param right non-null reference to the evaluated right operand.
-   *
-   * @return non-null reference to the XObject that represents the result of the operation.
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  public XObject operate(XObject left, XObject right)
-          throws javax.xml.transform.TransformerException
-  {
-    return new XNumber(left.num() + right.num());
-  }
-  
-  /**
-   * Evaluate this operation directly to a double.
-   *
-   * @param xctxt The runtime execution context.
-   *
-   * @return The result of the operation as a double.
-   *
-   * @throws javax.xml.transform.TransformerException
-   */
-  public double num(XPathContext xctxt)
-          throws javax.xml.transform.TransformerException
-  {
-
-    return (m_right.num(xctxt) + m_left.num(xctxt));
-  }
-
-}
