/*
 * 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.
 */

// Class header file...
#include "XPathProcessorImpl.hpp"



#include <xercesc/sax/Locator.hpp>



#include <xalanc/PlatformSupport/DOMStringHelper.hpp>
#include <xalanc/PlatformSupport/DOMStringPrintWriter.hpp>
#include <xalanc/PlatformSupport/DoubleSupport.hpp>
#include <xalanc/PlatformSupport/PrefixResolver.hpp>
#include <xalanc/PlatformSupport/XalanMessageLoader.hpp>
#include <xalanc/PlatformSupport/XalanUnicode.hpp>
#include <xalanc/PlatformSupport/XalanXMLChar.hpp>



#include <xalanc/DOMSupport/DOMServices.hpp>



#include "XalanQName.hpp"
#include "XPathEnvSupport.hpp"
#include "XPathFunctionTable.hpp"
#include "XPathConstructionContext.hpp"
#include "XPathExecutionContext.hpp"
#include "XPathParserException.hpp"



namespace XALAN_CPP_NAMESPACE {



XPathProcessorImpl::XPathProcessorImpl(MemoryManager&   theManager) :
    m_token(theManager),
    m_tokenChar(0),
    m_xpath(0),
    m_constructionContext(0),
    m_expression(0),
    m_prefixResolver(0),
    m_requireLiterals(false),
    m_isMatchPattern(false),
    m_positionPredicateStack(theManager),
    m_namespaces(theManager),
    m_allowVariableReferences(true),
    m_allowKeyFunction(true)
{
}



XPathProcessorImpl*
XPathProcessorImpl::create(MemoryManager&   theManager)
{
    typedef XPathProcessorImpl ThisType;

    XalanAllocationGuard    theGuard(theManager, theManager.allocate(sizeof(ThisType)));

    ThisType* const     theResult =
        new (theGuard.get()) ThisType(theManager);

    theGuard.release();

    return theResult;
}



XPathProcessorImpl::~XPathProcessorImpl()
{
}



void
XPathProcessorImpl::initXPath(
            XPath&                      pathObj,
            XPathConstructionContext&   constructionContext,
            const XalanDOMString&       expression,
            const PrefixResolver&       resolver,
            const Locator*              locator,
            bool                        allowVariableReferences,
            bool                        allowKeyFunction)
{
    m_isMatchPattern = false;

    m_requireLiterals = false;

    m_allowVariableReferences = allowVariableReferences;

    m_allowKeyFunction = allowKeyFunction;

    m_xpath = &pathObj;

    m_constructionContext = &constructionContext;

    m_expression = &m_xpath->getExpression();

    m_prefixResolver = &resolver;

    m_locator = locator;

    m_expression->reset();

    tokenize(expression);

    m_expression->appendOpCode(XPathExpression::eOP_XPATH);

    nextToken();

    Expr();

    if (m_token.empty() == false)
    {
        error(XalanMessages::ExtraIllegalTokens);
    }

    m_xpath = 0;
    m_constructionContext = 0;
    m_expression = 0;
    m_prefixResolver = 0;
    m_locator = 0;
    m_positionPredicateStack.clear();
    m_namespaces.clear();
}



void
XPathProcessorImpl::initMatchPattern(
            XPath&                      pathObj,
            XPathConstructionContext&   constructionContext,
            const XalanDOMString&       expression,
            const PrefixResolver&       resolver,
            const Locator*              locator,
            bool                        allowVariableReferences,
            bool                        allowKeyFunction)
{
    m_isMatchPattern = true;

    m_allowVariableReferences = allowVariableReferences;

    m_allowKeyFunction = allowKeyFunction;

    m_xpath = &pathObj;

    m_constructionContext = &constructionContext;

    m_expression = &m_xpath->getExpression();

    m_prefixResolver = &resolver;

    m_locator = locator;

    m_expression->reset();

    tokenize(expression);

    m_expression->appendOpCode(XPathExpression::eOP_MATCHPATTERN);

    nextToken();

    Pattern();

    if (m_token.empty() == false)
    {
        error(XalanMessages::ExtraIllegalTokens);
    }

    // Terminate for safety.
    m_expression->appendOpCode(XPathExpression::eENDOP);

    m_expression->shrink();

    m_xpath = 0;
    m_constructionContext = 0;
    m_expression = 0;
    m_prefixResolver = 0;
    m_locator = 0;
    m_positionPredicateStack.clear();
    m_namespaces.clear();
}



void
XPathProcessorImpl::tokenize(const XalanDOMString&  pat)
{
    assert(m_xpath != 0);
    assert(m_expression != 0);
    assert(m_constructionContext != 0);

    m_expression->setCurrentPattern(m_constructionContext->getPooledString(pat));

    const t_size_type   nChars = pat.length();

    t_size_type     startSubstring = XalanDOMString::npos;
    t_size_type     posOfNSSep = XalanDOMString::npos;

    const XPathConstructionContext::GetCachedString     theGuard(*m_constructionContext);

    XalanDOMString&     theToken = theGuard.get();

    for(t_size_type i = 0; i < nChars; i++)
    {
        XalanDOMChar    c = pat[i];

        switch(c)
        {
        case XalanUnicode::charQuoteMark: 
            {
                if(startSubstring != XalanDOMString::npos)
                {
                    if(XalanDOMString::npos != posOfNSSep)
                    {      
                        posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, i);
                    }
                    else
                    {
                        substring(pat, theToken, startSubstring, i);

                        addToTokenQueue(theToken);
                    }
                }

                startSubstring = i;

                for(++i; i < nChars && (c = pat[i]) != XalanUnicode::charQuoteMark; ++i);

                if(c == XalanUnicode::charQuoteMark && i < nChars)
                {
                    substring(pat, theToken, startSubstring, i + 1);

                    addToTokenQueue(theToken);

                    startSubstring = XalanDOMString::npos;
                }
                else
                {
                    error(XalanMessages::UnterminatedStringLiteral);
                }
            }
            break;

        case XalanUnicode::charApostrophe:
            {
                if(startSubstring != XalanDOMString::npos)
                {
                    if(XalanDOMString::npos != posOfNSSep)
                    {    
                        posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, i);
                    }
                    else
                    {
                        substring(pat, theToken, startSubstring, i);

                        addToTokenQueue(theToken);
                    }
                }

                startSubstring = i;

                for(++i; i < nChars && (c = pat[i]) != XalanUnicode::charApostrophe; ++i);

                if(c == XalanUnicode::charApostrophe && i < nChars)
                {
                    substring(pat, theToken, startSubstring, i + 1);

                    addToTokenQueue(theToken);

                    startSubstring = XalanDOMString::npos;
                }
                else
                {
                    error(XalanMessages::UnterminatedStringLiteral);
                }
            }
            break;
        
        case XalanUnicode::charLF:
        case XalanUnicode::charCR:
        case XalanUnicode::charSpace:
        case XalanUnicode::charHTab:
            {
                if(startSubstring != XalanDOMString::npos)
                {
                    if(XalanDOMString::npos != posOfNSSep)
                    {    
                        posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, i);
                    }
                    else
                    {
                        substring(pat, theToken, startSubstring, i);

                        addToTokenQueue(theToken);
                    }

                    startSubstring = XalanDOMString::npos;
                }
            }
            break;
        
        case XalanUnicode::charHyphenMinus:
            {
                if(!(startSubstring == XalanDOMString::npos))
                {
                    break;
                }
            }
            // fall-through on purpose

        case XalanUnicode::charCommercialAt:
        case XalanUnicode::charLeftParenthesis:
        case XalanUnicode::charLeftSquareBracket:
        case XalanUnicode::charRightParenthesis:
        case XalanUnicode::charRightSquareBracket:
        case XalanUnicode::charVerticalLine:
        case XalanUnicode::charSolidus:
        case XalanUnicode::charAsterisk:
        case XalanUnicode::charPlusSign:
        case XalanUnicode::charEqualsSign:
        case XalanUnicode::charComma:
        case XalanUnicode::charReverseSolidus: // Unused at the moment
        case XalanUnicode::charCircumflexAccent: // Unused at the moment
        case XalanUnicode::charExclamationMark: // Unused at the moment
        case XalanUnicode::charDollarSign:
        case XalanUnicode::charLessThanSign:
        case XalanUnicode::charGreaterThanSign:
            {
                if(startSubstring != XalanDOMString::npos)
                {
                    if(XalanDOMString::npos != posOfNSSep)
                    {    
                        posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, i);
                    }
                    else
                    {
                        substring(pat, theToken, startSubstring, i);

                        addToTokenQueue(theToken);
                    }

                    startSubstring = XalanDOMString::npos;
                }

                substring(pat, theToken, i, i + 1);

                addToTokenQueue(theToken);
            }       
            break;

        case XalanUnicode::charColon:
            {
                if(posOfNSSep == i - 1 && i > 0)
                { 
                    if(startSubstring != XalanDOMString::npos)
                    {
                        if (startSubstring < i - 1)
                        {
                            substring(pat, theToken, startSubstring, i - 1);

                            addToTokenQueue(theToken);
                        }
                    }

                    startSubstring = XalanDOMString::npos;
                    posOfNSSep = XalanDOMString::npos;

                    substring(pat, theToken, i - 1, i + 1);

                    addToTokenQueue(theToken);
                    break;
                }
                else
                {
                    posOfNSSep = i;
                }
            }
            // fall through on purpose

        
        default:
            {
                if(XalanDOMString::npos == startSubstring)
                {
                    startSubstring = i;

                    if (XalanXMLChar::isDigit(c) == true)
                    {
                        bool    gotFullStop = false;

                        while(i < nChars - 1)
                        {
                            ++i;

                            const XalanDOMChar  currentChar = pat[i];

                            if (currentChar == XalanUnicode::charFullStop)
                            {
                                if (gotFullStop == false)
                                {
                                    gotFullStop = true;
                                }
                                else
                                {
                                    --i;

                                    break;
                                }
                            }
                            else if (XalanXMLChar::isDigit(currentChar) == false)
                            {
                                --i;

                                break;
                            }
                        }

                        substring(pat, theToken, startSubstring, i + 1);

                        addToTokenQueue(theToken);

                        startSubstring = XalanDOMString::npos;
                    }
                }
            }
        }
    }

    if(startSubstring != XalanDOMString::npos)
    {
        if(XalanDOMString::npos != posOfNSSep)
        {    
            posOfNSSep = mapNSTokens(pat, startSubstring, posOfNSSep, nChars);
        }
        else
        {
            substring(pat, theToken, startSubstring, nChars);

            addToTokenQueue(theToken);
        }
    }

    if (0 == m_expression->tokenQueueSize())
    {
        error(XalanMessages::EmptyExpression);

    }

    m_expression->resetTokenPosition();
}



