/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#if !defined(XPATH_HEADER_GUARD_1357924680)
#define XPATH_HEADER_GUARD_1357924680



// Base header file.  Must be first.
#include <xalanc/XPath/XPathDefinitions.hpp>



#include <xalanc/XalanDOM/XalanDOMString.hpp>



#include <xalanc/PlatformSupport/DoubleSupport.hpp>



// Base class header files...
#include <xalanc/XPath/XPathExecutionContext.hpp>



#include <xalanc/XPath/MutableNodeRefList.hpp>
#include <xalanc/XPath/XPathExpression.hpp>
#include <xalanc/XPath/Function.hpp>
#include <xalanc/XPath/XPathFunctionTable.hpp>



namespace XERCES_CPP_NAMESPACE
{
    class Locator;
}



namespace XALAN_CPP_NAMESPACE {



class PrefixResolver;
class XObject;
class XalanElement;
class XalanNode;
class XPathConstructionContext;



class XALAN_XPATH_EXPORT XPath
{
public:

    typedef xercesc::Locator  LocatorType;

    typedef XPathExpression::OpCodeMapPositionType              OpCodeMapPositionType;
    typedef XPathExpression::OpCodeMapValueType                 OpCodeMapValueType;
    typedef XPathExpression::TokenQueuePositionType             TokenQueuePositionType;
    typedef XPathExecutionContext::GetCachedString              GetCachedString;
    typedef XPathExecutionContext::PrefixResolverSetAndRestore  PrefixResolverSetAndRestore;
    typedef XPathExecutionContext::CurrentNodePushAndPop        CurrentNodePushAndPop;


    static const XalanDOMChar   PSEUDONAME_ANY[];
    static const XalanDOMChar   PSEUDONAME_ROOT[];
    static const XalanDOMChar   PSEUDONAME_TEXT[];
    static const XalanDOMChar   PSEUDONAME_COMMENT[];
    static const XalanDOMChar   PSEUDONAME_PI[];
    static const XalanDOMChar   PSEUDONAME_OTHER[];
    static const XalanDOMChar   PSEUDONAME_NODE[];

    enum eMatchScore
    {
        eMatchScoreNone,
        eMatchScoreNodeTest,
        eMatchScoreNSWild,
        eMatchScoreQName,
        eMatchScoreOther
    };

    class TargetData
    {
    public:

        enum eTargetType { eAttribute, eElement, eAny, eOther };

        TargetData() :
            m_string(0),
            m_priority(eMatchScoreNone),
            m_targetType(eOther)
        {
        }

        TargetData(
                const XalanDOMChar*     theString,
                eMatchScore             thePriority,
                eTargetType             theTargetType) :
            m_string(theString),
            m_priority(thePriority),
            m_targetType(theTargetType)
        {
        }

        const XalanDOMChar*
        getString() const
        {
            return m_string;
        }

        eMatchScore
        getDefaultPriority() const
        {
            return m_priority;
        }

        eTargetType
        getTargetType() const
        {
            return m_targetType;
        }

    private:

        const XalanDOMChar*     m_string;

        eMatchScore             m_priority;

        eTargetType             m_targetType;
    };

    typedef XalanVector<TargetData>     TargetDataVectorType;

    /**
     * Perform static initialization.  See class XPathInit.
     */
    static void
    initialize(MemoryManager&   theManager);

    /**
     * Perform static shut down.  See class XPathInit.
     */
    static void
    terminate();

    /**
     * Construct an XPath.
     *
     * @param theLocator The applicable Locator, if any.
     */
    explicit
    XPath(
            MemoryManager&  theManager,
            const Locator*  theLocator = 0);

    static XPath*
    create(
            MemoryManager&  theManager,
            const Locator*  theLocator = 0);

    MemoryManager&
    getMemoryManager()
    {
        return m_expression.getMemoryManager();
    }

    ~XPath();

    /**
     * Shrink internal tables.
     */
    void
    shrink()
    {
        m_expression.shrink();
    }

    /**
     * Execute the XPath from the provided context.
     *
     * @param context          current source tree context node, which must not be 0
     * @param prefixResolver   prefix resolver to use
     * @param executionContext current execution context
     * @return smart-pointer to result XObject
     */
    const XObjectPtr
    execute(
            XalanNode*              context,
            const PrefixResolver&   prefixResolver,
            XPathExecutionContext&  executionContext) const;

    /**
     * Execute the XPath from the provided context.
     *
     * @param context          current source tree context node, which must not be 0
     * @param prefixResolver   prefix resolver to use
     * @param executionContext current execution context
     * @param result           the boolean result
     */
    void
    execute(
            XalanNode*              context,
            const PrefixResolver&   prefixResolver,
            XPathExecutionContext&  executionContext,
            bool&                   result) const;

    /**
     * Execute the XPath from the provided context.
     *
     * @param context          current source tree context node, which must not be 0
     * @param prefixResolver   prefix resolver to use
     * @param executionContext current execution context
     * @param result           the numeric result
     */
    void
    execute(
            XalanNode*              context,
            const PrefixResolver&   prefixResolver,
            XPathExecutionContext&  executionContext,
            double&                 result) const;

    /**
     * Execute the XPath from the provided context.  The
     * result is appended to the supplied string.
     *
     * @param context          current source tree context node, which must not be 0
     * @param prefixResolver   prefix resolver to use
     * @param executionContext current execution context
     * @param result           the string result
     */
    void
    execute(
            XalanNode*              context,
            const PrefixResolver&   prefixResolver,
            XPathExecutionContext&  executionContext,
            XalanDOMString&         result) const;

    typedef void (FormatterListener::*MemberFunctionPtr)(const XMLCh* const, const FormatterListener::size_type);

    /**
     * Execute the XPath from the provided context.
     *
     * @param context          current source tree context node, which must not be 0
     * @param prefixResolver   prefix resolver to use
     * @param executionContext current execution context
     * @param formatterListener the FormatterListener instance to receive the result
     * @param function A pointer to the member function of FormatterListener to call
     */
    void
    execute(
            XalanNode*              context,
            const PrefixResolver&   prefixResolver,
            XPathExecutionContext&  executionContext,
            FormatterListener&      formatterListener,
            MemberFunctionPtr       function) const;

    /**
     * Execute the XPath from the provided context.  Normally,
     * the expression will be evaluated and the result placed
     * in the parameter result.  However, some cases (such as
     * the evalution of a variable) could result in the copying
     * of a node-set, which is extremely expensive.  In that
     * case, the return value will contain the result of the
     * evaluation.  If the call to XObject::null() on the return
     * value is true, that indicates the value was executed
     * directly into the parameter.  Otherwise, the parameter
     * will be empty, and the result will be in the XObject
     * instance returned.
     *
     * @param context          current source tree context node, which must not be 0
     * @param prefixResolver   prefix resolver to use
     * @param executionContext current execution context
     * @param result           the node-set result
     * @return the node-set result, if the result was not returned in the parameter
     */
    const XObjectPtr
    execute(
            XalanNode*              context,
            const PrefixResolver&   prefixResolver,
            XPathExecutionContext&  executionContext,
            MutableNodeRefList&     result) const;

