/*
 * 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 "XPathExpression.hpp"



#include <algorithm>
#include <cstdio>



#include <ostream>



#include <xalanc/PlatformSupport/DoubleSupport.hpp>
#include <xalanc/PlatformSupport/XalanMessageLoader.hpp>



#include "XObjectTypeCallback.hpp"



namespace XALAN_CPP_NAMESPACE {





// This is an array which indicates which of the value defined by
// XPathExpression::eOpCodes are node tests.
static const bool   theNodeTestOpCodesArray[] =
{
    false, false, true,  false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false, false, false,
    false, false, false, false, false, false, false, false, false, false,
    false, false, false, false, true,  true,  true,  true,  true,  true,
    true,  true,  true,  true,  true,  true,  true,  false, false, false, 
    true,  true,  true
};

static const XalanSize_t    theNodeTestOpCodesArraySize =
        sizeof(theNodeTestOpCodesArray) / sizeof(theNodeTestOpCodesArray[0]);


// This is an array for all of the opcode defined by XPathExpression::eOpCodes.
// It is offset by 3, because there opcode values are -3, -2, and -1.  So,
// when getting the length of an opcode, we add three to get the correct index.
static const int    theOpCodeLengthArray[] =
{
    1,
    1,
    1,

    0,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,

    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,

    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 3,
    XPathExpression::s_opCodeMapLengthIndex + 3,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    1,
    1,

    1,
    1,
    1,
    1,
    1,
    XPathExpression::s_opCodeMapLengthIndex + 2,
    XPathExpression::s_opCodeMapLengthIndex + 2,
    XPathExpression::s_opCodeMapLengthIndex + 2,
    XPathExpression::s_opCodeMapLengthIndex + 2,
    XPathExpression::s_opCodeMapLengthIndex + 2,

    XPathExpression::s_opCodeMapLengthIndex + 2,
    XPathExpression::s_opCodeMapLengthIndex + 2,
    XPathExpression::s_opCodeMapLengthIndex + 2,
    XPathExpression::s_opCodeMapLengthIndex + 2,
    XPathExpression::s_opCodeMapLengthIndex + 2,
    XPathExpression::s_opCodeMapLengthIndex + 2,
    XPathExpression::s_opCodeMapLengthIndex + 2,
    XPathExpression::s_opCodeMapLengthIndex + 2,
    XPathExpression::s_opCodeMapLengthIndex + 2,
    XPathExpression::s_opCodeMapLengthIndex + 1,

    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 2,
    XPathExpression::s_opCodeMapLengthIndex + 2,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1,
    XPathExpression::s_opCodeMapLengthIndex + 1
};

static const int    theOpCodeLengthArraySize =
        sizeof(theOpCodeLengthArray) / sizeof(theOpCodeLengthArray[0]);



inline int
getOpCodeLength(int     theOpCode)
{
    assert(theOpCodeLengthArraySize == XPathExpression::eOpCodeNextAvailable + 3);

    // Add 3 to get the correct index into the array...
    theOpCode += 3;

    if (theOpCode < 0 || theOpCode >= theOpCodeLengthArraySize)
    {
        return 0;
    }
    else
    {
        return theOpCodeLengthArray[theOpCode];
    }
}



XPathExpression::XPathExpressionException::XPathExpressionException(
            const XalanDOMString&   theMessage,
            MemoryManager&          theManager) :
    XalanXPathException(theMessage, theManager)
{
}



XPathExpression::XPathExpressionException::~XPathExpressionException()
{
}



XPathExpression::InvalidOpCodeException::InvalidOpCodeException(
            OpCodeMapValueType  theOpCode,
            XalanDOMString&     theBuffer) :
    XPathExpressionException(
        FormatErrorMessage(
            theOpCode,
            theBuffer),
        theBuffer.getMemoryManager())
{
}



XPathExpression::InvalidOpCodeException::~InvalidOpCodeException()
{
}



XalanDOMString&
XPathExpression::InvalidOpCodeException::FormatErrorMessage(
            OpCodeMapValueType  theOpCode,
            XalanDOMString&     theBuffer)
{
    XalanDOMString  theOpcode(theBuffer.getMemoryManager()); 

    NumberToDOMString(theOpCode, theOpcode);

    return XalanMessageLoader::getMessage(
                theBuffer,
                XalanMessages::InvalidOpcodeWasDetected_1Param,
                theOpcode);
}



XPathExpression::InvalidArgumentCountException::InvalidArgumentCountException(
            OpCodeMapValueType  theOpCode,
            OpCodeMapValueType  theExpectedCount,
            OpCodeMapValueType  theSuppliedCount,
            XalanDOMString&     theBuffer) :
    XPathExpressionException(
        FormatErrorMessage(
            theOpCode,
            theExpectedCount,
            theSuppliedCount,
            theBuffer),
        theBuffer.getMemoryManager())
{
}



XPathExpression::InvalidArgumentCountException::~InvalidArgumentCountException()
{
}



XalanDOMString&
XPathExpression::InvalidArgumentCountException::FormatErrorMessage(
            OpCodeMapValueType  theOpCode,
            OpCodeMapValueType  theExpectedCount,
            OpCodeMapValueType  theSuppliedCount,
            XalanDOMString&     theBuffer)
{
    XalanDOMString  theResult(theBuffer.getMemoryManager());

    NumberToDOMString(theOpCode, theResult);

    XalanDOMString  theResult1(theBuffer.getMemoryManager());
    NumberToDOMString(theExpectedCount, theResult1);

    XalanDOMString  theResult2(theBuffer.getMemoryManager());
    NumberToDOMString(theSuppliedCount, theResult2);


    return XalanMessageLoader::getMessage(
                theBuffer,
                XalanMessages::InvalidNumberOfArgsWasDetected_3Param,
                theResult1,
                theResult2);
}



XPathExpression::InvalidArgumentException::InvalidArgumentException(
            OpCodeMapValueType  theOpCode,
            OpCodeMapValueType  theValue,
            XalanDOMString&     theBuffer) :
    XPathExpressionException(
        FormatErrorMessage(
            theOpCode,
            theValue,
            theBuffer),
        theBuffer.getMemoryManager())
{
}



XPathExpression::InvalidArgumentException::~InvalidArgumentException()
{
}



XalanDOMString&
XPathExpression::InvalidArgumentException::FormatErrorMessage(
                OpCodeMapValueType  theOpCode,
                OpCodeMapValueType  theValue,
                XalanDOMString&     theBuffer)
{ 
    XalanDOMString  theResult(theBuffer.getMemoryManager());
    NumberToDOMString(theValue, theResult);

    
    XalanDOMString  theResult1(theBuffer.getMemoryManager());
    NumberToDOMString(theOpCode, theResult1);

    return XalanMessageLoader::getMessage(
                theBuffer,
                XalanMessages::InvalidNumberOfArgsWasSupplied_2Param,
                theResult1) ;
}



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



XPathExpression::XPathExpression(MemoryManager& theManager) :
    m_opMap(theManager),
    m_lastOpCodeIndex(0),
    m_tokenQueue(theManager),
    m_currentPosition(0),
    m_currentPattern(&s_emptyString),
    m_numberLiteralValues(theManager)
{
    m_opMap.reserve(eDefaultOpMapSize);
    m_tokenQueue.reserve(eDefaultTokenQueueSize);
}



XPathExpression::~XPathExpression()
{
    reset();
}



void
XPathExpression::reset()
{
    m_opMap.clear();
    m_tokenQueue.clear();
}



void
XPathExpression::shrink()
{
    if (m_opMap.capacity() > m_opMap.size())
    {
        OpCodeMapType tmp(m_opMap, m_opMap.getMemoryManager());

        tmp.swap(m_opMap);
    }
}



#if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS)

XPathExpression::OpCodeMapValueType
XPathExpression::getOpCodeLengthFromOpMap(
            OpCodeMapPositionType   opPos,
            MemoryManager&          theManager) const
{
    assert(opPos - getInitialOpCodePosition() >= 0 &&
           opPos - getInitialOpCodePosition() < opCodeMapSize());

    OpCodeMapValueType  theResult = 0;

    // Is there a valid opcode?
    const int   theOpCodeLength = getOpCodeLength(*opPos);

    if (theOpCodeLength == 0)
    {
        XalanDOMString   theBuffer(theManager);

        throw InvalidOpCodeException(-1, theBuffer);
    }
    else
    {
        // Does the Op code have a length > 1?
        if (theOpCodeLength > 1)
        {
            // Yes, so get the length.
            theResult = *(opPos + s_opCodeMapLengthIndex);
        }
    }

    return theResult;
}

#endif

XPathExpression::OpCodeMapValueType
XPathExpression::getOpCodeLengthFromOpMap(
#if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS)
            OpCodeMapSizeType       theIndex,
#else
            OpCodeMapPositionType   theIndex,
#endif
            MemoryManager&          theManager) const
{
    OpCodeMapValueType  theResult = 0;

    if (theIndex >= opCodeMapSize())
    {
        XalanDOMString   theBuffer(theManager);

        throw InvalidOpCodeException(-1, theBuffer);
    }
    else
    {
        // Is there a valid opcode?
        const int   theOpCodeLength = getOpCodeLength(m_opMap[theIndex]);

        if (theOpCodeLength == 0)
        {
            XalanDOMString   theBuffer(theManager);

            throw InvalidOpCodeException(-1, theBuffer);
        }
        else
        {
            // Does the Op code have a length > 1?
            if (theOpCodeLength > 1)
            {
                // Yes, so get the length.
                theResult = m_opMap[theIndex + s_opCodeMapLengthIndex];
            }
        }
    }

    return theResult;
}



void
XPathExpression::setOpCodeArgs(
            eOpCodes                            theOpCode,
            OpCodeMapSizeType                   theIndex,
            const OpCodeMapValueVectorType&     theArgs)
{
    // There must be at least enough space to hold the OpCode
    // and the length indicator.
    assert(opCodeMapSize() > theIndex + 1);

    const int   theOpCodeLength = getOpCodeLength(theOpCode);

    // Make sure it's a valid op code and that it
    // matches the op code at supplied index.
    if (theOpCodeLength == 0 ||
        m_opMap[theIndex] != theOpCode)
    {
        XalanDOMString   theBuffer(getMemoryManager());

        throw InvalidOpCodeException(
                theOpCode,
                theBuffer);
    }
    else
    {
        const OpCodeMapValueType    theArgCount =
                theOpCodeLength - 1 - s_opCodeMapLengthIndex;

        if (OpCodeMapValueVectorType::size_type(theArgCount) != theArgs.size())
        {
            XalanDOMString   theBuffer(getMemoryManager());

            throw InvalidArgumentCountException(
                    theOpCode,
                    theOpCodeLength,
                    theArgCount,
                    theBuffer);
        }
        else
        {
            assert(opCodeMapSize() > theIndex + theArgCount);

            for (OpCodeMapValueType i = 0; i < theArgCount; ++i)
            {
                if (theArgs[i] < 0)
                {
                    XalanDOMString   theBuffer(getMemoryManager());

                    throw InvalidArgumentException(
                            theOpCode,
                            theArgs[i],
                            theBuffer);
                }
                else
                {
                    m_opMap[i + theIndex + s_opCodeMapLengthIndex + 1] =
                        theArgs[i];
                }
            }
        }
    }
}



XPathExpression::OpCodeMapSizeType
XPathExpression::appendOpCode(eOpCodes  theOpCode)
{
    const int   theOpCodeLength = getOpCodeLength(theOpCode);

    if (theOpCodeLength == 0)
    {
        XalanDOMString   theBuffer(getMemoryManager());

        throw InvalidOpCodeException(
                theOpCode,
                theBuffer);
    }
    else
    {
        // Set the current index before pushing, by
        // getting the length, which will be correct
        // after the push.
        m_lastOpCodeIndex = opCodeMapSize();

        m_opMap.push_back(theOpCode);

        assert(s_opCodeMapLengthIndex == 1);

        if (theOpCodeLength > 1)
        {
            m_opMap.push_back(theOpCodeLength);

            for (int i = 2; i < theOpCodeLength; ++i)
            {
                m_opMap.push_back(eENDOP);
            }
        }

        if (m_lastOpCodeIndex != 0)
        {
            m_opMap[s_opCodeMapLengthIndex] += theOpCodeLength;
        }
    }

    assert(opCodeMapSize() == OpCodeMapSizeType(opCodeMapLength()));

    return m_lastOpCodeIndex;
}



void
XPathExpression::replaceOpCode(
            OpCodeMapSizeType   theIndex,
            eOpCodes            theOldOpCode,
            eOpCodes            theNewOpCode)
{
    if (theIndex >= opCodeMapSize() ||
        m_opMap[theIndex] != theOldOpCode ||
        getOpCodeLength(theOldOpCode) != getOpCodeLength(theNewOpCode))
    {
        XalanDOMString   theBuffer(getMemoryManager());

        throw InvalidOpCodeException(
                theNewOpCode,
                theBuffer);
    }
    else
    {
        m_opMap[theIndex] = theNewOpCode;
    }
}



XPathExpression::OpCodeMapValueType
XPathExpression::insertOpCode(
            eOpCodes            theOpCode,
            OpCodeMapSizeType   theIndex)
{
    const int   theOpCodeLength = getOpCodeLength(theOpCode);

    if (theOpCodeLength == 0)
    {
        XalanDOMString   theBuffer(getMemoryManager());

        throw InvalidOpCodeException(
                theOpCode,
                theBuffer);
    }
    else
    {
        // Insert -1 for each element of the opcode.
        m_opMap.insert(
            m_opMap.begin() + theIndex,
            OpCodeMapSizeType(theOpCodeLength),
            -1);

        // Set the member that contains the last insert/appended
        // index.
        m_lastOpCodeIndex = theIndex;

        // Assign the opcode.
        m_opMap[theIndex] = theOpCode;

        // Update the entire expression length.
        m_opMap[s_opCodeMapLengthIndex] += theOpCodeLength;
    }

    return theOpCodeLength;
}



void
XPathExpression::updateShiftedOpCodeLength(
            OpCodeMapValueType  theOpCode,
#if defined(NDEBUG)
            OpCodeMapSizeType   /* theOriginalIndex */,