void
XPathProcessorImpl::addToTokenQueue(const XalanDOMString&   s) const
{
    assert(m_xpath != 0);
    assert(m_expression != 0);

    m_expression->pushToken(m_constructionContext->getPooledString(s));
}



void
XPathProcessorImpl::replaceTokenWithNamespaceToken() const
{
    assert(m_xpath != 0);
    assert(m_expression != 0);
    assert(m_token.empty() == false);

    StringToStringMapType::const_iterator   i = m_namespaces.find(m_token);
    assert(i != m_namespaces.end());

    const XalanDOMString* const     theNamespaceURI = (*i).second;
    assert(theNamespaceURI != 0 && theNamespaceURI->empty() == false);

    m_expression->replaceRelativeToken(
            1,
            XPathExpression::eRelativeBackward,
            m_constructionContext->getPooledString(*theNamespaceURI));
}



XPathProcessorImpl::t_size_type
XPathProcessorImpl::mapNSTokens(
            const XalanDOMString&   pat,
            t_size_type             startSubstring,
            t_size_type             posOfNSSep,
            t_size_type             posOfScan)
{
    assert(m_prefixResolver != 0);

    const XPathConstructionContext::GetCachedString     theGuard(*m_constructionContext);

    XalanDOMString&     scratchString = theGuard.get();

    // Get the prefix of the QName...
    scratchString.assign(pat, startSubstring, posOfNSSep - startSubstring);

    if (XalanQName::isValidNCName(scratchString) == false)
    {
        error(
            XalanMessages::IsNotValidNCName_1Param,
            scratchString);

    }

    const XalanDOMString* const     uName =
                m_prefixResolver->getNamespaceForPrefix(scratchString);

    if(uName == 0)
    {
        error(
            XalanMessages::PrefixIsNotDeclared_1Param,
            scratchString);
    }
    else if (uName->empty() == true)
    {
        error(
            XalanMessages::PrefixIsBoundToZeroLengthURI_1Param,
            scratchString);
    }
    else
    {
        m_namespaces[scratchString] = uName;

        addToTokenQueue(scratchString);

        addToTokenQueue(DOMServices::s_XMLNamespaceSeparatorString);

        // If there's no local part, then don't bother.  We need to check
        // this because '*' tokenizes separately, which means "ns:*" tokenizes
        // differently from "ns:foo".  In the first case, '*' will be tokenized
        // _after_ this code, in the second 'ns:foo' will be split into tokens
        // here...
        if(posOfNSSep + 1 < posOfScan)
        {
            scratchString.assign(pat, posOfNSSep + 1, posOfScan - (posOfNSSep + 1));

            assert(scratchString.empty() == false);

            if (XalanQName::isValidNCName(scratchString) == false)
            {
                error(
                    XalanMessages::NotValidNCName_1Param,
                    scratchString);
            }
            else
            {
                addToTokenQueue(scratchString);
            }
        }
    }

    return XalanDOMString::npos;
}



bool
XPathProcessorImpl::tokenIs(const XalanDOMString&   s) const
{
    return equals(m_token, s);
}



bool
XPathProcessorImpl::tokenIs(const XalanDOMChar*     s) const
{
    return equals(m_token, s);
}



bool
XPathProcessorImpl::tokenIs(XalanDOMChar    c) const
{
    return m_tokenChar == c ? true : false;
}



bool
XPathProcessorImpl::lookahead(
            XalanDOMChar    c,
            int             n) const
{
    const XalanDOMString&   tok =
        getTokenRelative(n - 1);

    if (tok.length() == 1 &&
        tok[0] == c)
    {
        return true;
    }
    else
    {
        return false;
    }
}



bool
XPathProcessorImpl::lookahead(
            const XalanDOMChar*     s,
            int                     n) const
{
    assert(s != 0);

    const XalanDOMString&   tok =
        getTokenRelative(n - 1);

    return equals(tok, s);
}



bool
XPathProcessorImpl::lookahead(
            const XalanDOMString&   s,
            int                     n) const
{
    const XalanDOMString&   tok =
        getTokenRelative(n - 1);

    return equals(tok, s);
}



bool
XPathProcessorImpl::lookbehind(
            char    c,
            int     n) const
{
    const XalanDOMString&   tok =
        getTokenRelative(-(n + 1));

    if (tok.length() == 1 &&
        tok[0] == c)
    {
        return true;
    }
    else
    {
        return false;
    }
}



bool
XPathProcessorImpl::lookbehindHasToken(int  n) const
{
    const XalanDOMString&   tok =
        getTokenRelative(-(n + 1));

    const XalanDOMChar      c0 = tok.length() == 0 ?
        XalanUnicode::charVerticalLine : tok[0];

    return c0 == XalanUnicode::charVerticalLine ? false : true;
}



bool
XPathProcessorImpl::nextToken()
{
    assert(m_expression != 0);

    const XToken* const     theNextToken =
            m_expression->getNextToken();

    if (theNextToken == 0)
    {
        m_token.clear();
    }
    else
    {
        m_token = theNextToken->str();
    }

    if(m_token.empty() == false)
    {
        m_tokenChar = m_token[0];

        return true;
    }
    else
    {
        m_tokenChar = 0;

        return false;
    }
}



void
XPathProcessorImpl::prevToken()
{
    assert(m_expression != 0);

    const XToken* const     thePreviousToken =
            m_expression->getPreviousToken();

    m_token = thePreviousToken == 0 ? s_emptyString : thePreviousToken->str();

    if(m_token.empty() == false)
    {
        m_tokenChar = m_token[0];
    }
    else
    {
        m_tokenChar = 0;
    }
}



const XalanDOMString&
XPathProcessorImpl::getTokenRelative(int    theOffset) const
{
    assert(m_expression != 0);

    const XToken*   theToken = 0;

    if (theOffset < 0)
    {
        theToken = 
            m_expression->getRelativeToken(
                    XPathExpression::TokenQueueSizeType(-theOffset),
                    XPathExpression::eRelativeBackward);
    }
    else
    {
        theToken =
            m_expression->getRelativeToken(
                    XPathExpression::TokenQueueSizeType(theOffset),
                    XPathExpression::eRelativeForward);
    }

    return theToken == 0 ? s_emptyString : theToken->str();
}



void
XPathProcessorImpl::consumeExpected(XalanDOMChar    expected)
{
    if(tokenIs(expected) == true)
    {
        nextToken();
    }
    else
    {
        error(
            XalanMessages::NotFoundWhatExpected_2Param,
            expected,
            m_token);
    }
}



typedef XPathConstructionContext::GetCachedString   GetCachedString;



void
XPathProcessorImpl::error(const XalanDOMString&     msg) const
{
    assert(m_constructionContext != 0);

    const GetCachedString   theGuard(*m_constructionContext);

    XalanDOMString&     emsg = theGuard.get();

    if (m_expression == 0)
    {
        emsg = msg;
    }
    else
    {
        const XalanDOMString&   theCurrentPattern =
                m_expression->getCurrentPattern();

        DOMStringPrintWriter    thePrintWriter(emsg);

        thePrintWriter.print(msg);

        thePrintWriter.println();

        if (theCurrentPattern.empty() == false)
        {
            const GetCachedString   theGuard(*m_constructionContext);

            XalanDOMString&     theResult = theGuard.get();

            const XalanMessages::Codes  theCode =
                            m_isMatchPattern == true ?
                                XalanMessages::PatternIs_1Param :
                                XalanMessages::ExpressionIs_1Param;

            thePrintWriter.print(
                XalanMessageLoader::getMessage(
                    theResult,
                    theCode,
                    theCurrentPattern));
        }

        // Back up one token, since we've consumed one...
        m_expression->getPreviousToken();

        // Ask the expression to dump the remaining tokens...
        m_expression->dumpRemainingTokenQueue(thePrintWriter);
    }

    m_constructionContext->problem(
        XPathConstructionContext::eXPath,
        XPathConstructionContext::eError,
        emsg,
        m_locator,
        0);

    throw XPathParserException(
                emsg, 
                m_constructionContext->getMemoryManager(),
                m_locator);
}



void
XPathProcessorImpl::error(XalanMessages::Codes  theCode) const
{
    assert(m_constructionContext != 0);

    const GetCachedString   theGuard(*m_constructionContext);

    error(
            XalanMessageLoader::getMessage(
                theGuard.get(),
                theCode));
}



void
XPathProcessorImpl::error(
            XalanMessages::Codes    theCode,
            const XalanDOMString&   theToken) const
{
    assert(m_constructionContext != 0);

    const GetCachedString   theGuard(*m_constructionContext);

    error(
            XalanMessageLoader::getMessage(
                theGuard.get(),
                theCode,
                theToken));
}



void
XPathProcessorImpl::error(
            XalanMessages::Codes    theCode,
            const XalanDOMChar*     theToken) const
{
    assert(m_constructionContext != 0);

    const GetCachedString   theGuard(*m_constructionContext);

    error(
            XalanMessageLoader::getMessage(
                theGuard.get(),
                theCode,
                theToken));
}



void
XPathProcessorImpl::error(
            XalanMessages::Codes    theCode,
            XalanDOMChar            theToken1,
            const XalanDOMString&   theToken2) const
{
    assert(m_constructionContext != 0);

    const GetCachedString   theGuard(*m_constructionContext);

    XalanDOMString&     theResult = theGuard.get();

    error(
            XalanMessageLoader::getMessage(
                theResult,
                theCode,
                XalanDOMString(1, theToken1, theResult.getMemoryManager()),
                theToken2));
}



void
XPathProcessorImpl::Expr()
{
    OrExpr();
}



void
XPathProcessorImpl::OrExpr()
{
    const int   opPos = m_expression->opCodeMapLength();

    AndExpr();

    if(tokenIs(s_orString) == true)
    {
        if (nextToken() == false)
        {
            error(XalanMessages::ExpectedToken);
        }
        else
        {
            m_expression->insertOpCode(
                XPathExpression::eOP_OR,
                opPos);

            OrExpr();

            m_expression->updateOpCodeLength(
                XPathExpression::eOP_OR,
                opPos);
        }
    }
}