    /**
     * Execute the XPath from the provided context.
     *
     * @param context          current source tree context node, which must not be 0
     * @param prefixResolver   prefix resolver to use
     * @param contextNodeList  node list for current context
     * @param executionContext current execution context
     * @return smart-pointer to result XObject
     */
    const XObjectPtr
    execute(
            XalanNode*              context,
            const PrefixResolver&   prefixResolver,
            const NodeRefListBase&  contextNodeList,
            XPathExecutionContext&  executionContext) const
    {
        // Push and pop the context node list...
        XPathExecutionContext::ContextNodeListPushAndPop    thePushAndPop(
                                        executionContext,
                                        contextNodeList);

        return execute(context, prefixResolver, executionContext);
    }

    /**
     * Execute the XPath from the provided context.
     *
     * @param context          current source tree context node, which must not be 0
     * @param prefixResolver   prefix resolver to use
     * @param contextNodeList  node list for current context
     * @param executionContext current execution context
     * @param result           the boolean result
     */
    void
    execute(
            XalanNode*              context,
            const PrefixResolver&   prefixResolver,
            const NodeRefListBase&  contextNodeList,
            XPathExecutionContext&  executionContext,
            bool&                   result) const
    {
        // Push and pop the context node list...
        XPathExecutionContext::ContextNodeListPushAndPop    thePushAndPop(
                                        executionContext,
                                        contextNodeList);

        execute(context, prefixResolver, executionContext, result);
    }

    /**
     * Execute the XPath from the provided context.
     *
     * @param context          current source tree context node, which must not be 0
     * @param prefixResolver   prefix resolver to use
     * @param contextNodeList  node list for current context
     * @param executionContext current execution context
     * @param result           the numeric result
     */
    void
    execute(
            XalanNode*              context,
            const PrefixResolver&   prefixResolver,
            const NodeRefListBase&  contextNodeList,
            XPathExecutionContext&  executionContext,
            double&                 result) const
    {
        // Push and pop the context node list...
        XPathExecutionContext::ContextNodeListPushAndPop    thePushAndPop(
                                        executionContext,
                                        contextNodeList);

        execute(context, prefixResolver, executionContext, result);
    }

    /**
     * Execute the XPath from the provided context.  The
     * result is appended to the supplied string.
     *
     * @param context          current source tree context node, which must not be 0
     * @param prefixResolver   prefix resolver to use
     * @param contextNodeList  node list for current context
     * @param executionContext current execution context
     * @param result           the string result
     */
    void
    execute(
            XalanNode*              context,
            const PrefixResolver&   prefixResolver,
            const NodeRefListBase&  contextNodeList,
            XPathExecutionContext&  executionContext,
            XalanDOMString&         result) const
    {
        // Push and pop the context node list...
        XPathExecutionContext::ContextNodeListPushAndPop    thePushAndPop(
                                        executionContext,
                                        contextNodeList);

        execute(context, prefixResolver, executionContext, result);
    }

    /**
     * Execute the XPath from the provided context.
     *
     * @param context          current source tree context node, which must not be 0
     * @param prefixResolver   prefix resolver to use
     * @param contextNodeList  node list for current context
     * @param executionContext current execution context
     * @param formatterListener the FormatterListener instance to receive the result
     * @param function A pointer to the member function of FormatterListener to call
     */
    void
    execute(
            XalanNode*              context,
            const PrefixResolver&   prefixResolver,
            const NodeRefListBase&  contextNodeList,
            XPathExecutionContext&  executionContext,
            FormatterListener&      formatterListener,
            MemberFunctionPtr       function) const
    {
        // Push and pop the context node list...
        XPathExecutionContext::ContextNodeListPushAndPop    thePushAndPop(
                                        executionContext,
                                        contextNodeList);

        execute(context, prefixResolver, executionContext, formatterListener, function);
    }

    /**
     * Execute the XPath from the provided context.  Normally,
     * the expression will be evaluated and the result placed
     * in the parameter result.  However, some cases (such as
     * the evalution of a variable) could result in the copying
     * of a node-set, which is extremely expensive.  In that
     * case, the return value will contain the result of the
     * evaluation.  If the call to XObject::null() on the return
     * value is true, that indicates the value was executed
     * directly into the parameter.  Otherwise, the parameter
     * will be empty, and the result will be in the XObject
     * instance returned.
     *
     * @param context          current source tree context node, which must not be 0
     * @param prefixResolver   prefix resolver to use
     * @param contextNodeList  node list for current context
     * @param executionContext current execution context
     * @param result           the result as a set of nodes
     * @return the node-set result, if the result was not returned in the parameter
     */
    const XObjectPtr
    execute(
            XalanNode*              context,
            const PrefixResolver&   prefixResolver,
            const NodeRefListBase&  contextNodeList,
            XPathExecutionContext&  executionContext,
            MutableNodeRefList&     result) const
    {
        // Push and pop the context node list...
        XPathExecutionContext::ContextNodeListPushAndPop    thePushAndPop(
                                        executionContext,
                                        contextNodeList);

        return execute(context, prefixResolver, executionContext, result);
    }

    /**
     * Execute the XPath from the provided context.
     *
     * The prefix resolver and current node must already
     * be set execution context, and must not be 0.
     *
     * @param executionContext current execution context
     * @return smart-pointer to result XObject
     */
    const XObjectPtr
    execute(XPathExecutionContext&  executionContext) const
    {
        assert(executionContext.getCurrentNode() != 0);
        assert(executionContext.getPrefixResolver() != 0);

        return executeMore(
                executionContext.getCurrentNode(),
                getInitialOpCodePosition(),
                executionContext);
    }

    /**
     * Execute the XPath from the provided context.
     *
     * The prefix resolver and current node must already
     * be set execution context, and must not be 0.
     *
     * @param executionContext current execution context
     * @param result the boolean result
     */
    void
    execute(
            XPathExecutionContext&  executionContext,
            bool&                   result) const
    {
        assert(executionContext.getCurrentNode() != 0);
        assert(executionContext.getPrefixResolver() != 0);

        executeMore(
                executionContext.getCurrentNode(),
                getInitialOpCodePosition(),
                executionContext,
                result);
    }

    /**
     * Execute the XPath from the provided context.
     *
     * The prefix resolver must already be set in the
     * execution context.
     *
     * @param executionContext current execution context
     * @param result           the numeric result
     */
    void
    execute(
            XPathExecutionContext&  executionContext,
            double&                 result) const
    {
        assert(executionContext.getCurrentNode() != 0);
        assert(executionContext.getPrefixResolver() != 0);

        executeMore(
                executionContext.getCurrentNode(),
                getInitialOpCodePosition(),
                executionContext,
                result);
    }

    /**
     * Execute the XPath from the provided context. The
     * result is appended to the supplied string.
     *
     * The prefix resolver and current node must already
     * be set execution context, and must not be 0.
     *
     * @param executionContext current execution context
     * @param result the string result
     */
    void
    execute(
            XPathExecutionContext&  executionContext,
            XalanDOMString&         result) const
    {
        assert(executionContext.getCurrentNode() != 0);
        assert(executionContext.getPrefixResolver() != 0);

        executeMore(
                executionContext.getCurrentNode(),
                getInitialOpCodePosition(),
                executionContext,
                result);
    }