#else
            OpCodeMapSizeType   theOriginalIndex,
#endif
            OpCodeMapSizeType   theNewIndex)
{
    // There must be some other expressions in
    // the buffer...
    assert(opCodeMapSize() > theNewIndex + 1);

    assert(theNewIndex > theOriginalIndex);

    const OpCodeMapValueType    theOpCodeLength = getOpCodeLength(theOpCode);

    // Make sure it's a valid op code and that it
    // matches the op code at supplied index.
    if (theOpCodeLength == 0 ||
        m_opMap[theNewIndex] != theOpCode)
    {
        XalanDOMString   theBuffer(getMemoryManager());

        throw InvalidOpCodeException(
                theOpCode,
                theBuffer);
    }
    else
    {
        // Determine where the length position of the op code
        // is.
        const   OpCodeMapSizeType   theLengthIndex =
                        theNewIndex + s_opCodeMapLengthIndex;

        // Too long, then throw an exception.
        if (theLengthIndex >= opCodeMapSize())
        {
            XalanDOMString   theBuffer(getMemoryManager());

            throw InvalidOpCodeException(
                    theOpCode,
                    theBuffer);
        }
        else
        {
            // Look ahead to where the new operand is.
            const OpCodeMapSizeType     theNextOpCodePosition =
                        getNextOpCodePosition(theNewIndex);

            // If it's there, then update our size by
            // adding that size in.
            if (theNextOpCodePosition < opCodeMapSize())
            {
                m_opMap[theLengthIndex] += getOpCodeLengthFromOpMap(theNextOpCodePosition, getMemoryManager());
            }
        }
    }
}