void
XPathProcessorImpl::AndExpr() 
{
    const int   opPos = m_expression->opCodeMapLength();

    EqualityExpr();

    if(tokenIs(s_andString) == true)
    {
        if (nextToken() == false)
        {
            error(XalanMessages::ExpectedToken);
        }
        else
        {
            m_expression->insertOpCode(
                XPathExpression::eOP_AND,
                opPos);

            AndExpr();

            m_expression->updateOpCodeLength(
                XPathExpression::eOP_AND,
                opPos);
        }
    }
}



int
XPathProcessorImpl::EqualityExpr(int    opCodePos)
{
    int         theOpDisplacement = 0;

    const int   opPos = opCodePos != -1 ? opCodePos : m_expression->opCodeMapLength();

    RelationalExpr();

    XPathExpression::eOpCodes   theOpCode =
            XPathExpression::eENDOP;

    bool    foundToken = false;

    if(tokenIs(XalanUnicode::charExclamationMark) &&
       lookahead(XalanUnicode::charEqualsSign, 1))
    {
        nextToken();

        foundToken = nextToken();

        theOpCode = XPathExpression::eOP_NOTEQUALS;
    }
    else if(tokenIs(XalanUnicode::charEqualsSign))
    {
        foundToken = nextToken();

        theOpCode = XPathExpression::eOP_EQUALS;
    }

    if (theOpCode != XPathExpression::eENDOP)
    {
        if (foundToken == false)
        {
            error(XalanMessages::ExpectedToken);
        }
        else
        {
            // Save the number of bytes we inserted
            // into the map.
            const int   theLocalDisplacement =
                    m_expression->insertOpCode(theOpCode,
                                               opPos);

            // Update the length
            m_expression->updateOpCodeLength(theOpCode,
                                             opPos);

            // Do the right term of the expression.
            theOpDisplacement += EqualityExpr(opPos);

            // If there's any displacement from the right
            // term, update the length for a shift. Otherwise,
            // just update the length.
            if (theOpDisplacement > 0)
            {
                m_expression->updateShiftedOpCodeLength(
                    theOpCode,
                    opPos,
                    opPos + theOpDisplacement);
            }
            else
            {
                m_expression->updateOpCodeLength(
                    theOpCode,
                    opPos);
            }

            // Accumulate the displacement.
            theOpDisplacement += theLocalDisplacement;
        }
    }

    return theOpDisplacement;
}



int
XPathProcessorImpl::RelationalExpr(int  opCodePos)
{
    int         theOpDisplacement = 0;

    const int   opPos = opCodePos != -1 ? opCodePos : m_expression->opCodeMapLength();

    AdditiveExpr();

    if(m_token.empty() == false)
    {
        bool    foundToken = false;

        XPathExpression::eOpCodes   theOpCode =
            XPathExpression::eENDOP;

        if(tokenIs(XalanUnicode::charLessThanSign) == true)
        {
            foundToken = nextToken();

            if(tokenIs(XalanUnicode::charEqualsSign) == true)
            {
                foundToken = nextToken();

                theOpCode = XPathExpression::eOP_LTE;
            }
            else
            {
                theOpCode = XPathExpression::eOP_LT;
            }
        }
        else if(tokenIs(XalanUnicode::charGreaterThanSign) == true)
        {
            foundToken = nextToken();

            if(tokenIs(XalanUnicode::charEqualsSign) == true)
            {
                foundToken = nextToken();

                theOpCode = XPathExpression::eOP_GTE;
            }
            else
            {
                theOpCode = XPathExpression::eOP_GT;
            }
        }

        if (theOpCode != XPathExpression::eENDOP)
        {
            if (foundToken == false)
            {
                error(XalanMessages::ExpectedToken);
            }
            else
            {
                // Save the number of bytes we inserted
                // into the map.
                const int   theLocalDisplacement =
                    m_expression->insertOpCode(theOpCode,
                                               opPos);

                // Update the length
                m_expression->updateOpCodeLength(theOpCode,
                                                 opPos);

                // Do the right term of the expression.
                theOpDisplacement += RelationalExpr(opPos);

                // If there's any displacement from the right
                // term, update the length for a shift. Otherwise,
                // just update the length.
                if (theOpDisplacement > 0)
                {
                    m_expression->updateShiftedOpCodeLength(
                        theOpCode,
                        opPos,
                        opPos + theOpDisplacement);
                }
                else
                {
                    m_expression->updateOpCodeLength(
                        theOpCode,
                        opPos);
                }

                // Accumulate the displacement.
                theOpDisplacement += theLocalDisplacement;
            }
        }
    }

    return theOpDisplacement;
}



int
XPathProcessorImpl::AdditiveExpr(int    opCodePos)
{
    int         theOpDisplacement = 0;

    const int   opPos = opCodePos != -1 ? opCodePos : m_expression->opCodeMapLength();

    MultiplicativeExpr();

    if(m_token.empty() == false)
    {
        XPathExpression::eOpCodes   theOpCode =
            XPathExpression::eENDOP;

        if(tokenIs(XalanUnicode::charPlusSign) == true)
        {
            theOpCode = XPathExpression::eOP_PLUS;
        }
        else if(tokenIs(XalanUnicode::charHyphenMinus) == true)
        {
            theOpCode = XPathExpression::eOP_MINUS;
        }

        if (theOpCode != XPathExpression::eENDOP)
        {
            if (nextToken() == false)
            {
                error(XalanMessages::ExpectedToken);
            }
            else
            {
                // Save the number of bytes we inserted
                // into the map.
                const int   theLocalDisplacement =
                    m_expression->insertOpCode(theOpCode,
                                               opPos);

            // Update the length
            m_expression->updateOpCodeLength(theOpCode,
                                             opPos);

            // Do the right term of the expression.
            theOpDisplacement += AdditiveExpr(opPos);

                // If there's any displacement from the right
                // term, update the length for a shift. Otherwise,
                // just update the length.
                if (theOpDisplacement > 0)
                {
                    m_expression->updateShiftedOpCodeLength(
                        theOpCode,
                        opPos,
                        opPos + theOpDisplacement);
                }
                else
                {
                    m_expression->updateOpCodeLength(
                        theOpCode,
                        opPos);
                }

            // Accumulate the displacement.
            theOpDisplacement += theLocalDisplacement;
        }
    }
    }

    return theOpDisplacement;
}



int
XPathProcessorImpl::MultiplicativeExpr(int  opCodePos)
{
    int         theOpDisplacement = 0;

    const int   opPos = opCodePos != -1 ? opCodePos : m_expression->opCodeMapLength();

    UnaryExpr();

    if(m_token.empty() == false)
    {
        XPathExpression::eOpCodes   theOpCode =
            XPathExpression::eENDOP;

        if(tokenIs(XalanUnicode::charAsterisk) == true)
        {
            theOpCode = XPathExpression::eOP_MULT;
        }
        else if(tokenIs(s_divString) == true)
        {
            theOpCode = XPathExpression::eOP_DIV;
        }
        else if(tokenIs(s_modString) == true)
        {
            theOpCode = XPathExpression::eOP_MOD;
        }

        if (theOpCode != XPathExpression::eENDOP)
        {
            if (nextToken() == false)
            {
                error(XalanMessages::ExpectedToken);
            }
            else
            {
                // Save the number of bytes we inserted
                // into the map.
                const int   theLocalDisplacement =
                    m_expression->insertOpCode(theOpCode,
                                               opPos);

                // Update the length
                m_expression->updateOpCodeLength(theOpCode,
                                                 opPos);

            // Do the right term of the expression.
            theOpDisplacement += MultiplicativeExpr(opPos);

                // If there's any displacement from the right
                // term, update the length for a shift. Otherwise,
                // just update the length.
                if (theOpDisplacement > 0)
                {
                    m_expression->updateShiftedOpCodeLength(
                        theOpCode,
                        opPos,
                        opPos + theOpDisplacement);
                }
                else
                {
                    m_expression->updateOpCodeLength(
                        theOpCode,
                        opPos);
                }

            // Accumulate the displacement.
            theOpDisplacement += theLocalDisplacement;
        }
    }
    }

    return theOpDisplacement;
}



void
XPathProcessorImpl::UnaryExpr()
{
    const int   opPos = m_expression->opCodeMapLength();

    bool        isNeg = false;

    if(tokenIs(XalanUnicode::charHyphenMinus) == true)
    {
        nextToken();

        m_expression->insertOpCode(XPathExpression::eOP_NEG,
                                   opPos);

        isNeg = true;
    }

    UnionExpr();

    if(isNeg == true)
    {
        m_expression->updateOpCodeLength(XPathExpression::eOP_NEG,
                                         opPos);
    }
}
  


void
XPathProcessorImpl::UnionExpr()
{
    const int   opPos = m_expression->opCodeMapLength();

    bool        continueOrLoop = true;
    bool        foundUnion = false;

    do 
    {
        PathExpr();

        if(tokenIs(XalanUnicode::charVerticalLine) == true)
        {
            if(false == foundUnion)
            {
                foundUnion = true;

                m_expression->insertOpCode(XPathExpression::eOP_UNION,
                                           opPos);
            }

            nextToken();
        }
        else
        {
            if (foundUnion == true)
            {
                // Terminate for safety.
                m_expression->appendOpCode(XPathExpression::eENDOP);
            }

            break;
        }
    }
    while(continueOrLoop == true);

    m_expression->updateOpCodeLength(opPos);
}

 

void
XPathProcessorImpl::PathExpr()
{
    assert(m_expression != 0);

    const int   opPos = m_expression->opCodeMapLength();

    FilterExpr();

    if(tokenIs(XalanUnicode::charSolidus) == true)
    {
        nextToken();

        m_expression->insertOpCode(
            XPathExpression::eOP_LOCATIONPATH,
            opPos);

        RelativeLocationPath();

        m_expression->appendOpCode(XPathExpression::eENDOP);

        m_expression->updateOpCodeLength(
            XPathExpression::eOP_LOCATIONPATH,
            opPos);
    }
}



void
XPathProcessorImpl::FilterExpr()
{
    assert(m_expression != 0);

    const int   opPos = m_expression->opCodeMapLength();

    //  const bool  isFunc = lookahead(XalanUnicode::charLeftParenthesis, 1);

    PrimaryExpr();

    if(tokenIs(XalanUnicode::charLeftSquareBracket) == true)
    {
        m_expression->insertOpCode(XPathExpression::eOP_LOCATIONPATH,
                                   opPos);
      
        while(tokenIs(XalanUnicode::charLeftSquareBracket) == true)
        {
            Predicate();
        }

        if(tokenIs(XalanUnicode::charSolidus) == true)
        {
            nextToken();

            RelativeLocationPath();
        }

        // Terminate for safety.
        m_expression->appendOpCode(XPathExpression::eENDOP);

        m_expression->updateOpCodeLength(XPathExpression::eOP_LOCATIONPATH,
                                         opPos);
    }
}
  