    /**
     * Execute the XPath from the provided context.
     * 
     * The prefix resolver and current node must already
     * be set execution context, and must not be 0.
     *
     * @param executionContext current execution context
     * @param formatterListener the FormatterListener instance to receive the result
     * @param function A pointer to the member function of FormatterListener to call
     */
    void
    execute(
            XPathExecutionContext&  executionContext,
            FormatterListener&      formatterListener,
            MemberFunctionPtr       function) const
    {
        assert(executionContext.getCurrentNode() != 0);
        assert(executionContext.getPrefixResolver() != 0);

        executeMore(
                executionContext.getCurrentNode(),
                getInitialOpCodePosition(),
                executionContext,
                formatterListener,
                function);
    }

    /**
     * Execute the XPath from the provided context.  Normally,
     * the expression will be evaluated and the result placed
     * in the parameter result.  However, some cases (such as
     * the evalution of a variable) could result in the copying
     * of a node-set, which is extremely expensive.  In that
     * case, the return value will contain the result of the
     * evaluation.  If the call to XObject::null() on the return
     * value is true, that indicates the value was executed
     * directly into the parameter.  Otherwise, the parameter
     * will be empty, and the result will be in the XObject
     * instance returned.
     * 
     * The prefix resolver and current node must already
     * be set execution context, and must not be 0.
     *
     * @param executionContext current execution context
     * @param result A node list for the result.  This may or may not contain the actual result.
     * @return the node-set result, if the result was not returned in the parameter
     */
    const XObjectPtr
    execute(
            XPathExecutionContext&  executionContext,
            MutableNodeRefList&     result) const
    {
        assert(executionContext.getCurrentNode() != 0);
        assert(executionContext.getPrefixResolver() != 0);

        return executeMore(
                executionContext.getCurrentNode(),
                getInitialOpCodePosition(),
                executionContext,
                result);
    }

    /**
     * Execute the XPath from the provided context.
     *
     * The current node must already be set execution context,
     * and must not be 0.
     *
     * @param executionContext current execution context
     * @param prefixResolver   prefix resolver to use
     * @return smart-pointer to result XObject
     */
    const XObjectPtr
    execute(
            const PrefixResolver&   prefixResolver,
            XPathExecutionContext&  executionContext) const
    {
        assert(executionContext.getCurrentNode() != 0);

        // Push and pop the PrefixResolver...
        const PrefixResolverSetAndRestore   theResolverSetAndRestore(
                                                executionContext,
                                                &prefixResolver);

        return executeMore(
                executionContext.getCurrentNode(),
                getInitialOpCodePosition(),
                executionContext);
    }

    /**
     * Execute the XPath from the provided context.
     *
     * The current node must already be set execution context,
     * and must not be 0.
     *
     * @param executionContext current execution context
     * @param prefixResolver prefix resolver to use
     * @param result the boolean result
     */
    void
    execute(
            const PrefixResolver&   prefixResolver,
            XPathExecutionContext&  executionContext,
            bool&                   result) const
    {
        assert(executionContext.getCurrentNode() != 0);

        // Push and pop the PrefixResolver...
        const PrefixResolverSetAndRestore   theResolverSetAndRestore(
                                                executionContext,
                                                &prefixResolver);

        executeMore(
                executionContext.getCurrentNode(),
                getInitialOpCodePosition(),
                executionContext,
                result);
    }

    /**
     * Execute the XPath from the provided context.
     *
     * The current node must already be set execution context,
     * and must not be 0.
     *
     * @param executionContext current execution context
     * @param prefixResolver prefix resolver to use
     * @param result the numeric result
     */
    void
    execute(
            const PrefixResolver&   prefixResolver,
            XPathExecutionContext&  executionContext,
            double&                 result) const
    {
        assert(executionContext.getCurrentNode() != 0);

        // Push and pop the PrefixResolver...
        const PrefixResolverSetAndRestore   theResolverSetAndRestore(
                                                executionContext,
                                                &prefixResolver);

        executeMore(
                executionContext.getCurrentNode(),
                getInitialOpCodePosition(),
                executionContext,
                result);
    }

    /**
     * Execute the XPath from the provided context. The
     * result is appended to the supplied string.
     *
     * The current node must already be set execution context,
     * and must not be 0.
     *
     * @param executionContext current execution context
     * @param prefixResolver prefix resolver to use
     * @param result the string result
     */
    void
    execute(
            const PrefixResolver&   prefixResolver,
            XPathExecutionContext&  executionContext,
            XalanDOMString&         result) const
    {
        assert(executionContext.getCurrentNode() != 0);

        // Push and pop the PrefixResolver...
        const PrefixResolverSetAndRestore   theResolverSetAndRestore(
                                                executionContext,
                                                &prefixResolver);

        executeMore(
                executionContext.getCurrentNode(),
                getInitialOpCodePosition(),
                executionContext,
                result);
    }

    /**
     * Execute the XPath from the provided context.
     *
     * @param prefixResolver   prefix resolver to use
     * @param executionContext current execution context
     * @param formatterListener the FormatterListener instance to receive the result
     * @param function A pointer to the member function of FormatterListener to call
     */
    void
    execute(
            const PrefixResolver&   prefixResolver,
            XPathExecutionContext&  executionContext,
            FormatterListener&      formatterListener,
            MemberFunctionPtr       function) const
    {
        assert(executionContext.getCurrentNode() != 0);

        // Push and pop the PrefixResolver...
        const PrefixResolverSetAndRestore   theResolverSetAndRestore(
                                                executionContext,
                                                &prefixResolver);

        executeMore(
                executionContext.getCurrentNode(),
                getInitialOpCodePosition(),
                executionContext,
                formatterListener,
                function);
    }

    /**
     * Execute the XPath from the provided context.  Normally,
     * the expression will be evaluated and the result placed
     * in the parameter result.  However, some cases (such as
     * the evalution of a variable) could result in the copying
     * of a node-set, which is extremely expensive.  In that
     * case, the return value will contain the result of the
     * evaluation.  If the call to XObject::null() on the return
     * value is true, that indicates the value was executed
     * directly into the parameter.  Otherwise, the parameter
     * will be empty, and the result will be in the XObject
     * instance returned.
     *
     * The current node must already be set execution context,
     * and must not be 0.
     *
     * @param executionContext current execution context
     * @param prefixResolver prefix resolver to use
     * @param result A node list for the result.  This may or may not contain the actual result.
     * @return the node-set result, if the result was not returned in the parameter
     */
    XObjectPtr
    execute(
            const PrefixResolver&   prefixResolver,
            XPathExecutionContext&  executionContext,
            MutableNodeRefList&     result) const
    {
        assert(executionContext.getCurrentNode() != 0);

        // Push and pop the PrefixResolver...
        const PrefixResolverSetAndRestore   theResolverSetAndRestore(
                                                executionContext,
                                                &prefixResolver);

        return executeMore(
                executionContext.getCurrentNode(),
                getInitialOpCodePosition(),
                executionContext,
                result);
    }