void
XPathExpression::updateOpCodeLength(
            OpCodeMapValueType  theOpCode,
            OpCodeMapValueType  theIndex)
{
    // There must be some other expressions in
    // the buffer...
    assert(opCodeMapSize() > theIndex + 1);

    const int   theOpCodeLength = getOpCodeLength(theOpCode);

    // Make sure it's a valid op code and that it
    // matches the op code at supplied index.
    if (theOpCodeLength == 0 ||
        m_opMap[theIndex] != theOpCode)
    {
        XalanDOMString   theBuffer(getMemoryManager());

        throw InvalidOpCodeException(
                theOpCode,
                theBuffer);
    }
    else
    {
        // This presumes that the other opcodes
        // have been appended to the expression,
        // and that the specified op code's length
        // needs to be set.  The size includes the
        // normal length of the opcode, plus the
        // length of its subexpressions.
        m_opMap[theIndex + s_opCodeMapLengthIndex] =
                            opCodeMapLength() - theIndex;
    }
}



bool
XPathExpression::isNodeTestOpCode(OpCodeMapValueType    theOpCode)
{
    if (theOpCode < theNodeTestOpCodesArraySize)
    {
        return theNodeTestOpCodesArray[theOpCode];
    }
    else
    {
        return false;
    }
}



void
XPathExpression::updateOpCodeLengthAfterNodeTest(OpCodeMapSizeType  theIndex)
{
    // There must be some other expressions in
    // the buffer...
    assert(opCodeMapSize() > theIndex + 1);

    const OpCodeMapValueType    theOpCode =
                        m_opMap[theIndex];

    const int   theOpCodeLength = getOpCodeLength(theOpCode);

    // Make sure it's a valid op code and that it
    // is a node test op code.
    if (theOpCodeLength == 0 ||
        isNodeTestOpCode(theOpCode) == false)
    {
        XalanDOMString   theBuffer(getMemoryManager());

        throw InvalidOpCodeException(
                theOpCode,
                theBuffer);
    }
    else
    {
        m_opMap[theIndex + s_opCodeMapLengthIndex + 1] =
                            opCodeMapLength() - theIndex;
    }
}