void
XPathProcessorImpl::PrimaryExpr()
{
    assert(m_expression != 0);

    const int   opPos = m_expression->opCodeMapLength();

    if(tokenIs(XalanUnicode::charApostrophe) == true ||
       tokenIs(XalanUnicode::charQuoteMark) == true)
    {
        m_expression->appendOpCode(XPathExpression::eOP_LITERAL);

        Literal();

        m_expression->updateOpCodeLength(
            XPathExpression::eOP_LITERAL,
            opPos);
    }
    else if(tokenIs(XalanUnicode::charDollarSign) == true)
    {
        nextToken(); // consume '$'

        if (m_allowVariableReferences == false)
        {
            error(XalanMessages::VariableReferenceNotAllowed);
        }
        else
        {
            m_expression->appendOpCode(XPathExpression::eOP_VARIABLE);

            QName();

            m_expression->updateOpCodeLength(
                XPathExpression::eOP_VARIABLE,
                opPos);
        }
    }
    else if(tokenIs(XalanUnicode::charLeftParenthesis) == true)
    {
        nextToken();

        m_expression->appendOpCode(XPathExpression::eOP_GROUP);

        Expr();

        consumeExpected(XalanUnicode::charRightParenthesis);

        m_expression->updateOpCodeLength(
            XPathExpression::eOP_GROUP,
            opPos);
    }
    else if((tokenIs(XalanUnicode::charFullStop) == true &&
                m_token.length() > 1 &&
                XalanXMLChar::isDigit(m_token[1]) == true) ||
                XalanXMLChar::isDigit(m_tokenChar) == true)
    {
        m_expression->appendOpCode(XPathExpression::eOP_NUMBERLIT);

        Number();

        m_expression->updateOpCodeLength(
            XPathExpression::eOP_NUMBERLIT,
            opPos);
    }
    else if(lookahead(XalanUnicode::charLeftParenthesis, 1) == true ||
            (lookahead(XalanUnicode::charColon, 1) == true && lookahead(XalanUnicode::charLeftParenthesis, 3) == true))
    {
        FunctionCall();
    }
    else
    {
        LocationPath();
    }
}



void
XPathProcessorImpl::Argument()
{
    assert(m_expression != 0);

    if (m_requireLiterals == false ||
        isCurrentLiteral() == true)
    {
        Expr();
    }
    else
    {
        error(XalanMessages::LiteralArgumentIsRequired);
    }
}



int
XPathProcessorImpl::FunctionCallArguments()
{
    int     argCount = 0;

    consumeExpected(XalanUnicode::charLeftParenthesis);

    while(tokenIs(XalanUnicode::charRightParenthesis) == false &&
          m_token.empty() == false)
    {
        if(tokenIs(XalanUnicode::charComma) == true)
        {
            error(XalanMessages::NoPrecedingArgument);
        }

        Argument();

        ++argCount;

        if(tokenIs(XalanUnicode::charRightParenthesis) == false)
        {
            consumeExpected(XalanUnicode::charComma);

            if(tokenIs(XalanUnicode::charRightParenthesis) == true)
            {
                error(XalanMessages::NoFollowingArgument);
            }
        }
    }

    consumeExpected(XalanUnicode::charRightParenthesis);

    return argCount;
}



void
XPathProcessorImpl::FunctionCall()
{
    assert(m_expression != 0);

    const int   opPos = m_expression->opCodeMapLength();

    if(lookahead(XalanUnicode::charColon, 1) == true)
    {
        m_expression->appendOpCode(XPathExpression::eOP_EXTFUNCTION);

        XPathExpression::OpCodeMapValueVectorType   theArgs(2, 0, m_constructionContext->getMemoryManager());

        // Replace the token in the queue with the actual namespace URI...
        replaceTokenWithNamespaceToken();

        theArgs[0] = m_expression->getTokenPosition() - 1;

        nextToken();

        consumeExpected(XalanUnicode::charColon);

        theArgs[1] = m_expression->getTokenPosition() - 1;

        m_expression->setOpCodeArgs(XPathExpression::eOP_EXTFUNCTION,
                                    opPos,
                                    theArgs);

        nextToken();

        FunctionCallArguments();
    }
    else
    {
        if (isValidFunction(m_token) == false)
        {
            error(
                XalanMessages::CouldNotFindFunction_1Param,
                m_token);

        }

        const XPathExpression::eOpCodes     funcTok = getFunctionToken(m_token);

        switch(funcTok)
        {
        case XPathExpression::eNODETYPE_PI:
        case XPathExpression::eNODETYPE_COMMENT:
        case XPathExpression::eNODETYPE_TEXT:
        case XPathExpression::eNODETYPE_NODE:
            LocationPath();
            // ************** Nasty return here!!! *********************** //
            return;
            break;

        case XPathExpression::eOP_FUNCTION_POSITION:
            FunctionPosition();
            break;

        case XPathExpression::eOP_FUNCTION_LAST:
            FunctionLast();
            break;

        case XPathExpression::eOP_FUNCTION_COUNT:
            FunctionCount();
            break;

        case XPathExpression::eOP_FUNCTION_NOT:
            FunctionNot();
            break;

        case XPathExpression::eOP_FUNCTION_TRUE:
            FunctionTrue();
            break;

        case XPathExpression::eOP_FUNCTION_FALSE:
            FunctionFalse();
            break;

        case XPathExpression::eOP_FUNCTION_BOOLEAN:
            FunctionBoolean();
            break;

        case XPathExpression::eOP_FUNCTION_NAME_0:
            FunctionName(opPos);
            break;

        case XPathExpression::eOP_FUNCTION_LOCALNAME_0:
            FunctionLocalName(opPos);
            break;

        case XPathExpression::eOP_FUNCTION_NUMBER_0:
            FunctionNumber(opPos);
            break;

        case XPathExpression::eOP_FUNCTION_FLOOR:
            FunctionFloor();
            break;

        case XPathExpression::eOP_FUNCTION_CEILING:
            FunctionCeiling();
            break;

        case XPathExpression::eOP_FUNCTION_ROUND:
            FunctionRound();
            break;

        case XPathExpression::eOP_FUNCTION_STRINGLENGTH_0:
            FunctionStringLength(opPos);
            break;

        case XPathExpression::eOP_FUNCTION_SUM:
            FunctionSum();
            break;

        default:
            {
                // The position must be at least 1, since
                // we've looked at a token.
                assert(m_expression->getTokenPosition() > 0);

                if (m_allowKeyFunction == false &&
                    m_token == XPathFunctionTable::s_key)
                {
                    error(XalanMessages::KeyFunctionNotAllowed);
                }

                int     theFunctionID =
                    XPath::getFunctionTable().nameToID(m_token);

                if ((equals(m_token, s_positionString) == true ||
                     equals(m_token, s_lastString) == true) &&
                    m_positionPredicateStack.empty() == false)
                {
                    m_positionPredicateStack.back() = true;
                }

                XPathExpression::OpCodeMapValueVectorType   theArgs(2, 0, m_constructionContext->getMemoryManager());
        
                theArgs[0] = theFunctionID;
                theArgs[1] = 0;

                m_expression->appendOpCode(
                        XPathExpression::eOP_FUNCTION,
                        theArgs);

                nextToken();

                // Get the arguments, and the argument count...
                const int   argCount = FunctionCallArguments();

                assert(m_expression->getOpCodeMapValue(opPos + 3) == 0);

                // update the arg count in the op map...
                m_expression->setOpCodeMapValue(opPos + 3, argCount);
            }
        }
    }

    // Terminate for safety.
    m_expression->appendOpCode(XPathExpression::eENDOP);

    m_expression->updateOpCodeLength(opPos);
}



void
XPathProcessorImpl::FunctionPosition()
{
    m_expression->appendOpCode(XPathExpression::eOP_FUNCTION_POSITION);

    // Consume the name...
    nextToken();

    // Get the arguments, and the argument count...
    const int   argCount = FunctionCallArguments();

    if (argCount != 0)
    {
        XalanDOMString  theResult(m_constructionContext->getMemoryManager());

        error(
            XalanMessages::FunctionDoesNotAcceptAnyArguments_1Param,
            XPathFunctionTable::s_position);
    }
    else
    {
        if (m_positionPredicateStack.empty() == false)
        {
            m_positionPredicateStack.back() = true;
        }
    }
}



void
XPathProcessorImpl::FunctionLast()
{
    m_expression->appendOpCode(XPathExpression::eOP_FUNCTION_LAST);

    // Consume the name...
    nextToken();

    // Get the arguments, and the argument count...
    const int   argCount = FunctionCallArguments();

    if (argCount != 0)
    {
        error(
            XalanMessages::FunctionDoesNotAcceptAnyArguments_1Param,
            XPathFunctionTable::s_last);
    }
    else
    {
        if (m_positionPredicateStack.empty() == false)
        {
            m_positionPredicateStack.back() = true;
        }
    }
}



void
XPathProcessorImpl::FunctionCount()
{
    m_expression->appendOpCode(XPathExpression::eOP_FUNCTION_COUNT);

    // Consume the name...
    nextToken();

    // Get the arguments, and the argument count...
    const int   argCount = FunctionCallArguments();

    if (argCount != 1)
    {
        error(
            XalanMessages::FunctionAcceptsOneArgument_1Param,
            XPathFunctionTable::s_count);
    }
}



void
XPathProcessorImpl::FunctionNot()
{
    m_expression->appendOpCode(XPathExpression::eOP_FUNCTION_NOT);

    // Consume the name...
    nextToken();

    // Get the arguments, and the argument count...
    const int   argCount = FunctionCallArguments();

    if (argCount != 1)
    {
        error(
            XalanMessages::FunctionAcceptsOneArgument_1Param,
            XPathFunctionTable::s_not);
    }
}



void
XPathProcessorImpl::FunctionTrue()
{
    m_expression->appendOpCode(XPathExpression::eOP_FUNCTION_TRUE);

    // Consume the name...
    nextToken();

    // Get the arguments, and the argument count...
    const int   argCount = FunctionCallArguments();

    if (argCount != 0)
    {
        error(
            XalanMessages::FunctionDoesNotAcceptAnyArguments_1Param,
            XPathFunctionTable::s_true);
    }
}