    /**
     * Retrieve a reference to the current expression.
     * 
     * @return current expression
     */
    XPathExpression&
    getExpression()
    {
        return m_expression;
    }

    /**
     * Retrieve a reference to the current expression.
     * 
     * @return current expression
     */
    const XPathExpression&
    getExpression() const
    {
        return m_expression;
    }

    static double
    getMatchScoreValue(eMatchScore  score)
    {
        switch(score)
        {
        case eMatchScoreNone:
            return DoubleSupport::getNegativeInfinity();
            break;

        case eMatchScoreNodeTest:
            return -0.5;
            break;

        case eMatchScoreNSWild:
            return -0.25;
            break;

        case eMatchScoreOther:
            return 0.5;
            break;

        case eMatchScoreQName:
            return 0.0;
            break;
        };

        assert(false);
        return 0.0;
    }

    /**
     * Get the match score for the specified node.
     *
     * @param node The node for the score
     * @param executionContext current execution context
     * @return union of node-set operands
     */
    eMatchScore
    getMatchScore(
            XalanNode*              node,
            XPathExecutionContext&  executionContext) const;

    /**
     * Get the match score for the specified node.
     *
     * @param node The node for the score
     * @param resolver The prefix resolver
     * @param executionContext current execution context
     * @return union of node-set operands
     */
    eMatchScore
    getMatchScore(
            XalanNode*              node,
            const PrefixResolver&   resolver,
            XPathExecutionContext&  executionContext) const;