void
XPathExpression::dumpOpCodeMap(
            PrintWriter&        thePrintWriter,
            OpCodeMapSizeType   theStartPosition) const
{
    for (OpCodeMapSizeType  i = theStartPosition;
                i < opCodeMapSize(); i++) 
    {
        thePrintWriter.print(" '");
        thePrintWriter.print(m_opMap[i]);
        thePrintWriter.print("'");
    }
}



void
XPathExpression::dumpOpCodeMap(
            OstreamType&        theStream,
            OpCodeMapSizeType   theStartPosition) const
{
    for (OpCodeMapSizeType  i = theStartPosition;
                i < opCodeMapSize(); i++) 
    {
        theStream << " '" << m_opMap[i] << "'";
    }
}



void
XPathExpression::dumpTokenQueue(
            OstreamType&        theStream,
            TokenQueueSizeType  theStartPosition) const
{
    for (TokenQueueSizeType i = theStartPosition;
                i < tokenQueueSize(); i++) 
    {
        assert(getToken(i) != 0);

        theStream << " '" << getToken(i)->str() << "'";
    }
}



void
XPathExpression::dumpTokenQueue(
            PrintWriter&        thePrintWriter,
            TokenQueueSizeType  theStartPosition) const
{
    for (TokenQueueSizeType i = theStartPosition;
                i < tokenQueueSize(); i++) 
    {
        assert(getToken(i) != 0);

        if (i > 0)
        {
            thePrintWriter.print(" '");
        }
        else
        {
            thePrintWriter.print("'");
        }

        thePrintWriter.print(getToken(i)->str());
        thePrintWriter.print("'");
    }
}