void
XPathProcessorImpl::FunctionFalse()
{
    m_expression->appendOpCode(XPathExpression::eOP_FUNCTION_FALSE);

    // Consume the name...
    nextToken();

    // Get the arguments, and the argument count...
    const int   argCount = FunctionCallArguments();

    if (argCount != 0)
    {
        error(
            XalanMessages::FunctionDoesNotAcceptAnyArguments_1Param,
            XPathFunctionTable::s_false);
    }
}



void
XPathProcessorImpl::FunctionBoolean()
{
    m_expression->appendOpCode(XPathExpression::eOP_FUNCTION_BOOLEAN);

    // Consume the name...
    nextToken();

    // Get the arguments, and the argument count...
    const int   argCount = FunctionCallArguments();

    if (argCount != 1)
    {
        error(
            XalanMessages::FunctionAcceptsOneArgument_1Param,
            XPathFunctionTable::s_boolean);
    }
}



void
XPathProcessorImpl::FunctionName(int    opPos)
{
    m_expression->appendOpCode(XPathExpression::eOP_FUNCTION_NAME_0);

    // Consume the name...
    nextToken();

    // Get the arguments, and the argument count...
    const int   argCount = FunctionCallArguments();

    if (argCount != 0)
    {
        if (argCount == 1)
        {
            m_expression->replaceOpCode(
                opPos,
                XPathExpression::eOP_FUNCTION_NAME_0,
                XPathExpression::eOP_FUNCTION_NAME_1);
        }
        else
        {
            error(
                XalanMessages::FunctionTakesZeroOrOneArg_1Param,
                XPathFunctionTable::s_name);
        }
    }
}



void
XPathProcessorImpl::FunctionLocalName(int   opPos)
{
    m_expression->appendOpCode(XPathExpression::eOP_FUNCTION_LOCALNAME_0);

    // Consume the name...
    nextToken();

    // Get the arguments, and the argument count...
    const int   argCount = FunctionCallArguments();

    if (argCount != 0)
    {
        if (argCount == 1)
        {
            m_expression->replaceOpCode(
                opPos,
                XPathExpression::eOP_FUNCTION_LOCALNAME_0,
                XPathExpression::eOP_FUNCTION_LOCALNAME_1);
        }
        else
        {
            error(
                XalanMessages::FunctionTakesZeroOrOneArg_1Param,
                XPathFunctionTable::s_localName);
        }
    }
}



void
XPathProcessorImpl::FunctionNumber(int  opPos)
{
    m_expression->appendOpCode(XPathExpression::eOP_FUNCTION_NUMBER_0);

    // Consume the name...
    nextToken();

    // Get the arguments, and the argument count...
    const int   argCount = FunctionCallArguments();

    if (argCount != 0)
    {
        if (argCount == 1)
        {
            m_expression->replaceOpCode(
                opPos,
                XPathExpression::eOP_FUNCTION_NUMBER_0,
                XPathExpression::eOP_FUNCTION_NUMBER_1);
        }
        else
        {
            error(
                XalanMessages::FunctionTakesZeroOrOneArg_1Param,
                XPathFunctionTable::s_number);
        }
    }
}



void
XPathProcessorImpl::FunctionFloor()
{
    m_expression->appendOpCode(XPathExpression::eOP_FUNCTION_FLOOR);

    // Consume the name...
    nextToken();

    // Get the arguments, and the argument count...
    const int   argCount = FunctionCallArguments();

    if (argCount != 1)
    {
        error(
            XalanMessages::FunctionAcceptsOneArgument_1Param,
            XPathFunctionTable::s_floor);
    }
}



void
XPathProcessorImpl::FunctionCeiling()
{
    m_expression->appendOpCode(XPathExpression::eOP_FUNCTION_CEILING);

    // Consume the name...
    nextToken();

    // Get the arguments, and the argument count...
    const int   argCount = FunctionCallArguments();

    if (argCount != 1)
    {
        error(
            XalanMessages::FunctionAcceptsOneArgument_1Param,
            XPathFunctionTable::s_ceiling);
    }
}



void
XPathProcessorImpl::FunctionRound()
{
    m_expression->appendOpCode(XPathExpression::eOP_FUNCTION_ROUND);

    // Consume the name...
    nextToken();

    // Get the arguments, and the argument count...
    const int   argCount = FunctionCallArguments();

    if (argCount != 1)
    {
        error(
            XalanMessages::FunctionAcceptsOneArgument_1Param,
            XPathFunctionTable::s_round);
    }
}



void
XPathProcessorImpl::FunctionString(int  opPos)
{
    m_expression->appendOpCode(XPathExpression::eOP_FUNCTION_STRING_0);

    // Consume the name...
    nextToken();

    // Get the arguments, and the argument count...
    const int   argCount = FunctionCallArguments();

    if (argCount != 0)
    {
        if (argCount == 1)
        {
            m_expression->replaceOpCode(
                opPos,
                XPathExpression::eOP_FUNCTION_STRING_0,
                XPathExpression::eOP_FUNCTION_STRING_1);
        }
        else
        {
            error(
                XalanMessages::FunctionTakesZeroOrOneArg_1Param,
                XPathFunctionTable::s_string);
        }
    }
}



void
XPathProcessorImpl::FunctionSum()
{
    m_expression->appendOpCode(XPathExpression::eOP_FUNCTION_SUM);

    // Consume the name...
    nextToken();

    // Get the arguments, and the argument count...
    const int   argCount = FunctionCallArguments();

    if (argCount != 1)
    {
        error(
            XalanMessages::FunctionAcceptsOneArgument_1Param,
            XPathFunctionTable::s_sum);
    }
}



void
XPathProcessorImpl::FunctionStringLength(int    opPos)
{
    m_expression->appendOpCode(XPathExpression::eOP_FUNCTION_STRINGLENGTH_0);

    // Consume the name...
    nextToken();

    // Get the arguments, and the argument count...
    const int   argCount = FunctionCallArguments();

    if (argCount != 0)
    {
        if (argCount == 1)
        {
            m_expression->replaceOpCode(
                opPos,
                XPathExpression::eOP_FUNCTION_STRINGLENGTH_0,
                XPathExpression::eOP_FUNCTION_STRINGLENGTH_1);
        }
        else
        {
            error(
                XalanMessages::FunctionTakesZeroOrOneArg_1Param,
                XPathFunctionTable::s_stringLength);
        }
    }
}



void
XPathProcessorImpl::FunctionNamespaceURI(int    opPos)
{
    m_expression->appendOpCode(XPathExpression::eOP_FUNCTION_NAMESPACEURI_0);

    // Consume the name...
    nextToken();

    // Get the arguments, and the argument count...
    const int   argCount = FunctionCallArguments();

    if (argCount != 0)
    {
        if (argCount == 1)
        {
            m_expression->replaceOpCode(
                opPos,
                XPathExpression::eOP_FUNCTION_NAMESPACEURI_0,
                XPathExpression::eOP_FUNCTION_NAMESPACEURI_1);
        }
        else
        {
            error(
                XalanMessages::FunctionTakesZeroOrOneArg_1Param,
                XPathFunctionTable::s_namespaceUri);
        }
    }
}



void
XPathProcessorImpl::LocationPath()
{
    const int   opPos = m_expression->opCodeMapLength();

    m_expression->appendOpCode(XPathExpression::eOP_LOCATIONPATH);

    if(tokenIs(XalanUnicode::charSolidus) == true)
    {
        nextToken();

        const int   newOpPos = m_expression->opCodeMapLength();

        // Tell how long the step is without the predicate
        const XPathExpression::OpCodeMapValueVectorType     theArgs(1, 4, m_constructionContext->getMemoryManager());

        m_expression->appendOpCode(
            XPathExpression::eFROM_ROOT,
            theArgs);

        m_expression->appendOpCode(XPathExpression::eNODETYPE_ROOT);

        // Tell how long the entire step is.
        m_expression->updateOpCodeLength(newOpPos);
    }

    if(m_token.empty() == false)
    {
        RelativeLocationPath();
    }

    // Terminate for safety.
    m_expression->appendOpCode(XPathExpression::eENDOP);

    m_expression->updateOpCodeLength(XPathExpression::eOP_LOCATIONPATH,
                                     opPos);
}


  
void
XPathProcessorImpl::RelativeLocationPath()
{
    Step();

    while(tokenIs(XalanUnicode::charSolidus) == true)
    {
        nextToken();

        Step();
    }
}
  


void
XPathProcessorImpl::Step()
{
    const int   opPos = m_expression->opCodeMapLength();

    if(m_token.empty() == true)
    {
        error(XalanMessages::ExpectedNodeTest);
    }
    else if(tokenIs(s_dotString) == true)
    {
        nextToken();

        if(tokenIs(XalanUnicode::charLeftSquareBracket) == true)
        {
            error(XalanMessages::IllegalSyntaxOfPredicatesSelf);
        }

        const XPathExpression::OpCodeMapValueVectorType     theArgs(1, 4, m_constructionContext->getMemoryManager());

        m_expression->appendOpCode(XPathExpression::eFROM_SELF,
                                   theArgs);

        m_expression->appendOpCode(XPathExpression::eNODETYPE_NODE);

        // Tell how long the entire step is.
        m_expression->updateOpCodeLength(opPos);
    }
    else if(tokenIs(s_dotDotString) == true)
    {
        nextToken();

        if(tokenIs(XalanUnicode::charLeftSquareBracket) == true)
        {
            error(XalanMessages::IllegalSyntaxOfPredicatesParent);
        }

        // Tell how long the step is without the predicate
        const XPathExpression::OpCodeMapValueVectorType     theArgs(1, 4,m_constructionContext->getMemoryManager());

        m_expression->appendOpCode(XPathExpression::eFROM_PARENT,
                                   theArgs);

        m_expression->appendOpCode(XPathExpression::eNODETYPE_NODE);

        // Tell how long the entire step is.
        m_expression->updateOpCodeLength(opPos);
    }
    else if (tokenIs(XalanUnicode::charAsterisk) ||
             tokenIs(XalanUnicode::charCommercialAt) ||
             tokenIs(XalanUnicode::charSolidus) ||
             (tokenIs(XalanUnicode::charLowLine) ||
              XalanXMLChar::isLetter(m_token[0])))
    {
        Basis();

        while(tokenIs(XalanUnicode::charLeftSquareBracket) == true)
        {
            Predicate();
        }

        // Tell how long the entire step is.
        m_expression->updateOpCodeLength(opPos);
    }
    else if (tokenIs(XalanUnicode::charRightParenthesis) == false)
    {
        error(
            XalanMessages::UnexpectedTokenFound_1Param,
            m_token);
    }
}