    /**
     * Evaluate a predicate.
     *
     * @param context          current source tree context node
     * @param opPos            current position in the Op Map
     * @param executionContext current execution context
     * @return pointer to either a boolean or a number
     */
    const XObjectPtr
    predicate(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const
    {
        return executeMore(context, opPos + 2, executionContext);
    }

    /**
     * Add the data for the target of match pattern to a vector.
     * 
     * @param targetData The vector for the data
     */
    void
    getTargetData(TargetDataVectorType&     targetData) const;

    /**
     * Install a built-in function.
     *
     * @param funcName  unqualified name of the function
     * @param func      instance of an XPath function object
     */
    static void
    installFunction(
            const XalanDOMString&   funcName,
            const Function&         func)
    {
        s_functions.InstallFunction(funcName,
                                    func);
    }

    /**
     * Install a built-in function.
     *
     * @param funcName  unqualified name of the function
     * @param func      instance of an XPath function object
     */
    static void
    installFunction(
            const XalanDOMChar*     funcName,
            const Function&         func)
    {
        s_functions.InstallFunction(funcName,
                                    func);
    }

    /**
     * Remove a named function from the function table.
     * 
     * @param funcName name of function
     * @return true if the function was found and removed.
     */
    static bool
    uninstallFunction(const XalanDOMString&     funcName)
    {
        return s_functions.UninstallFunction(funcName);
    }

    /**
     * Remove a named function from the function table.
     * 
     * @param funcName name of function
     * @return true if the function was found and removed.
     */
    static bool
    uninstallFunction(const XalanDOMChar*   funcName)
    {
        return s_functions.UninstallFunction(funcName);
    }

    /**
     * Whether the named function is installed in the function table.
     * 
     * @param name of function
     * @return true if the function has been installed
     */
    static bool
    isInstalledFunction(const XalanDOMString&   theFunctionName)
    {
        return s_functions.isInstalledFunction(theFunctionName);
    }

    typedef XPathFunctionTable  FunctionTableType;

    /**
     * Retrieve the table of installed functions.
     * 
     * @return function table
     */
    static const FunctionTableType&
    getFunctionTable()
    {
        return s_functions;
    }

    /**
     * Add the names for the installed functions to a vector strings.
     * 
     * @param theIterator vector added to
     */
    template<class OutputIteratorType>
    static void
    getInstalledFunctionNames(OutputIteratorType    theIterator)
    {
        s_functions.getInstalledFunctionNames(theIterator);
    }

    static void
    destroyTable()
    {
        s_functions.DestroyTable();
    }

    bool
    getInStylesheet() const
    {
        return m_inStylesheet;
    }

    void
    setInStylesheet(bool    fValue)
    {
        m_inStylesheet = fValue;
    }

    const Locator*
    getLocator() const
    {
        return m_locator;
    }

    void
    setLocator(const Locator*   theLocator)
    {
        m_locator = theLocator;
    }

    class NodeTester
    {
    public:

        NodeTester();

        NodeTester(const NodeTester&    theSource);

        NodeTester(
            const XPath&            xpath,
            XPathExecutionContext&  executionContext,
            OpCodeMapPositionType   opPos,
            OpCodeMapValueType      argLen,
            OpCodeMapValueType      stepType);

        NodeTester(
            XPathConstructionContext&   theContext,
            const XalanDOMString&       theNameTest,
            const PrefixResolver&       thePrefixResolver,
            const Locator*          theLocator = 0,
            eMatchScore*                theMatchScore = 0);

        NodeTester(
            const XalanDOMString&   theNamespaceURI,
            const XalanDOMString&   theLocalName,
            eMatchScore*            theMatchScore = 0);

        eMatchScore
        operator()(
            const XalanNode&        context,
            XalanNode::NodeType     nodeType) const
        {
            assert(context.getNodeType() == nodeType);

            return (this->*m_testFunction)(context, nodeType);
        }

        eMatchScore
        operator()(const XalanElement&  context) const
        {
            return (this->*m_testFunction2)(context);
        }

        NodeTester&
        operator=(const NodeTester&     theRHS)
        {
            m_executionContext = theRHS.m_executionContext;
            m_targetNamespace = theRHS.m_targetNamespace;
            m_targetLocalName = theRHS.m_targetLocalName;
            m_testFunction = theRHS.m_testFunction;
            m_testFunction2 = theRHS.m_testFunction2;

            return *this;
        }

    protected:

        eMatchScore
        initialize(
            XPathConstructionContext&   theConstructionContext,
            const XalanDOMString&       theNameTest,
            const PrefixResolver&       thePrefixResolver,
            const Locator*          theLocator);

        eMatchScore
        initialize(
            const XalanDOMString&   theNamespaceURI,
            const XalanDOMString&   theLocalName);

    private:


        typedef eMatchScore (NodeTester::*TestFunctionPtr)(const XalanNode&, XalanNode::NodeType) const;
        typedef eMatchScore (NodeTester::*TestFunctionPtr2)(const XalanElement&) const;


        eMatchScore
        testComment(
            const XalanNode&        context,
            XalanNode::NodeType     nodeType) const;

        eMatchScore
        testText(
            const XalanNode&        context,
            XalanNode::NodeType     nodeType) const;

        eMatchScore
        testPI(
            const XalanNode&        context,
            XalanNode::NodeType     nodeType) const;

        eMatchScore
        testPIName(
            const XalanNode&        context,
            XalanNode::NodeType     nodeType) const;

        eMatchScore
        testNode(
            const XalanNode&        context,
            XalanNode::NodeType     nodeType) const;

        eMatchScore
        testRoot(
            const XalanNode&        context,
            XalanNode::NodeType     nodeType) const;

        eMatchScore
        testAttributeNCName(
            const XalanNode&        context,
            XalanNode::NodeType     nodeType) const;

        eMatchScore
        testAttributeQName(
            const XalanNode&        context,
            XalanNode::NodeType     nodeType) const;

        eMatchScore
        testAttributeNamespaceOnly(
            const XalanNode&        context,
            XalanNode::NodeType     nodeType) const;

        eMatchScore
        testAttributeTotallyWild(
            const XalanNode&        context,
            XalanNode::NodeType     nodeType) const;

        eMatchScore
        testElementNCName(
            const XalanNode&        context,
            XalanNode::NodeType     nodeType) const;

        eMatchScore
        testElementQName(
            const XalanNode&        context,
            XalanNode::NodeType     nodeType) const;

        eMatchScore
        testElementNamespaceOnly(
            const XalanNode&        context,
            XalanNode::NodeType     nodeType) const;

        eMatchScore
        testElementTotallyWild(
            const XalanNode&        context,
            XalanNode::NodeType     nodeType) const;

        eMatchScore
        testElementNCName2(const XalanElement&  context) const;

        eMatchScore
        testElementQName2(const XalanElement&   context) const;

        eMatchScore
        testElementNamespaceOnly2(const XalanElement&   context) const;

        eMatchScore
        testElementTotallyWild2(const XalanElement&     context) const;

        eMatchScore
        testNamespaceNCName(
            const XalanNode&        context,
            XalanNode::NodeType     nodeType) const;

        eMatchScore
        testNamespaceTotallyWild(
            const XalanNode&        context,
            XalanNode::NodeType     nodeType) const;

        eMatchScore
        testDefault(
            const XalanNode&        context,
            XalanNode::NodeType     nodeType) const;

        eMatchScore
        testDefault2(const XalanElement&    context) const;

        bool
        matchLocalName(const XalanNode&     context) const;

        bool
        matchNamespaceURI(const XalanNode&  context) const;

        bool
        matchLocalNameAndNamespaceURI(const XalanNode&  context) const;

        bool
        matchNamespace(const XalanNode&     context) const;

        bool
        shouldStripSourceNode(const XalanText&  context) const;

        // Data members...
        XPathExecutionContext*  m_executionContext;

        const XalanDOMString*   m_targetNamespace;

        const XalanDOMString*   m_targetLocalName;

        TestFunctionPtr         m_testFunction;

        TestFunctionPtr2        m_testFunction2;
    };

    friend class NodeTester;

protected:

    /**
     * Execute a location path.
     *
     * @param context          current source tree context node
     * @param opPos            current position in the Op Mpa
     * @param executionContext current execution context
     * @return node-set
     */
    const XObjectPtr
    locationPath(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Execute a location path.
     *
     * @param context          current source tree context node
     * @param opPos            current position in the Op Map
     * @param executionContext current execution context
     * @param theResult        the result as a node list
     */
    void
    locationPath(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            bool&                   theResult) const;

    /**
     * Execute a location path.
     *
     * @param context          current source tree context node
     * @param opPos            current position in the Op Map
     * @param executionContext current execution context
     * @param theResult        the result as a node list
     */
    void
    locationPath(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            double&                 theResult) const;

    /**
     * Execute a location path.
     *
     * @param context          current source tree context node
     * @param opPos            current position in the Op Map
     * @param executionContext current execution context
     * @param theResult        the result as a node list
     */
    void
    locationPath(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            XalanDOMString&         theResult) const;

    /**
     * Execute a location path.
     *
     * @param context          current source tree context node
     * @param opPos            current position in the Op Map
     * @param executionContext current execution context
     * @param formatterListener the FormatterListener instance to receive the result
     * @param function A pointer to the member function of FormatterListener to call
     */
    void
    locationPath(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            FormatterListener&      formatterListener,
            MemberFunctionPtr       function) const;

    /**
     * Execute a location path.
     *
     * @param context          current source tree context node
     * @param opPos            current position in the Op Map
     * @param executionContext current execution context
     * @param theResult        the result as a node list
     */
    void
    locationPath(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            MutableNodeRefList&     theResult) const
    {
        step(executionContext, context, opPos + 2, theResult);
    }

    /**
     * Execute the XPath from the provided context.
     *
     * @param context          current source tree context node
     * @param opPos            current position in the Op Map
     * @param executionContext current execution context
     * @return pointer to union of node-set operands
     */
    const XObjectPtr
    executeMore(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Execute the XPath from the provided context.
     *
     * @param context          current source tree context node
     * @param opPos            current position in the Op Map
     * @param executionContext current execution context
     * @param theResult        The result of the execution
     */
    void
    executeMore(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            bool&                   theResult) const;

    /**
     * Execute the XPath from the provided context.
     *
     * @param context          current source tree context node
     * @param opPos            current position in the Op Map
     * @param executionContext current execution context
     * @param theResult        The result of the execution
     */
    void
    executeMore(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            double&                 theResult) const;

    /**
     * Execute the XPath from the provided context.  The result
     * is appended to the supplied string.
     *
     * @param context          current source tree context node
     * @param opPos            current position in the Op Map
     * @param executionContext current execution context
     * @param theResult        The result of the execution
     */
    void
    executeMore(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            XalanDOMString&         theResult) const;

    /**
     * Execute the XPath from the provided context.
     *
     * @param context          current source tree context node
     * @param opPos            current position in the Op Map
     * @param executionContext current execution context
     * @param formatterListener the FormatterListener instance to receive the result
     * @param function A pointer to the member function of FormatterListener to call
     */
    void
    executeMore(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            FormatterListener&      formatterListener,
            MemberFunctionPtr       function) const;

    /**
     * Execute the XPath from the provided context.
     *
     * @param context          current source tree context node
     * @param opPos            current position in the Op Map
     * @param executionContext current execution context
     * @param theResult        The result of the execution
     * @return the node-set result, if the result was not returned in the parameter
     */
    const XObjectPtr
    executeMore(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            MutableNodeRefList&     theResult) const;

    /**
     * Helper function to get match score.
     * @param context The current source tree context node.
     * @param executionContext The current execution context
     * @param score The match score
     */
    void
    doGetMatchScore(
            XalanNode*              context,
            XPathExecutionContext&  executionContext,
            eMatchScore&            score) const;

    /**
     * OR two expressions and return the boolean result.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return true if the one of the two arguments are true.
     */
    bool
    Or(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * OR two expressions and return the boolean result.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return true if the two arguments are both true.
     */
    bool
    And(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Tell if two expressions are functionally not equal.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return true if the two arguments are not equal.
     */
    bool
    notequals(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Tell if two expressions are functionally equal.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return true if the two arguments are equal.
     */
    bool
    equals(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Tell if one argument is less than or equal to the other argument.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return true if arg 1 is less than or equal to arg 2.
     */
    bool
    lte(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Tell if one argument is less than the other argument.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return true if arg 1 is less than arg 2.
     */
    bool
    lt(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Tell if one argument is greater than or equal to the other argument.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return true if arg 1 is greater than or equal to arg 2.
     */
    bool
    gte(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Tell if one argument is greater than the other argument.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return true if arg 1 is greater than arg 2.
     */
    bool
    gt(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Give the sum of two arguments.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return sum of arg1 and arg2.
     */
    double
    plus(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Give the sum of two arguments.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @param formatterListener the FormatterListener instance to receive the result
     * @param function A pointer to the member function of FormatterListener to call
     */
    void
    plus(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            FormatterListener&      formatterListener,
            MemberFunctionPtr       function) const;

    /**
     * Give the difference of two arguments.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return difference of arg1 and arg2.
     */
    double
    minus(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Give the difference of two arguments.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @param formatterListener the FormatterListener instance to receive the result
     * @param function A pointer to the member function of FormatterListener to call
     */
    void
    minus(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            FormatterListener&      formatterListener,
            MemberFunctionPtr       function) const;

    /**
     * Multiply two arguments.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return arg1 * arg2.
     */
    double
    mult(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Multiply two arguments.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @param formatterListener the FormatterListener instance to receive the result
     * @param function A pointer to the member function of FormatterListener to call
     */
    void
    mult(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            FormatterListener&      formatterListener,
            MemberFunctionPtr       function) const;

    /**
     * Divide a number.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return arg1 / arg2.
     */
    double
    div(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Divide a number.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @param formatterListener the FormatterListener instance to receive the result
     * @param function A pointer to the member function of FormatterListener to call
     */
    void
    div(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            FormatterListener&      formatterListener,
            MemberFunctionPtr       function) const;

    /**
     * Return the remainder from a truncating division.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return arg1 mod arg2.
     */
    double
    mod(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Return the remainder from a truncating division.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @param formatterListener the FormatterListener instance to receive the result
     * @param function A pointer to the member function of FormatterListener to call
     */
    void
    mod(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            FormatterListener&      formatterListener,
            MemberFunctionPtr       function) const;

    /**
     * Return the negation of a number.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return -arg.
     */
    double
    neg(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Return the negation of a number.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @param formatterListener the FormatterListener instance to receive the result
     * @param function A pointer to the member function of FormatterListener to call
     */
    void
    neg(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            FormatterListener&      formatterListener,
            MemberFunctionPtr       function) const;

    /**
     * Computes the union of its operands which must be node-sets.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return the union of node-set operands.
     */
    const XObjectPtr
    Union(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Computes the union of its operands which must be node-sets.
     *
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @result the result of the union of node-set operands.
     */
    void
    Union(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            bool&                   result) const;

    /**
     * Computes the union of its operands which must be node-sets.
     *
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @result the result of the union of node-set operands.
     */
    void
    Union(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            double&                 result) const;

    /**
     * Computes the union of its operands which must be node-sets.
     *
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @result the result of the union of node-set operands.
     */
    void
    Union(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            XalanDOMString&         result) const;

    /**
     * Computes the union of its operands which must be node-sets.
     *
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @param formatterListener the FormatterListener instance to receive the result
     * @param function A pointer to the member function of FormatterListener to call
     */
    void
    Union(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            FormatterListener&      formatterListener,
            MemberFunctionPtr       function) const;

    /**
     * Computes the union of its operands which must be node-sets.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @result the result of the union of node-set operands.
     */
    void
    Union(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            MutableNodeRefList&     result) const;

    /**
     * Get a literal value.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return an XObject object.
     */
    const XObjectPtr
    literal(
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;
  
    /**
     * Get a literal value as a boolean.
     *
     * @param opPos The current position in the Op Map.
     * @param theResult The value.
     */
    void
    literal(
            OpCodeMapPositionType   opPos,
            bool&                   theResult) const;

    /**
     * Get a literal value as a number.
     *
     * @param opPos The current position in the Op Map.
     * @param theResult The value.
     */
    void
    literal(
            OpCodeMapPositionType   opPos,
            double&                 theResult) const;

    /**
     * Get a literal value.  The value is appended to the
     * supplied string.
     *
     * @param opPos The current position in the Op Map.
     * @param theResult The string.
     */
    void
    literal(
            OpCodeMapPositionType   opPos,
            XalanDOMString&         theResult) const;

    /**
     * Get a literal value.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return The result as a double.
     */
    void
    literal(
            OpCodeMapPositionType   opPos,
            FormatterListener&      formatterListener,
            MemberFunctionPtr       function) const;

    /**
     * Get the value of a variable.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return an XObject object.
     */
    const XObjectPtr
    variable(
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Execute an expression as a group.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return arg.
     */
    const XObjectPtr
    group(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const
    {
        return executeMore(context, opPos + 2, executionContext);
    }

    /**
     * Execute an expression as a group.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @param theResult The result of the execution
     */
    void
    group(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            bool&                   theResult) const
    {
        executeMore(context, opPos + 2, executionContext, theResult);
    }

    /**
     * Execute an expression as a group.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @param theResult The result of the execution
     */
    void
    group(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            double&                 theResult) const
    {
        executeMore(context, opPos + 2, executionContext, theResult);
    }

    /**
     * Execute an expression as a group.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @param theResult The result of the execution
     */
    void
    group(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            XalanDOMString&         theResult) const
    {
        executeMore(context, opPos + 2, executionContext, theResult);
    }

    /**
     * Execute an expression as a group.
     *
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @param formatterListener the FormatterListener instance to receive the result
     * @param function A pointer to the member function of FormatterListener to call
     */
    void
    group(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            FormatterListener&      formatterListener,
            MemberFunctionPtr       function) const
    {
        executeMore(
            context,
            opPos + 2,
            executionContext,
            formatterListener,
            function);
    }

    /**
     * Execute an expression as a group.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @param theResult The result of the execution
     */
    void
    group(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext,
            MutableNodeRefList&     theResult) const
    {
        const XObjectPtr    theValue(executeMore(
                                        context,
                                        opPos + 2,
                                        executionContext,
                                        theResult));

        if (theValue.null() == false)
        {
            theResult.addNodesInDocOrder(
                theValue->nodeset(),
                executionContext);

            theResult.setDocumentOrder();
        }
    }

    /**
     * Get a literal value.
     * @param opPos The current position in the Op Map.
     * @return The result as a double.
     */
    double
    numberlit(OpCodeMapPositionType     opPos) const;

    /**
     * Get a literal value.
     * @param opPos The current position in the Op Map.
     * @return The result as a double.
     */
    const XObjectPtr
    numberlit(
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Get a literal value as a boolean.
     *
     * @param opPos The current position in the Op Map.
     * @param theResult The string.
     */
    void
    numberlit(
            OpCodeMapPositionType   opPos,
            bool&                   theResult) const;

    /**
     * Get a literal value.  The value is appended to the
     * supplied string.
     *
     * @param opPos The current position in the Op Map.
     * @param theResult The string.
     */
    void
    numberlit(
            OpCodeMapPositionType   opPos,
            XalanDOMString&         theResult) const;

    /**
     * Get a literal value.
     *
     * @param opPos The current position in the Op Map.
     * @param formatterListener the FormatterListener instance to receive the result
     * @param function A pointer to the member function of FormatterListener to call
     */
    void
    numberlit(
            OpCodeMapPositionType   opPos,
            FormatterListener&      formatterListener,
            MemberFunctionPtr       function) const;

    /**
     * Setup for and run an extension function.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return the result of the function.
     */
    const XObjectPtr
    runExtFunction(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Handle an extension function.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param theNamespace The namespace of the function.
     * @param functionName The name of the function.
     * @param executionContext current execution context
     * @return the result of the function.
     */
    const XObjectPtr
    extfunction(
            XalanNode*                              context,
            OpCodeMapPositionType                   /* opPos */,
            const XalanDOMString&                   theNamespace,
            const XalanDOMString&                   functionName, 
            const Function::XObjectArgVectorType&   argVec,
            XPathExecutionContext&                  executionContext) const
    {
        return  executionContext.extFunction(theNamespace,
                                             functionName,
                                             context,
                                             argVec,
                                             m_locator);
    }

    /**
     * Setup for and run a function.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return the result of the function.
     */
    const XObjectPtr
    runFunction(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Handle a built-in function.
     * @param context The current source tree context node.
     * @param funcID The function ID.
     * @param argVec The arguments for the function.
     * @param executionContext current execution context
     * @return the result of the function.
     */
    const XObjectPtr
    function(
            XalanNode*                              context,
            OpCodeMapValueType                      funcID,
            const Function::XObjectArgVectorType&   argVec,
            XPathExecutionContext&                  executionContext) const
    {
        return s_functions[funcID].execute(executionContext, context, argVec, m_locator);
    }

    /**
     * Handle the built-in function "position".
     *
     * @param context The current source tree context node, which must not be 0.
     * @param executionContext current execution context
     * @return the result of the function.
     */
    double
    functionPosition(
            XalanNode*              context,
            XPathExecutionContext&  executionContext) const
    {
        assert(context != 0);

        const XPathExecutionContext::size_type  theResult =
            executionContext.getContextNodeListPosition(*context);
        assert(static_cast<double>(theResult) == theResult);

        return static_cast<double>(theResult);
    }

    /**
     * Handle the built-in function "last".
     *
     * @param executionContext current execution context
     * @return the result of the function.
     */
    double
    functionLast(XPathExecutionContext&     executionContext) const
    {
        const XPathExecutionContext::size_type  theResult =
            executionContext.getContextNodeListLength();
        assert(static_cast<double>(theResult) == theResult);

        return static_cast<double>(theResult);
    }

    /**
     * Handle the built-in function "count".
     *
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return the result of the function.
     */
    double
    functionCount(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Handle the built-in function "not".
     *
     * @param context The current source tree context node, which must not be 0.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return the result of the function.
     */
    bool
    functionNot(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const
    {
        assert(context != 0);

        return !functionBoolean(context, opPos, executionContext);
    }

    /**
     * Handle the built-in function "boolean".
     *
     * @param context The current source tree context node, which must not be 0.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return the result of the function.
     */
    bool
    functionBoolean(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const
    {
        assert(context != 0);

        bool    result;

        executeMore(context, opPos + 2, executionContext, result);

        return result;
    }

    /**
     * Handle the built-in function "name".
     *
     * @param context The current source tree context node, which must not be 0.
     * @return the result of the function.
     */
    const XalanDOMString&
    functionName(XalanNode*     context) const
    {
        assert(context != 0);

        return DOMServices::getNameOfNode(*context);
    }

    /**
     * Handle the built-in function "name".
     *
     * @param context The current source tree context node, which must not be 0.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return the result of the function.
     */
    const XalanDOMString&
    functionName(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Handle the built-in function "local-name".
     *
     * @param context The current source tree context node, which must not be 0.
     * @return the result of the function.
     */
    const XalanDOMString&
    functionLocalName(XalanNode*    context) const;

    /**
     * Handle the built-in function "local-name".
     *
     * @param context The current source tree context node, which must not be 0.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return the result of the function.
     */
    const XalanDOMString&
    functionLocalName(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Handle the built-in function "number".
     *
     * @param context The current source tree context node, which must not be 0.
     * @param executionContext current execution context
     * @return the result of the function.
     */
    double
    functionNumber(
            XalanNode*              context,
            XPathExecutionContext&  executionContext) const
    {
        assert(context != 0);

        return XObject::number(executionContext, *context);
    }

    /**
     * Handle the built-in function "number".
     *
     * @param context The current source tree context node, which must not be 0.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return the result of the function.
     */
    double
    functionNumber(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const
    {
        double  result;

        executeMore(context, opPos + 2, executionContext, result);

        return result;
    }

    /**
     * Handle the built-in function "floor".
     *
     * @param context The current source tree context node, which must not be 0.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return the result of the function.
     */
    double
    functionFloor(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const
    {
        return DoubleSupport::floor(functionNumber(context, opPos, executionContext));
    }

    /**
     * Handle the built-in function "ceiling".
     *
     * @param context The current source tree context node, which must not be 0.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return the result of the function.
     */
    double
    functionCeiling(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const
    {
        return DoubleSupport::ceiling(functionNumber(context, opPos, executionContext));
    }

    /**
     * Handle the built-in function "round".
     *
     * @param context The current source tree context node, which must not be 0.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return the result of the function.
     */
    double
    functionRound(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const
    {
        return DoubleSupport::round(functionNumber(context, opPos, executionContext));
    }

    /**
     * Handle the built-in function "string-length".
     *
     * @param context The current source tree context node, which must not be 0.
     * @param executionContext current execution context
     * @return the result of the function.
     */
    double
    functionStringLength(
            XalanNode*              context,
            XPathExecutionContext&  executionContext) const;

    /**
     * Handle the built-in function "string-length".
     *
     * @param context The current source tree context node, which must not be 0.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return the result of the function.
     */
    double
    functionStringLength(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Handle the built-in function "sum".
     *
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return the result of the function.
     */
    double
    functionSum(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

    /**
     * Get a numeric operand for an expression.
     * @param context The current source tree context node.
     * @param opPos The current position in the Op Map.
     * @param executionContext current execution context
     * @return The value of the operand.
     */
    double
    getNumericOperand(
            XalanNode*              context,
            OpCodeMapPositionType   opPos,
            XPathExecutionContext&  executionContext) const;

private:

    // These are not implemented...
    XPath(const XPath&);

    XPath&
    operator=(const XPath&);

    bool
    operator==(const XPath&) const;

    // Default vector allocation sizes.
    enum
    {
        eDefaultTargetDataSize = 5
    };

    OpCodeMapPositionType
    getInitialOpCodePosition() const
    {
#if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS)
        assert(m_expression.getOpCodeMapValue(0) == XPathExpression::eOP_XPATH);
#else
        assert(m_expression.getOpCodeMapValue(
                    m_expression.getInitialOpCodePosition()) == XPathExpression::eOP_XPATH);
#endif
        return m_expression.getInitialOpCodePosition() + 2;
    }

    eMatchScore
    locationPathPattern(
            XPathExecutionContext&  executionContext,
            XalanNode&              context, 
            OpCodeMapPositionType   opPos) const;

protected:

    /**
     * Execute a step in a location path.
     *
     * @param xpath The xpath that is executing
     * @param context The current source tree context node
     * @param opPos The current position in the xpath operation map array
     * @param queryResults The set of nodes that matches the step.
     */
    void
    step(
            XPathExecutionContext&  executionContext,
            XalanNode*              context, 
            OpCodeMapPositionType   opPos,
            MutableNodeRefList&     queryResults) const;

    /**
     * Potentially evaluate a predicate in a match pattern step.
     *
     * @param executionContext The current execution context.
     * @param context          The current source tree context node.
     * @param opPos            The current position in the Op Map.
     * @param startOpPos       The original position for the step in the Op Map.
     * @param score            The current match score for the context node.
     * @return The resulting match score
     */
    eMatchScore
    doStepPredicate(
            XPathExecutionContext&  executionContext,
            XalanNode*              context, 
            OpCodeMapPositionType   opPos,
            OpCodeMapPositionType   startOpPos,
            eMatchScore             score) const;

    /**
     * Execute a step in a match pattern's location path.
     *
     * @param xpath The xpath that is executing
     * @param context The current source tree context node
     * @param opPos The current position in the xpath operation map array
     * @param scoreHolder a reference to an eMatchScore to receive
     * the result.
     * @return the last matched context node
     */
    XalanNode*
    stepPattern(
            XPathExecutionContext&  executionContext,
            XalanNode*              context, 
            OpCodeMapPositionType   opPos,
            eMatchScore&            scoreHolder) const;

    OpCodeMapPositionType
    findNodeSet(
            XPathExecutionContext&  executionContext,
            XalanNode*              context, 
            OpCodeMapPositionType   opPos,
            OpCodeMapValueType      stepType,
            MutableNodeRefList&     subQueryResults) const;

    OpCodeMapPositionType
    findRoot(
            XPathExecutionContext&  executionContext,
            XalanNode*              context, 
            OpCodeMapPositionType   opPos,
            OpCodeMapValueType      stepType,
            MutableNodeRefList&     subQueryResults) const;

    OpCodeMapPositionType
    findParent(
            XPathExecutionContext&  executionContext,
            XalanNode*              context, 
            OpCodeMapPositionType   opPos,
            OpCodeMapValueType      stepType,
            MutableNodeRefList&     subQueryResults) const;

    OpCodeMapPositionType
    findSelf(
            XPathExecutionContext&  executionContext,
            XalanNode*              context, 
            OpCodeMapPositionType   opPos,
            OpCodeMapValueType      stepType,
            MutableNodeRefList&     subQueryResults) const;

    OpCodeMapPositionType
    findAncestors(
            XPathExecutionContext&  executionContext,
            XalanNode*              context, 
            OpCodeMapPositionType   opPos,
            OpCodeMapValueType      stepType,
            MutableNodeRefList&     subQueryResults) const;

    OpCodeMapPositionType
    findAncestorsOrSelf(
            XPathExecutionContext&  executionContext,
            XalanNode*              context, 
            OpCodeMapPositionType   opPos,
            OpCodeMapValueType      stepType,
            MutableNodeRefList&     subQueryResults) const;

    OpCodeMapPositionType
    findAttributes(
            XPathExecutionContext&  executionContext,
            XalanNode*              context, 
            OpCodeMapPositionType   opPos,
            OpCodeMapValueType      stepType,
            MutableNodeRefList&     subQueryResults) const;

    OpCodeMapPositionType
    findChildren(
            XPathExecutionContext&  executionContext,
            XalanNode*              context, 
            OpCodeMapPositionType   opPos,
            OpCodeMapValueType      stepType,
            MutableNodeRefList&     subQueryResults) const;

    OpCodeMapPositionType
    findDescendants(
            XPathExecutionContext&  executionContext,
            XalanNode*              context, 
            OpCodeMapPositionType   opPos,
            OpCodeMapValueType      stepType,
            MutableNodeRefList&     subQueryResults) const;

    OpCodeMapPositionType
    findFollowing(
            XPathExecutionContext&  executionContext,
            XalanNode*              context, 
            OpCodeMapPositionType   opPos,
            OpCodeMapValueType      stepType,
            MutableNodeRefList&     subQueryResults) const;

    OpCodeMapPositionType
    findFollowingSiblings(
            XPathExecutionContext&  executionContext,
            XalanNode*              context, 
            OpCodeMapPositionType   opPos,
            OpCodeMapValueType      stepType,
            MutableNodeRefList&     subQueryResults) const;

    OpCodeMapPositionType
    findPreceeding(
            XPathExecutionContext&  executionContext,
            XalanNode*              context, 
            OpCodeMapPositionType   opPos,
            OpCodeMapValueType      stepType,
            MutableNodeRefList&     subQueryResults) const;

    OpCodeMapPositionType
    findPreceedingSiblings(
            XPathExecutionContext&  executionContext,
            XalanNode*              context, 
            OpCodeMapPositionType   opPos,
            OpCodeMapValueType      stepType,
            MutableNodeRefList&     subQueryResults) const;

    OpCodeMapPositionType
    findNamespace(
            XPathExecutionContext&  executionContext,
            XalanNode*              context, 
            OpCodeMapPositionType   opPos,
            OpCodeMapValueType      stepType,
            MutableNodeRefList&     subQueryResults) const;

    OpCodeMapPositionType
    findNodesOnUnknownAxis(
            XPathExecutionContext&  executionContext,
            XalanNode*              context, 
            OpCodeMapPositionType   opPos,
            OpCodeMapValueType      stepType,
            MutableNodeRefList&     subQueryResults) const;

    OpCodeMapPositionType
    predicates(
            XPathExecutionContext&  executionContext,
            OpCodeMapPositionType   opPos,
            MutableNodeRefList&     subQueryResults) const;

    eMatchScore
    handleFoundIndex(
            XPathExecutionContext&  executionContext,
            XalanNode*              localContext,
            OpCodeMapPositionType   startOpPos) const;

    eMatchScore
    handleFoundIndexPositional(
            XPathExecutionContext&  executionContext,
            XalanNode*              localContext,
            OpCodeMapPositionType   startOpPos) const;

private:

    void
    unknownOpCodeError(
            XalanNode*              context,
            XPathExecutionContext&  executionContext,
            OpCodeMapPositionType   opPos) const;

    void
    notNodeSetError(
            XalanNode*              context,
            XPathExecutionContext&  executionContext) const;

    // Data members...

    /**
     *
     * Holds information about the current expression.
     *
     */
    XPathExpression     m_expression;

    /**
     * A Locator for reporting errors.
     */
    const Locator*      m_locator;

    /**
     * If true, the XPath can allocated XObjects in more
     * efficient ways, since its lifetime is guaranteed
     * to be at least that of the transformation.
     */
    bool                m_inStylesheet;

    /**
     *
     * This is the table of installed functions.
     *
     */
    static FunctionTableType        s_functions;

    static const XalanDOMString     s_emptyString;
};



}



#endif  // XPATH_HEADER_GUARD_1357924680