void
XPathExpression::dumpRemainingTokenQueue(PrintWriter&   thePrintWriter) const
{
    XalanDOMString  tmpString(thePrintWriter.getMemoryManager());

    thePrintWriter.print(
        XalanMessageLoader::getMessage(
            tmpString,
            XalanMessages::RemainingTokens));

    thePrintWriter.print("(");

    dumpTokenQueue(
        thePrintWriter,
        m_currentPosition);

    thePrintWriter.print(")");
}



void
XPathExpression::dumpRemainingTokenQueue(
            OstreamType&    theStream,
            MemoryManager&  theMemoryManager) const
{
    XalanDOMString  tmpString(theMemoryManager);

    theStream << XalanMessageLoader::getMessage(tmpString, XalanMessages::RemainingTokens)
              << "(";

    dumpTokenQueue(theStream,
                   m_currentPosition);

    theStream << ")";
}



void
XPathExpression::pushArgumentOnOpCodeMap(const XToken&  theXToken)
{
    assert(m_currentPosition != 0);

    const int   thePosition = m_currentPosition - 1;

    assert(thePosition < tokenQueueSize());

    // Set the entry in the token queue to the XObject.
    m_tokenQueue[thePosition] = theXToken;

    // Push the index onto the op map.
    m_opMap.push_back(thePosition);

    // Update the op map length.
    ++m_opMap[s_opCodeMapLengthIndex];
}