void
XPathProcessorImpl::Basis()
{
    assert(m_xpath != 0);
    assert(m_expression != 0);

    const int   opPos = m_expression->opCodeMapLength();

    XPathExpression::eOpCodes   axisType = XPathExpression::eENDOP;

    // The next blocks guarantee that a FROM_XXX will be added.
    if(lookahead(s_axisString, 1) == true)
    {
        axisType = AxisName();

        nextToken();
        nextToken();
    }
    else if(tokenIs(XalanUnicode::charCommercialAt) == true)
    {
        axisType = XPathExpression::eFROM_ATTRIBUTES;

        m_expression->appendOpCode(XPathExpression::eFROM_ATTRIBUTES);

        nextToken();
    }
    else if(tokenIs(XalanUnicode::charSolidus) == true)
    {
        // Check the current token in the expression.  It's
        // actually the next token in this context.
        //
        const XalanDOMString&   theNextToken = getTokenRelative(0);

        if (isAxis(theNextToken) == false && isNodeTest(theNextToken) == false)
        {
            nextToken();

            error(XalanMessages::ExpectedAxis); 
        }
        else
        {
            // Tell how long the step is without the predicate
            const XPathExpression::OpCodeMapValueVectorType     theArgs(1, 4, m_constructionContext->getMemoryManager());

            m_expression->appendOpCode(XPathExpression::eFROM_DESCENDANTS_OR_SELF,
                                       theArgs);

            m_expression->appendOpCode(XPathExpression::eNODETYPE_NODE);

            // Tell how long the step is without the predicate
            m_expression->updateOpCodeLengthAfterNodeTest(opPos);

            return; // make a quick exit...
        }
    }
    else
    {
        axisType = XPathExpression::eFROM_CHILDREN;

        m_expression->appendOpCode(XPathExpression::eFROM_CHILDREN);
    }

    NodeTest();

    // Tell how long the step is without the predicate
    m_expression->updateOpCodeLengthAfterNodeTest(opPos);
}



XPathExpression::eOpCodes
XPathProcessorImpl::AxisName()
{
    assert(m_xpath != 0);
    assert(m_expression != 0);

    const XPathExpression::eOpCodes     theOpCode =
        getAxisToken(m_token);

    if (theOpCode == XPathExpression::eENDOP)
    {
        error(
            XalanMessages::IllegalAxisName_1Param,
            m_token); 
    }
    else
    {
        m_expression->appendOpCode(theOpCode);
    }

    return theOpCode;
}



int
XPathProcessorImpl::NodeTest()
{
    assert(m_xpath != 0);
    assert(m_expression != 0);

    int     nodeTestPos = -1;

    if (lookahead(XalanUnicode::charLeftParenthesis, 1) == true)
    {
        const XPathExpression::eOpCodes     theOpCode = getNodeTypeToken(m_token);

        if (theOpCode == XPathExpression::eENDOP)
        {
            error(
                XalanMessages::UnknownNodeType_1Param,
                m_token);
        }
        else
        {
            nextToken();

            nodeTestPos = m_expression->appendOpCode(theOpCode);

            consumeExpected(XalanUnicode::charLeftParenthesis);

            if(XPathExpression::eNODETYPE_PI == theOpCode)
            {
                if(tokenIs(XalanUnicode::charRightParenthesis) == false)
                {
                    Literal();
                }
            }

            consumeExpected(XalanUnicode::charRightParenthesis);
        }
    }
    else
    {
        // Assume name of attribute or element.
        m_expression->appendOpCode(XPathExpression::eNODENAME);

        if(lookahead(XalanUnicode::charColon, 1) == true)
        {
            if(tokenIs(XalanUnicode::charAsterisk) == true)
            {
                m_expression->appendOpCode(XPathExpression::eELEMWILDCARD);
            }
            else
            {
                // Replace the token in the queue with the actual namespace...
                replaceTokenWithNamespaceToken();

                m_expression->pushCurrentTokenOnOpCodeMap();
            }

            nextToken();

            consumeExpected(XalanUnicode::charColon);
        }
        else
        {
            m_expression->appendOpCode(XPathExpression::eEMPTY);
        }

        if (tokenIs(XalanUnicode::charAsterisk) == true)
        {
            m_expression->appendOpCode(XPathExpression::eELEMWILDCARD);
        }
        else if (isNodeTest(m_token) == false)
        {
            error(XalanMessages::ExpectedNodeTest);
        }
        else
        {
            m_expression->pushCurrentTokenOnOpCodeMap();
        }

        nextToken();
    }

    return nodeTestPos;
}



void
XPathProcessorImpl::Predicate()
{
    if(tokenIs(XalanUnicode::charLeftSquareBracket) == true)
    {
        nextToken();

        PredicateExpr();        

        consumeExpected(XalanUnicode::charRightSquareBracket);
    }
}



void
XPathProcessorImpl::PredicateExpr()
{
    assert(m_xpath != 0);
    assert(m_expression != 0);

    const int   opPos = m_expression->opCodeMapLength();

    m_expression->appendOpCode(XPathExpression::eOP_PREDICATE);

    m_positionPredicateStack.push_back(false);

    Expr();

    // Terminate for safety.
    m_expression->appendOpCode(XPathExpression::eENDOP);

    m_expression->updateOpCodeLength(XPathExpression::eOP_PREDICATE,
                                     opPos);

    assert(m_positionPredicateStack.empty() == false);

    if (m_positionPredicateStack.back() == true)
    {
        m_expression->replaceOpCode(
            opPos,
            XPathExpression::eOP_PREDICATE,
            XPathExpression::eOP_PREDICATE_WITH_POSITION);
    }

    m_positionPredicateStack.pop_back();
}



void
XPathProcessorImpl::QName()
{
    assert(m_xpath != 0);
    assert(m_expression != 0);

    // If there is no prefix, we have to fake things out...
    if (lookahead(XalanUnicode::charColon, 1) == false)
    {
        m_expression->insertToken(s_emptyString);

        m_expression->pushCurrentTokenOnOpCodeMap();

        nextToken();
    }
    else
    {
        // Replace the token in the queue with the actual namespace...
        replaceTokenWithNamespaceToken();

        m_expression->pushCurrentTokenOnOpCodeMap();

        nextToken();

        consumeExpected(XalanUnicode::charColon);
    }

    m_expression->pushCurrentTokenOnOpCodeMap();

    nextToken();
}



void
XPathProcessorImpl::NCName()
{
    assert(m_xpath != 0);
    assert(m_expression != 0);

    m_expression->pushCurrentTokenOnOpCodeMap();

    nextToken();
}



void
XPathProcessorImpl::Literal()
{
    assert(m_xpath != 0);
    assert(m_expression != 0);

    if(isCurrentLiteral() == true)
    {
        m_expression->pushArgumentOnOpCodeMap(
            m_constructionContext->getPooledString(m_token.c_str() + 1, m_token.length() - 2));

        nextToken();
    }
    else
    {
        error(XalanMessages::LiteralArgumentIsRequired); 
    }
}



void
XPathProcessorImpl::Number()
{
    assert(m_xpath != 0);
    assert(m_expression != 0);

    if(m_token.empty() == false)
    {
        const double    num = DoubleSupport::toDouble(m_token, m_constructionContext->getMemoryManager());

        const XPathConstructionContext::GetCachedString     theGuard(*m_constructionContext);
 
        XalanDOMString&     theStringValue = theGuard.get();
 
        NumberToDOMString(num, theStringValue);

        m_expression->pushNumberLiteralOnOpCodeMap(num);

        m_expression->pushArgumentOnOpCodeMap(num, m_constructionContext->getPooledString(theStringValue));

        nextToken();
    }
}



void
XPathProcessorImpl::Pattern()
{
    while(true)
    {
        LocationPathPattern();

        if(tokenIs(XalanUnicode::charVerticalLine) == true)
        {
            nextToken();
        }
        else
        {
            break;
        }
    }
}



void
XPathProcessorImpl::LocationPathPattern()
{
    assert(m_xpath != 0);
    assert(m_expression != 0);

    const int   opPos = m_expression->opCodeMapLength();

    m_expression->appendOpCode(XPathExpression::eOP_LOCATIONPATHPATTERN);

    if(lookahead(XalanUnicode::charLeftParenthesis, 1) == true &&
                (tokenIs(s_functionIDString) == true ||
                 tokenIs(s_functionKeyString) == true))
    {
        IdKeyPattern();

        if(tokenIs(XalanUnicode::charSolidus) == true && lookahead(XalanUnicode::charSolidus, 1) == true)
        {
            const int   newOpPos = m_expression->opCodeMapLength();

            // Tell how long the step is without the predicate
            const XPathExpression::OpCodeMapValueVectorType     theArgs(1, 4, m_constructionContext->getMemoryManager());

            m_expression->appendOpCode(XPathExpression::eMATCH_ANY_ANCESTOR_WITH_FUNCTION_CALL,
                                       theArgs);

            m_expression->updateOpCodeLength(newOpPos);

            nextToken();
        }
    }
    else if(tokenIs(XalanUnicode::charSolidus) == true)
    {
        const int   newOpPos = m_expression->opCodeMapLength();

        // Tell how long the step is without the predicate
        const XPathExpression::OpCodeMapValueVectorType     theArgs(1, 4, m_constructionContext->getMemoryManager());

        if(lookahead(XalanUnicode::charSolidus, 1) == true)
        {
            m_expression->appendOpCode(
                XPathExpression::eMATCH_ANY_ANCESTOR_WITH_PREDICATE,
                theArgs);

            m_expression->appendOpCode(XPathExpression::eNODETYPE_NODE);

            nextToken();
        }
        else
        {
            m_expression->appendOpCode(XPathExpression::eFROM_ROOT,
                                       theArgs);

            m_expression->appendOpCode(XPathExpression::eNODETYPE_ROOT);
        }

        m_expression->updateOpCodeLength(newOpPos);

        nextToken();
    }

    if(m_token.empty() == false)
    {
        if (!tokenIs(XalanUnicode::charVerticalLine) == true)
        {
            RelativePathPattern();
        }
        else if (lookahead(XalanUnicode::charVerticalLine, -1) == true)
        {
            error(
                XalanMessages::UnexpectedTokenFound_1Param,
                m_token);
        }
    }

    // Terminate for safety.
    m_expression->appendOpCode(XPathExpression::eENDOP);

    m_expression->updateOpCodeLength(XPathExpression::eOP_LOCATIONPATHPATTERN,
                                     opPos);
}



void
XPathProcessorImpl::IdKeyPattern()
{
    m_requireLiterals = true;

    FunctionCall();

    m_requireLiterals = false;
}



void
XPathProcessorImpl::RelativePathPattern()
{    
    StepPattern();

    while(tokenIs(XalanUnicode::charSolidus) == true)
    {
        nextToken();

        StepPattern();
    }
}



void
XPathProcessorImpl::StepPattern()
{
    AbbreviatedNodeTestStep();
}



void
XPathProcessorImpl::AbbreviatedNodeTestStep()
{
    assert(m_xpath != 0);
    assert(m_expression != 0);

    const int   opPos = m_expression->opCodeMapLength();

    int         matchTypePos = -1;

    XPathExpression::eOpCodes   axisType = XPathExpression::eENDOP;

    // The next blocks guarantee that a MATCH_XXX will be added.
    if(tokenIs(XalanUnicode::charCommercialAt) == true)
    {
        axisType = XPathExpression::eMATCH_ATTRIBUTE;

        m_expression->appendOpCode(axisType);

        nextToken();
    }
    else if(lookahead(s_axisString, 1) == true)
    {
        if(tokenIs(s_attributeString) == true)
        {
            axisType = XPathExpression::eMATCH_ATTRIBUTE;

            m_expression->appendOpCode(axisType);
        }
        else if(tokenIs(s_childString) == true)
        {
            matchTypePos = m_expression->opCodeMapLength();

            axisType = XPathExpression::eMATCH_IMMEDIATE_ANCESTOR;

            m_expression->appendOpCode(axisType);
        }
        else
        {
            error(XalanMessages::OnlyChildAndAttributeAxesAreAllowed); 
        }

        nextToken();
        nextToken();
    }
    else if(tokenIs(XalanUnicode::charSolidus) == true)
    {
        if(lookahead(s_axisString, 2) == false &&
           lookahead(XalanUnicode::charCommercialAt, 1) == false)
        {
            matchTypePos = m_expression->opCodeMapLength();

            axisType = XPathExpression::eMATCH_IMMEDIATE_ANCESTOR;

            m_expression->appendOpCode(axisType);
        }
        else
        {
            nextToken();

            // This matches an abbreviated step "@foo"
            if (tokenIs(XalanUnicode::charCommercialAt) == true)
            {
                axisType = XPathExpression::eMATCH_ATTRIBUTE;

                m_expression->appendOpCode(axisType);
            }
            else
            {
                // This matches the attribute or child axis: attribute::name or child::name.
                if(tokenIs(s_attributeString) == true)
                {
                    axisType = XPathExpression::eMATCH_ATTRIBUTE;

                    m_expression->appendOpCode(axisType);
                }
                else if(tokenIs(s_childString) == true)
                {
                    matchTypePos = m_expression->opCodeMapLength();

                    axisType = XPathExpression::eMATCH_IMMEDIATE_ANCESTOR;

                    m_expression->appendOpCode(axisType);
                }
                else
                {
                    error(XalanMessages::OnlyChildAndAttributeAxesAreAllowed); 
                }

                nextToken();
            }
        }

        nextToken();
    }
    else
    {
        if(tokenIs(XalanUnicode::charSolidus) == true)
        {
            nextToken();
        }

        matchTypePos = m_expression->opCodeMapLength();

        axisType = XPathExpression::eMATCH_IMMEDIATE_ANCESTOR;

        m_expression->appendOpCode(axisType);
    }

    // Make room for telling how long the step is without the predicate.
    // This will be replaced by the right value.
    m_expression->appendOpCode(XPathExpression::eENDOP);

    NodeTest();

    m_expression->updateOpCodeLengthAfterNodeTest(opPos);

    while(tokenIs(XalanUnicode::charLeftSquareBracket) == true)
    {
        Predicate();
    }

    if(matchTypePos > -1 && tokenIs(XalanUnicode::charSolidus) == true && lookahead(XalanUnicode::charSolidus, 1) == true)
    {
        assert(m_expression->opCodeMapLength() > matchTypePos);

        m_expression->setOpCodeMapValue(matchTypePos, XPathExpression::eMATCH_ANY_ANCESTOR);
    }

    m_expression->updateOpCodeLength(opPos);
}



bool
XPathProcessorImpl::isValidFunction(const XalanDOMString&   key)
{
    bool    fResult = true;

    if(XPath::isInstalledFunction(key) == false)
    {
        if (searchTable(s_functionTable, s_functionTableSize, key).m_opCode == XPathExpression::eENDOP)
        {
            fResult = false;
        }
    }

    return fResult;
}