void
XPathExpression::pushArgumentOnOpCodeMap(const XalanDOMString&  theToken)
{
    assert(m_currentPosition != 0);

    const TokenQueueSizeType    thePosition = m_currentPosition - 1;

    assert(thePosition < tokenQueueSize());

    // Set the entry in the token queue to the XObject.
    m_tokenQueue[thePosition].set(
        theToken,
        DoubleSupport::toDouble(theToken, getMemoryManager()));

    // Push the index onto the op map.
    m_opMap.push_back(thePosition);

    // Update the op map length.
    ++m_opMap[s_opCodeMapLengthIndex];
}



void
XPathExpression::pushArgumentOnOpCodeMap(
            double                  theNumber,
            const XalanDOMString&   theString)
{
    assert(m_currentPosition != 0);

    const TokenQueueSizeType    thePosition = m_currentPosition - 1;

    assert(thePosition < tokenQueueSize());

    // Set the entry in the token queue to the XObject.
    m_tokenQueue[thePosition].set(theNumber, theString);

    // Push the index onto the op map.
    m_opMap.push_back(thePosition);

    // Update the op map length.
    ++m_opMap[s_opCodeMapLengthIndex];
}



void
XPathExpression::pushNumberLiteralOnOpCodeMap(double    theNumber)
{
    // Get the new index for the literal...
    const OpCodeMapValueType    theIndex = OpCodeMapValueType(m_numberLiteralValues.size());

    assert(NumberLiteralValueVectorType::size_type(theIndex) == m_numberLiteralValues.size());

    // Push the index onto the op map.
    m_opMap.push_back(theIndex);

    // Update the op map length.
    ++m_opMap[s_opCodeMapLengthIndex];

    m_numberLiteralValues.push_back(theNumber);
}



void
XPathExpression::pushCurrentTokenOnOpCodeMap()
{
    assert(m_currentPosition != 0);

    const TokenQueueSizeType    thePosition = m_currentPosition - 1;

    assert(thePosition < tokenQueueSize());

    // Push the index onto the op map.
    m_opMap.push_back(thePosition);

    // Update the op map length.
    ++m_opMap[s_opCodeMapLengthIndex];
}



}