bool
XPathProcessorImpl::isCurrentLiteral() const
{
    const t_size_type   theLength = m_token.length();

    if (theLength <= 1)
    {
        return false;
    }
    else
    {
        const t_size_type   last = theLength - 1;

        const XalanDOMChar  c0 = m_tokenChar;
        const XalanDOMChar  cX = m_token[last];

        if((c0 == XalanUnicode::charQuoteMark && cX == XalanUnicode::charQuoteMark) ||
           (c0 == XalanUnicode::charApostrophe && cX == XalanUnicode::charApostrophe))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}



bool
XPathProcessorImpl::isAxis(const XalanDOMString&    theToken)
{
    const XalanDOMString::size_type     theLength =
        theToken.length();

    if (theLength == 0)
    {
        return false;
    }
    else if (theLength == 1 &&
             theToken[0] == XalanUnicode::charCommercialAt)
    {
        return true;
    }
    else if (equals(theToken, s_dotString) == true ||
             equals(theToken, s_dotDotString) == true)
    {
        return true;
    }
    else
    {
        const XPathExpression::eOpCodes     theOpCode =
            getAxisToken(theToken);

        if (theOpCode != XPathExpression::eENDOP)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}



bool
XPathProcessorImpl::isNodeTest(const XalanDOMString&    theToken)
{
    const XalanDOMString::size_type     theLength = theToken.length();

    if (theLength == 0)
    {
        return false;
    }
    else if (theLength == 1 &&
             theToken[0] == XalanUnicode::charAsterisk)
    {
        return true;
    }
    else if (theToken[0] == XalanUnicode::charLowLine ||
             XalanXMLChar::isLetter(theToken[0]) == true)
    {
        return true;
    }
    else
    {
        return false;
    }
}



const XPathProcessorImpl::TableEntry&
XPathProcessorImpl::searchTable(
        const TableEntry        theTable[],
        size_type               theTableSize,
        const XalanDOMString&   theString)
{
    const TableEntry*   theFirst = theTable;
    const TableEntry*   theLast = &theTable[theTableSize - 1];

    while(theFirst <= theLast)
    {
        const TableEntry*   theCurrent = theFirst + (theLast - theFirst) / 2;
        assert(theCurrent->m_string[0] != 0);

        const int   theResult = compare(theString.c_str(), theCurrent->m_string);

        if (theResult < 0)
        {
            theLast = theCurrent - 1;
        }
        else if (theResult > 0)
        {
            theFirst = theCurrent + 1;
        }
        else
        {
            return *theCurrent;
        }
    }

    return s_dummyEntry;
}



const XalanDOMString    XPathProcessorImpl::s_emptyString(XalanMemMgrs::getDummyMemMgr());



const XalanDOMChar  XPathProcessorImpl::s_functionIDString[] =
{
    XalanUnicode::charLetter_i,
    XalanUnicode::charLetter_d,
    0
};

// This shouldn't really be here, since it's not part of the XPath standard,
// but rather a part ofthe XSLT standard.
const XalanDOMChar  XPathProcessorImpl::s_functionKeyString[] =
{
    XalanUnicode::charLetter_k,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_y,
    0
};

const XalanDOMChar  XPathProcessorImpl::s_orString[] =
{
    XalanUnicode::charLetter_o,
    XalanUnicode::charLetter_r,
    0
};

const XalanDOMChar  XPathProcessorImpl::s_andString[] =
{
    XalanUnicode::charLetter_a,
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_d,
    0
};

const XalanDOMChar  XPathProcessorImpl::s_divString[] =
{
    XalanUnicode::charLetter_d,
    XalanUnicode::charLetter_i,
    XalanUnicode::charLetter_v,
    0
};

const XalanDOMChar  XPathProcessorImpl::s_modString[] =
{
    XalanUnicode::charLetter_m,
    XalanUnicode::charLetter_o,
    XalanUnicode::charLetter_d,
    0
};

const XalanDOMChar  XPathProcessorImpl::s_dotString[] =
{
    XalanUnicode::charFullStop,
    0
};

const XalanDOMChar  XPathProcessorImpl::s_dotDotString[] =
{
    XalanUnicode::charFullStop,
    XalanUnicode::charFullStop,
    0
};

const XalanDOMChar  XPathProcessorImpl::s_axisString[] =
{
    XalanUnicode::charColon,
    XalanUnicode::charColon,
    0
};

const XalanDOMChar  XPathProcessorImpl::s_attributeString[] =
{
    XalanUnicode::charLetter_a,
    XalanUnicode::charLetter_t,
    XalanUnicode::charLetter_t,
    XalanUnicode::charLetter_r,
    XalanUnicode::charLetter_i,
    XalanUnicode::charLetter_b,
    XalanUnicode::charLetter_u,
    XalanUnicode::charLetter_t,
    XalanUnicode::charLetter_e,
    0
};

const XalanDOMChar  XPathProcessorImpl::s_childString[] =
{
    XalanUnicode::charLetter_c,
    XalanUnicode::charLetter_h,
    XalanUnicode::charLetter_i,
    XalanUnicode::charLetter_l,
    XalanUnicode::charLetter_d,
    0
};

const XalanDOMChar  XPathProcessorImpl::s_lastString[] =
{
    XalanUnicode::charLetter_l,
    XalanUnicode::charLetter_a,
    XalanUnicode::charLetter_s,
    XalanUnicode::charLetter_t,
    0
};

const XalanDOMChar  XPathProcessorImpl::s_positionString[] =
{
    XalanUnicode::charLetter_p,
    XalanUnicode::charLetter_o,
    XalanUnicode::charLetter_s,
    XalanUnicode::charLetter_i,
    XalanUnicode::charLetter_t,
    XalanUnicode::charLetter_i,
    XalanUnicode::charLetter_o,
    XalanUnicode::charLetter_n,
    0
};

const XalanDOMChar  XPathProcessorImpl::s_asteriskString[] =
{
    XalanUnicode::charAsterisk,
    0
};

const XalanDOMChar  XPathProcessorImpl::s_commentString[] =
{
    XalanUnicode::charLetter_c,
    XalanUnicode::charLetter_o,
    XalanUnicode::charLetter_m,
    XalanUnicode::charLetter_m,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_t,
    0
};

const XalanDOMChar  XPathProcessorImpl::s_piString[] =
{
    XalanUnicode::charLetter_p,
    XalanUnicode::charLetter_r,
    XalanUnicode::charLetter_o,
    XalanUnicode::charLetter_c,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_s,
    XalanUnicode::charLetter_s,
    XalanUnicode::charLetter_i,
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_g,
    XalanUnicode::charHyphenMinus,
    XalanUnicode::charLetter_i,
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_s,
    XalanUnicode::charLetter_t,
    XalanUnicode::charLetter_r,
    XalanUnicode::charLetter_u,
    XalanUnicode::charLetter_c,
    XalanUnicode::charLetter_t,
    XalanUnicode::charLetter_i,
    XalanUnicode::charLetter_o,
    XalanUnicode::charLetter_n,
    0
};

const XalanDOMChar  XPathProcessorImpl::s_nodeString[] =
{
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_o,
    XalanUnicode::charLetter_d,
    XalanUnicode::charLetter_e,
    0
};

const XalanDOMChar  XPathProcessorImpl::s_textString[] =
{
    XalanUnicode::charLetter_t,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_x,
    XalanUnicode::charLetter_t,
    0
};

const XalanDOMChar      XPathProcessorImpl::s_ancestorString[] =
{
    XalanUnicode::charLetter_a,
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_c,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_s,
    XalanUnicode::charLetter_t,
    XalanUnicode::charLetter_o,
    XalanUnicode::charLetter_r,
    0
};

const XalanDOMChar      XPathProcessorImpl::s_ancestorOrSelfString[] =
{
    XalanUnicode::charLetter_a,
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_c,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_s,
    XalanUnicode::charLetter_t,
    XalanUnicode::charLetter_o,
    XalanUnicode::charLetter_r,
    XalanUnicode::charHyphenMinus,
    XalanUnicode::charLetter_o,
    XalanUnicode::charLetter_r,
    XalanUnicode::charHyphenMinus,
    XalanUnicode::charLetter_s,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_l,
    XalanUnicode::charLetter_f,
    0
};

const XalanDOMChar      XPathProcessorImpl::s_descendantString[] =
{
    XalanUnicode::charLetter_d,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_s,
    XalanUnicode::charLetter_c,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_d,
    XalanUnicode::charLetter_a,
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_t,
    0
};

const XalanDOMChar      XPathProcessorImpl::s_descendantOrSelfString[] =
{
    XalanUnicode::charLetter_d,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_s,
    XalanUnicode::charLetter_c,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_d,
    XalanUnicode::charLetter_a,
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_t,
    XalanUnicode::charHyphenMinus,
    XalanUnicode::charLetter_o,
    XalanUnicode::charLetter_r,
    XalanUnicode::charHyphenMinus,
    XalanUnicode::charLetter_s,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_l,
    XalanUnicode::charLetter_f,
    0
};

const XalanDOMChar      XPathProcessorImpl::s_followingString[] =
{
    XalanUnicode::charLetter_f,
    XalanUnicode::charLetter_o,
    XalanUnicode::charLetter_l,
    XalanUnicode::charLetter_l,
    XalanUnicode::charLetter_o,
    XalanUnicode::charLetter_w,
    XalanUnicode::charLetter_i,
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_g,
    0
};

const XalanDOMChar      XPathProcessorImpl::s_followingSiblingString[] =
{
    XalanUnicode::charLetter_f,
    XalanUnicode::charLetter_o,
    XalanUnicode::charLetter_l,
    XalanUnicode::charLetter_l,
    XalanUnicode::charLetter_o,
    XalanUnicode::charLetter_w,
    XalanUnicode::charLetter_i,
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_g,
    XalanUnicode::charHyphenMinus,
    XalanUnicode::charLetter_s,
    XalanUnicode::charLetter_i,
    XalanUnicode::charLetter_b,
    XalanUnicode::charLetter_l,
    XalanUnicode::charLetter_i,
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_g,
    0
};

const XalanDOMChar      XPathProcessorImpl::s_parentString[] =
{
    XalanUnicode::charLetter_p,
    XalanUnicode::charLetter_a,
    XalanUnicode::charLetter_r,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_t,
    0
};

const XalanDOMChar      XPathProcessorImpl::s_precedingString[] =
{
    XalanUnicode::charLetter_p,
    XalanUnicode::charLetter_r,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_c,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_d,
    XalanUnicode::charLetter_i,
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_g,
    0
};

const XalanDOMChar      XPathProcessorImpl::s_precedingSiblingString[] =
{
    XalanUnicode::charLetter_p,
    XalanUnicode::charLetter_r,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_c,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_d,
    XalanUnicode::charLetter_i,
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_g,
    XalanUnicode::charHyphenMinus,
    XalanUnicode::charLetter_s,
    XalanUnicode::charLetter_i,
    XalanUnicode::charLetter_b,
    XalanUnicode::charLetter_l,
    XalanUnicode::charLetter_i,
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_g,
    0
};

const XalanDOMChar      XPathProcessorImpl::s_selfString[] =
{
    XalanUnicode::charLetter_s,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_l,
    XalanUnicode::charLetter_f,
    0
};

const XalanDOMChar      XPathProcessorImpl::s_namespaceString[] =
{
    XalanUnicode::charLetter_n,
    XalanUnicode::charLetter_a,
    XalanUnicode::charLetter_m,
    XalanUnicode::charLetter_e,
    XalanUnicode::charLetter_s,
    XalanUnicode::charLetter_p,
    XalanUnicode::charLetter_a,
    XalanUnicode::charLetter_c,
    XalanUnicode::charLetter_e,
    0
};



const XPathProcessorImpl::TableEntry    XPathProcessorImpl::s_functionTable[] =
{
    { XPathFunctionTable::s_not, XPathExpression::eOP_FUNCTION_NOT },
    { XPathFunctionTable::s_sum, XPathExpression::eOP_FUNCTION_SUM },
    { XPathProcessorImpl::s_lastString, XPathExpression::eOP_FUNCTION_LAST },
    { XPathFunctionTable::s_name, XPathExpression::eOP_FUNCTION_NAME_0 },
    { XPathProcessorImpl::s_nodeString, XPathExpression::eNODETYPE_NODE },
    { XPathProcessorImpl::s_textString, XPathExpression::eNODETYPE_TEXT },
    { XPathFunctionTable::s_true, XPathExpression::eOP_FUNCTION_TRUE },
    { XPathFunctionTable::s_count, XPathExpression::eOP_FUNCTION_COUNT  },
    { XPathFunctionTable::s_false, XPathExpression::eOP_FUNCTION_FALSE },
    { XPathFunctionTable::s_floor, XPathExpression::eOP_FUNCTION_FLOOR },
    { XPathFunctionTable::s_round, XPathExpression::eOP_FUNCTION_ROUND },
    { XPathFunctionTable::s_number, XPathExpression::eOP_FUNCTION_NUMBER_0 },
    { XPathFunctionTable::s_boolean, XPathExpression::eOP_FUNCTION_BOOLEAN },
    { XPathFunctionTable::s_ceiling, XPathExpression::eOP_FUNCTION_CEILING },
    { XPathProcessorImpl::s_commentString, XPathExpression::eNODETYPE_COMMENT },
    { XPathProcessorImpl::s_positionString, XPathExpression::eOP_FUNCTION_POSITION },
    { XPathFunctionTable::s_localName, XPathExpression::eOP_FUNCTION_LOCALNAME_0 },
    { XPathFunctionTable::s_stringLength, XPathExpression::eOP_FUNCTION_STRINGLENGTH_0 },
    { XPathProcessorImpl::s_piString, XPathExpression::eNODETYPE_PI },
};

const XPathProcessorImpl::size_type     XPathProcessorImpl::s_functionTableSize =
    sizeof(s_functionTable) / sizeof(s_functionTable[0]);



const XPathProcessorImpl::TableEntry    XPathProcessorImpl::s_nodeTypeTable[] =
{
    { XPathProcessorImpl::s_asteriskString, XPathExpression::eNODETYPE_ANYELEMENT },
    { XPathProcessorImpl::s_nodeString, XPathExpression::eNODETYPE_NODE },
    { XPathProcessorImpl::s_textString, XPathExpression::eNODETYPE_TEXT },
    { XPathProcessorImpl::s_commentString, XPathExpression::eNODETYPE_COMMENT },
    { XPathProcessorImpl::s_piString, XPathExpression::eNODETYPE_PI },
};

const XPathProcessorImpl::size_type     XPathProcessorImpl::s_nodeTypeTableSize =
    sizeof(s_nodeTypeTable) / sizeof(s_nodeTypeTable[0]);



const XPathProcessorImpl::TableEntry    XPathProcessorImpl::s_axisTable[] =
{
    { XPathProcessorImpl::s_selfString, XPathExpression::eFROM_SELF },
    { XPathProcessorImpl::s_childString, XPathExpression::eFROM_CHILDREN },
    { XPathProcessorImpl::s_parentString, XPathExpression::eFROM_PARENT },
    { XPathProcessorImpl::s_ancestorString, XPathExpression::eFROM_ANCESTORS },
    { XPathProcessorImpl::s_attributeString, XPathExpression::eFROM_ATTRIBUTES },
    { XPathProcessorImpl::s_followingString, XPathExpression::eFROM_FOLLOWING },
    { XPathProcessorImpl::s_namespaceString, XPathExpression::eFROM_NAMESPACE },
    { XPathProcessorImpl::s_precedingString, XPathExpression::eFROM_PRECEDING },
    { XPathProcessorImpl::s_descendantString, XPathExpression::eFROM_DESCENDANTS },
    { XPathProcessorImpl::s_ancestorOrSelfString, XPathExpression::eFROM_ANCESTORS_OR_SELF },
    { XPathProcessorImpl::s_followingSiblingString, XPathExpression::eFROM_FOLLOWING_SIBLINGS },
    { XPathProcessorImpl::s_precedingSiblingString, XPathExpression::eFROM_PRECEDING_SIBLINGS },
    { XPathProcessorImpl::s_descendantOrSelfString, XPathExpression::eFROM_DESCENDANTS_OR_SELF },
};

const XPathProcessorImpl::size_type     XPathProcessorImpl::s_axisTableSize =
    sizeof(s_axisTable) / sizeof(s_axisTable[0]);


const XPathProcessorImpl::TableEntry    XPathProcessorImpl::s_dummyEntry =
{
    0, XPathExpression::eENDOP
};



}
