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

/*
 * $Id: XercesXPath.cpp 568078 2007-08-21 11:43:25Z amassari $
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/validators/schema/identity/XercesXPath.hpp>
#include <xercesc/validators/schema/identity/XPathSymbols.hpp>
#include <xercesc/validators/schema/identity/XPathException.hpp>
#include <xercesc/validators/schema/NamespaceScope.hpp>
#include <xercesc/util/StringPool.hpp>
#include <xercesc/util/Janitor.hpp>
#include <xercesc/framework/XMLBuffer.hpp>
#include <xercesc/internal/XMLReader.hpp>
#include <xercesc/util/RuntimeException.hpp>
#include <xercesc/util/OutOfMemoryException.hpp>

#include <xercesc/internal/XTemplateSerializer.hpp>

XERCES_CPP_NAMESPACE_BEGIN


// ---------------------------------------------------------------------------
//  Static data
// ---------------------------------------------------------------------------
const XMLByte XPathScanner::fASCIICharMap[128] =
{
    0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  2,  0,  0,  2,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    2,  3,  4,  1,  5,  1,  1,  4,  6,  7,  8,  9, 10, 11, 12, 13,
    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15,  1, 16, 17, 18,  1,
    19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
    20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,  1, 22,  1, 23,
    1, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
    20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  1, 24,  1,  1,  1
};


// ---------------------------------------------------------------------------
//  XercesNodeTest: Constructors and Destructor
// ---------------------------------------------------------------------------
XercesNodeTest::XercesNodeTest(const short aType,
                               MemoryManager* const manager)
    : fType(aType)
    , fName(new (manager) QName(manager))
{
}

XercesNodeTest::XercesNodeTest(const QName* const qName)
    : fType(QNAME)
    , fName(new (qName->getMemoryManager()) QName(*qName))
{
}

XercesNodeTest::XercesNodeTest(const XMLCh* const prefix,
                               const unsigned int uriId,
                               MemoryManager* const manager)
    : fType(NAMESPACE)
    , fName(new (manager) QName(manager))
{
    fName->setURI(uriId);
    fName->setPrefix(prefix);
}

XercesNodeTest::XercesNodeTest(const XercesNodeTest& other)
    : XSerializable(other)
    , XMemory(other)
    , fType(other.fType)
    , fName(new ((other.fName)->getMemoryManager()) QName(*other.fName))
{
}

/***
 * Support for Serialization/De-serialization
 ***/

IMPL_XSERIALIZABLE_TOCREATE(XercesNodeTest)

void XercesNodeTest::serialize(XSerializeEngine& serEng)
{

    if (serEng.isStoring())
    {
        serEng<<fType;
        serEng<<fName;
    }
    else
    {
        serEng>>fType;
        serEng>>fName;
    }
}

XercesNodeTest::XercesNodeTest(MemoryManager* const)
:fType(UNKNOWN)
,fName(0)
{
}

// ---------------------------------------------------------------------------
//  XercesNodeTest: Operators
// ---------------------------------------------------------------------------
XercesNodeTest& XercesNodeTest::operator=(const XercesNodeTest& other)
{
    if (this == &other)
        return *this;

    fType = other.fType;
    fName->setValues(*(other.fName));
    return *this;
}

bool XercesNodeTest::operator ==(const XercesNodeTest& other) const {

    if (this == &other)
        return true;

    if (fType != other.fType)
        return false;

    return (*fName == *(other.fName));
}


bool XercesNodeTest::operator !=(const XercesNodeTest& other) const {

    return !operator==(other);
}

// ---------------------------------------------------------------------------
//  XercesStep: Constructors and Destructor
// ---------------------------------------------------------------------------
XercesStep::XercesStep(const unsigned short axisType, XercesNodeTest* const nodeTest)
    : fAxisType(axisType)
    , fNodeTest(nodeTest)
{
}

XercesStep::XercesStep(const XercesStep& other)
    : XSerializable(other)
    , XMemory(other)
    , fAxisType(other.fAxisType)
    , fNodeTest(0)
{
    fNodeTest = new (other.fNodeTest->getName()->getMemoryManager()) XercesNodeTest(*(other.fNodeTest));
}


// ---------------------------------------------------------------------------
//  XercesStep: Operators
// ---------------------------------------------------------------------------
XercesStep& XercesStep::operator=(const XercesStep& other)
{
    if (this == &other)
        return *this;

    fAxisType = other.fAxisType;
    *fNodeTest = *(other.fNodeTest);
    return *this;
}

bool XercesStep::operator==(const XercesStep& other) const {

    if (this == &other)
        return true;

    if (fAxisType != other.fAxisType)
        return false;

    if (fAxisType == XercesStep::CHILD ||
        fAxisType == XercesStep::ATTRIBUTE) {
        return (*fNodeTest == *(other.fNodeTest));
    }

    return true;
}

bool XercesStep::operator!=(const XercesStep& other) const {

    return !operator==(other);
}

/***
 * Support for Serialization/De-serialization
 ***/

IMPL_XSERIALIZABLE_TOCREATE(XercesStep)

void XercesStep::serialize(XSerializeEngine& serEng)
{
    if (serEng.isStoring())
    {
        serEng<<(int)fAxisType;
        serEng<<fNodeTest;
    }
    else
    {
        int i;
        serEng>>i;
        fAxisType = (unsigned short) i;

        serEng>>fNodeTest;
    }
}

XercesStep::XercesStep(MemoryManager* const)
:fAxisType(UNKNOWN)
,fNodeTest(0)
{
}

// ---------------------------------------------------------------------------
//  XercesLocationPath: Constructors and Destructor
// ---------------------------------------------------------------------------
XercesLocationPath::XercesLocationPath(RefVectorOf<XercesStep>* const steps)
    : fSteps(steps)
{
}

// ---------------------------------------------------------------------------
//  XercesLocationPath: Operators
// ---------------------------------------------------------------------------
bool XercesLocationPath::operator==(const XercesLocationPath& other) const {

    unsigned int stepsSize = fSteps->size();

    if (stepsSize != other.fSteps->size())
        return false;

    for (unsigned int i=0; i < stepsSize; i++) {
        if (*(fSteps->elementAt(i)) != *(other.fSteps->elementAt(i)))
            return false;
    }

    return true;
}

bool XercesLocationPath::operator!=(const XercesLocationPath& other) const {

    return !operator==(other);
}

/***
 * Support for Serialization/De-serialization
 ***/

IMPL_XSERIALIZABLE_TOCREATE(XercesLocationPath)

void XercesLocationPath::serialize(XSerializeEngine& serEng)
{
    if (serEng.isStoring())
    {
        /***
         * Serialize RefVectorOf<XercesStep>* fSteps;
         ***/
        XTemplateSerializer::storeObject(fSteps, serEng);
    }
    else
    {
        /***
         * Deserialize RefVectorOf<XercesStep>* fSteps;
         ***/
        XTemplateSerializer::loadObject(&fSteps, 8, true, serEng);
    }
}

XercesLocationPath::XercesLocationPath(MemoryManager* const)
:fSteps(0)
{
}

typedef JanitorMemFunCall<XercesXPath>  CleanupType;

// ---------------------------------------------------------------------------
//  XercesPath: Constructors and Destructor
// ---------------------------------------------------------------------------
XercesXPath::XercesXPath(const XMLCh* const xpathExpr,
                         XMLStringPool* const stringPool,
                         NamespaceScope* const scopeContext,
                         const unsigned int emptyNamespaceId,
                         const bool isSelector,
                         MemoryManager* const manager)
    : fEmptyNamespaceId(emptyNamespaceId)
    , fExpression(0)
    , fLocationPaths(0)
    , fMemoryManager(manager)
{
    CleanupType cleanup(this, &XercesXPath::cleanUp);

    try
    {
        fExpression = XMLString::replicate(xpathExpr, fMemoryManager);
        parseExpression(stringPool, scopeContext);

        if (isSelector) {
            checkForSelectedAttributes();
        }
    }
    catch(const OutOfMemoryException&)
    {
        cleanup.release();

        throw;
    }

    cleanup.release();
}

XercesXPath::~XercesXPath() {
    cleanUp();
}


// ---------------------------------------------------------------------------
//  XercesXPath: Operators
// ---------------------------------------------------------------------------
bool XercesXPath::operator==(const XercesXPath& other) const {

    unsigned int locPathSize = fLocationPaths->size();

    if (locPathSize != other.fLocationPaths->size())
        return false;

    for (unsigned int i=0; i < locPathSize; i++) {
        if (*(fLocationPaths->elementAt(i)) != *(other.fLocationPaths->elementAt(i)))
            return false;
    }

    return true;
}

bool XercesXPath::operator!=(const XercesXPath& other) const {

    return !operator==(other);
}

// ---------------------------------------------------------------------------
//  XercesPath: Helper methods
// ---------------------------------------------------------------------------
void XercesXPath::cleanUp() {

    fMemoryManager->deallocate(fExpression);//delete [] fExpression;
    delete fLocationPaths;
}

void XercesXPath::checkForSelectedAttributes() {

    // verify that an attribute is not selected
    unsigned int locSize = (fLocationPaths) ? fLocationPaths->size() : 0;

    for (unsigned int i = 0; i < locSize; i++) {

        XercesLocationPath* locPath = fLocationPaths->elementAt(i);
        unsigned int stepSize = locPath->getStepSize();

        if (stepSize) {
            if (locPath->getStep(stepSize - 1)->getAxisType() == XercesStep::ATTRIBUTE) {
                ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoAttrSelector, fMemoryManager);
            }
		}
    }
}

void XercesXPath::parseExpression(XMLStringPool* const stringPool,
                                  NamespaceScope* const scopeContext) {

    unsigned int length = XMLString::stringLen(fExpression);

    if (!length) {
        return;
    }

    ValueVectorOf<int>                tokens(16, fMemoryManager);
    XPathScannerForSchema             scanner(stringPool);
    bool                              success = scanner.scanExpression(fExpression, 0, length, &tokens);
    bool                              firstTokenOfLocationPath=true;
    unsigned int                      tokenCount = tokens.size();
    RefVectorOf<XercesStep>*          stepsVector = new (fMemoryManager) RefVectorOf<XercesStep>(16, true, fMemoryManager);
    Janitor<RefVectorOf<XercesStep> > janSteps(stepsVector);

    if (tokenCount) {
        fLocationPaths = new (fMemoryManager) RefVectorOf<XercesLocationPath>(8, true, fMemoryManager);
    }

    for (unsigned int i = 0; i < tokenCount; i++) {

        int  aToken = tokens.elementAt(i);
        bool isNamespace=false;

        switch (aToken) {
        case  XercesXPath::EXPRTOKEN_OPERATOR_UNION:
            {
                if (i == 0) {
                    ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoUnionAtStart, fMemoryManager);
                }

                int stepsSize = stepsVector->size();

                if (stepsSize == 0) {
                    ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoMultipleUnion, fMemoryManager);
                }

                fLocationPaths->addElement(new (fMemoryManager) XercesLocationPath(stepsVector));
                janSteps.orphan();
                stepsVector = new (fMemoryManager) RefVectorOf<XercesStep>(16, true, fMemoryManager);
                janSteps.reset(stepsVector);
                firstTokenOfLocationPath = true;
            }
            break;
        case XercesXPath::EXPRTOKEN_AXISNAME_ATTRIBUTE:
            {
                // consume "::" token and drop through
                i++;
            }
        case XercesXPath::EXPRTOKEN_ATSIGN:
            {
                // consume QName token
                if (i == tokenCount - 1) {
                    ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_MissingAttr, fMemoryManager);
                }

                aToken = tokens.elementAt(++i);

                if (aToken != XercesXPath::EXPRTOKEN_NAMETEST_QNAME
                    && aToken!= XercesXPath::EXPRTOKEN_NAMETEST_ANY
                    && aToken!= XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE) {
                        ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_ExpectedToken1, fMemoryManager);
                }

                bool isNamespaceAtt=false;

                switch (aToken) {

                case XercesXPath::EXPRTOKEN_NAMETEST_ANY:
                    {
                        XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::WILDCARD, fMemoryManager);
                        XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::ATTRIBUTE, nodeTest);
                        stepsVector->addElement(step);
                        break;
                    }
                case XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE:
                    {
                        isNamespaceAtt = true;
                    }
                case XercesXPath::EXPRTOKEN_NAMETEST_QNAME:
                    {
                        aToken = tokens.elementAt(++i);

                        const XMLCh* prefix = XMLUni::fgZeroLenString;
                        unsigned int uri = fEmptyNamespaceId;

                        if (scopeContext && aToken != -1) {

                            prefix = stringPool->getValueForId(aToken);
                            uri = scopeContext->getNamespaceForPrefix(prefix);
                        }

                        if (aToken != -1 && scopeContext && uri == fEmptyNamespaceId) {
                            ThrowXMLwithMemMgr1(XPathException, XMLExcepts::XPath_PrefixNoURI, prefix, fMemoryManager);
                        }

                        if (isNamespaceAtt) {

                            // build step
                            XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(prefix, uri, fMemoryManager);
                            XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::ATTRIBUTE, nodeTest);
                            stepsVector->addElement(step);
                            break;
                        }

                        aToken = tokens.elementAt(++i);

                        const XMLCh* localPart = stringPool->getValueForId(aToken);
                        QName aQName(prefix, localPart, uri, fMemoryManager);

                        // build step
                        XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(&aQName);
                        XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::ATTRIBUTE, nodeTest);
                        stepsVector->addElement(step);
                        break;
                    }
				}

                firstTokenOfLocationPath=false;
                break;
            }
        case XercesXPath::EXPRTOKEN_DOUBLE_COLON:
            {
                // should never have a bare double colon
                ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoDoubleColon, fMemoryManager);
            }
        case XercesXPath::EXPRTOKEN_AXISNAME_CHILD:
            {
                // consume "::" token and drop through
                i++;

                if (i == tokenCount - 1) {
                    ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_ExpectedStep1, fMemoryManager);
                }

                firstTokenOfLocationPath=false;
                break;
            }
        case XercesXPath::EXPRTOKEN_NAMETEST_ANY:
            {
                XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::WILDCARD, fMemoryManager);
                XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::CHILD, nodeTest);
                stepsVector->addElement(step);
                firstTokenOfLocationPath = false;
                break;
            }
        case XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE:
            {
                isNamespace=true;
            }
        case XercesXPath::EXPRTOKEN_NAMETEST_QNAME:
            {
                // consume QName token
                aToken = tokens.elementAt(++i);

                const XMLCh* prefix = XMLUni::fgZeroLenString;
                unsigned int uri = fEmptyNamespaceId;

                if (scopeContext && aToken != -1) {

                    prefix = stringPool->getValueForId(aToken);
                    uri = scopeContext->getNamespaceForPrefix(prefix);
                }

                if (aToken != -1 && scopeContext && uri == fEmptyNamespaceId) {
                    ThrowXMLwithMemMgr1(XPathException, XMLExcepts::XPath_PrefixNoURI, prefix, fMemoryManager);
                }

                if (isNamespace) {

                    // build step
                    XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(prefix, uri, fMemoryManager);
                    XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::CHILD, nodeTest);
                    stepsVector->addElement(step);
                    break;
                }

                aToken = tokens.elementAt(++i);
                const XMLCh* localPart = stringPool->getValueForId(aToken);
                QName aQName(prefix, localPart, uri, fMemoryManager);

                // build step
                XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(&aQName);
                XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::CHILD, nodeTest);
                stepsVector->addElement(step);
                firstTokenOfLocationPath = false;
                break;
            }
        case XercesXPath::EXPRTOKEN_PERIOD:
            {
                // build step
                XercesNodeTest* nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::NODE, fMemoryManager);
                XercesStep* step = new (fMemoryManager) XercesStep(XercesStep::SELF, nodeTest);
                stepsVector->addElement(step);

                if (firstTokenOfLocationPath && i+1 < tokenCount) {

                    aToken = tokens.elementAt(i+1);

                    if (aToken == XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH){

                        if (++i == tokenCount - 1) {
                            ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_ExpectedStep2, fMemoryManager);
                        }

                        if (i+1 < tokenCount)	{

                            aToken = tokens.elementAt(i+1);

                            if (aToken == XercesXPath::EXPRTOKEN_OPERATOR_SLASH) {
                                ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoForwardSlash, fMemoryManager);
                            }
                        }
                        // build step
                        nodeTest = new (fMemoryManager) XercesNodeTest(XercesNodeTest::NODE, fMemoryManager);
                        step = new (fMemoryManager) XercesStep(XercesStep::DESCENDANT, nodeTest);
                        stepsVector->addElement(step);
                    }
                }
                firstTokenOfLocationPath=false;
                break;
            }
        case XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH:
            {
                ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoDoubleForwardSlash, fMemoryManager);
            }
        case XercesXPath::EXPRTOKEN_OPERATOR_SLASH:
            {
                if (i == 0) {
                    ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoForwardSlashAtStart, fMemoryManager);
                }

                // keep on truckin'
                if (firstTokenOfLocationPath) {
                    ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoSelectionOfRoot, fMemoryManager);
                }

                if (i == tokenCount - 1) {
                    ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_ExpectedStep3, fMemoryManager);
                }

                firstTokenOfLocationPath=false;
                break;
            }
        default:
            firstTokenOfLocationPath=false;
        }
    }

    int stepsSize = stepsVector->size();

    if (stepsSize == 0) {
        if (!fLocationPaths || fLocationPaths->size() == 0) {
            ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_EmptyExpr, fMemoryManager);
        }
        else {
            ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_NoUnionAtEnd, fMemoryManager);
        }
    }

    fLocationPaths->addElement(new (fMemoryManager) XercesLocationPath(stepsVector));
    janSteps.orphan();
}

/***
 * Support for Serialization/De-serialization
 ***/

IMPL_XSERIALIZABLE_TOCREATE(XercesXPath)

void XercesXPath::serialize(XSerializeEngine& serEng)
{

    if (serEng.isStoring())
    {
        serEng<<fEmptyNamespaceId;
        serEng.writeString(fExpression);

        /***
         * Serialize RefVectorOf<XercesLocationPath>* fLocationPaths;
         ***/
        XTemplateSerializer::storeObject(fLocationPaths, serEng);
    }
    else
    {
        serEng>>fEmptyNamespaceId;
        serEng.readString(fExpression);

        /***
         * Deserialize RefVectorOf<XercesLocationPath>* fLocationPaths;
         ***/
        XTemplateSerializer::loadObject(&fLocationPaths, 8, true, serEng);
    }
}

XercesXPath::XercesXPath(MemoryManager* const manager)
:fEmptyNamespaceId(0)
,fExpression(0)
,fLocationPaths(0)
,fMemoryManager(manager)
{
}

// ---------------------------------------------------------------------------
//  XPathScanner: Constructors and Destructor
// ---------------------------------------------------------------------------
XPathScanner::XPathScanner(XMLStringPool* const stringPool)
    : fAndSymbol (0)
    , fOrSymbol(0)
    , fModSymbol(0)
    , fDivSymbol(0)
    , fCommentSymbol(0)
    , fTextSymbol(0)
    , fPISymbol(0)
    , fNodeSymbol(0)
    , fAncestorSymbol(0)
    , fAncestorOrSelfSymbol(0)
    , fAttributeSymbol(0)
    , fChildSymbol(0)
    , fDescendantSymbol(0)
    , fDescendantOrSelfSymbol(0)
    , fFollowingSymbol(0)
    , fFollowingSiblingSymbol(0)
    , fNamespaceSymbol(0)
    , fParentSymbol(0)
    , fPrecedingSymbol(0)
    , fPrecedingSiblingSymbol(0)
    , fSelfSymbol(0)
    , fStringPool(stringPool)
{
    init();
}

// ---------------------------------------------------------------------------
//  XPathScanner: Helper methods
// ---------------------------------------------------------------------------
void XPathScanner::init() {

    fAndSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_AND);
    fOrSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_OR);
    fModSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_MOD);
    fDivSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_DIV);
    fCommentSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_COMMENT);
    fTextSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_TEXT);
    fPISymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PI);
    fNodeSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_NODE);
    fAncestorSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_ANCESTOR);
    fAncestorOrSelfSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_ANCESTOR_OR_SELF);
    fAttributeSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_ATTRIBUTE);
    fChildSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_CHILD);
    fDescendantSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_DESCENDANT);
    fDescendantOrSelfSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_DESCENDANT_OR_SELF);
    fFollowingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_FOLLOWING);
    fFollowingSiblingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_FOLLOWING_SIBLING);
    fNamespaceSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_NAMESPACE);
    fParentSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PARENT);
    fPrecedingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PRECEDING);
    fPrecedingSiblingSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_PRECEDING_SIBLING);
    fSelfSymbol = fStringPool->addOrFind(XPathSymbols::fgSYMBOL_SELF);
}


// ---------------------------------------------------------------------------
//  XPathScanner: Scan methods
// ---------------------------------------------------------------------------
bool XPathScanner::scanExpression(const XMLCh* const data,
                                  int currentOffset,
                                  const int endOffset,
                                  ValueVectorOf<int>* const tokens) {

    bool      starIsMultiplyOperator = false;
    int       nameOffset = -1;
    int       nameHandle = -1;
    int       prefixHandle = -1;
    XMLCh     ch;
    XMLBuffer dataBuffer(128, tokens->getMemoryManager());

    while (true) {

        if (currentOffset == endOffset) {
            break;
        }

        ch = data[currentOffset];

        while (XMLChar1_0::isWhitespace(ch)) {

            if (++currentOffset == endOffset) {
                break;
            }

            ch = data[currentOffset];
        }

        if (currentOffset == endOffset) {
            break;
        }
        //
        // [28] ExprToken ::= '(' | ')' | '[' | ']' | '.' | '..' | '@' | ',' | '::'
        //                  | NameTest | NodeType | Operator | FunctionName
        //                  | AxisName | Literal | Number | VariableReference
        //
        XMLByte chartype = (ch >= 0x80) ? CHARTYPE_NONASCII : fASCIICharMap[ch];

        switch (chartype) {
        case CHARTYPE_OPEN_PAREN:       // '('
            addToken(tokens, XercesXPath::EXPRTOKEN_OPEN_PAREN);
            starIsMultiplyOperator = false;
            ++currentOffset;
            break;
        case CHARTYPE_CLOSE_PAREN:      // ')'
            addToken(tokens, XercesXPath::EXPRTOKEN_CLOSE_PAREN);
            starIsMultiplyOperator = true;
            ++currentOffset;
            break;
        case CHARTYPE_OPEN_BRACKET:     // '['
            addToken(tokens, XercesXPath::EXPRTOKEN_OPEN_BRACKET);
            starIsMultiplyOperator = false;
            ++currentOffset;
            break;
        case CHARTYPE_CLOSE_BRACKET:    // ']'
            addToken(tokens, XercesXPath::EXPRTOKEN_CLOSE_BRACKET);
            starIsMultiplyOperator = true;
            ++currentOffset;
            break;
                //
                // [30] Number ::= Digits ('.' Digits?)? | '.' Digits
                //                                         ^^^^^^^^^^
                //
        case CHARTYPE_PERIOD:           // '.', '..' or '.' Digits
            if (currentOffset + 1 == endOffset) {
                addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD);
                starIsMultiplyOperator = true;
                currentOffset++;
                break;
            }

            ch = data[currentOffset + 1];

            if (ch == chPeriod) {            // '..'
                addToken(tokens, XercesXPath::EXPRTOKEN_DOUBLE_PERIOD);
                starIsMultiplyOperator = true;
                currentOffset += 2;
            } else if (ch >= chDigit_0 && ch <= chDigit_9) {
                addToken(tokens, XercesXPath::EXPRTOKEN_NUMBER);
                starIsMultiplyOperator = true;
                currentOffset = scanNumber(data, endOffset, currentOffset, tokens);
            } else if (ch == chForwardSlash) {
                addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD);
                starIsMultiplyOperator = true;
                currentOffset++;
            } else if (ch == chPipe) { // '|'
                addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD);
                starIsMultiplyOperator = true;
                currentOffset++;
            } else if (XMLChar1_0::isWhitespace(ch)) {
                do {
                    if (++currentOffset == endOffset)
                        break;

                    ch = data[currentOffset];
                } while (XMLChar1_0::isWhitespace(ch));

                if (currentOffset == endOffset || ch == chPipe) {
				    addToken(tokens, XercesXPath::EXPRTOKEN_PERIOD);
                    starIsMultiplyOperator = true;
                    break;
                }
            } else {
                XMLCh str[2]= {ch, 0 };
                ThrowXMLwithMemMgr1(XPathException, XMLExcepts::XPath_InvalidChar, str, tokens->getMemoryManager());
            }

            break;
        case CHARTYPE_ATSIGN:           // '@'
            addToken(tokens, XercesXPath::EXPRTOKEN_ATSIGN);
            starIsMultiplyOperator = false;
            ++currentOffset;
            break;
        case CHARTYPE_COMMA:            // ','
            addToken(tokens, XercesXPath::EXPRTOKEN_COMMA);
            starIsMultiplyOperator = false;
            ++currentOffset;
            break;
        case CHARTYPE_COLON:            // '::'
            if (++currentOffset == endOffset) {
                return false; // REVISIT
            }
            ch = data[currentOffset];

            if (ch != chColon) {
                return false; // REVISIT
            }
            addToken(tokens, XercesXPath::EXPRTOKEN_DOUBLE_COLON);
            starIsMultiplyOperator = false;
            ++currentOffset;
            break;
        case CHARTYPE_SLASH:            // '/' and '//'
            if (++currentOffset == endOffset) {
                addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_SLASH);
                starIsMultiplyOperator = false;
                break;
            }

            ch = data[currentOffset];

            if (ch == chForwardSlash) { // '//'
                addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH);
                starIsMultiplyOperator = false;
                ++currentOffset;
            } else {
                addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_SLASH);
                starIsMultiplyOperator = false;
            }
            break;
        case CHARTYPE_UNION:            // '|'
            addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_UNION);
            starIsMultiplyOperator = false;
            ++currentOffset;
            break;
        case CHARTYPE_PLUS:             // '+'
            addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_PLUS);
            starIsMultiplyOperator = false;
            ++currentOffset;
            break;
        case CHARTYPE_MINUS:            // '-'
            addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_MINUS);
            starIsMultiplyOperator = false;
            ++currentOffset;
            break;
        case CHARTYPE_EQUAL:            // '='
            addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_EQUAL);
            starIsMultiplyOperator = false;
            ++currentOffset;
            break;
        case CHARTYPE_EXCLAMATION:      // '!='
            if (++currentOffset == endOffset) {
                return false; // REVISIT
            }

            ch = data[currentOffset];

            if (ch != chEqual) {
                return false; // REVISIT
            }

            addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_NOT_EQUAL);
            starIsMultiplyOperator = false;
            ++currentOffset;
            break;
        case CHARTYPE_LESS: // '<' and '<='
            if (++currentOffset == endOffset) {
                addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_LESS);
                starIsMultiplyOperator = false;
                break;
            }

            ch = data[currentOffset];

            if (ch == chEqual) { // '<='
                addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_LESS_EQUAL);
                starIsMultiplyOperator = false;
                ++currentOffset;
            } else {
                addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_LESS);
                starIsMultiplyOperator = false;
            }
            break;
        case CHARTYPE_GREATER: // '>' and '>='
            if (++currentOffset == endOffset) {
                addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_GREATER);
                starIsMultiplyOperator = false;
                break;
            }

            ch = data[currentOffset];

            if (ch == chEqual) { // '>='
                addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_GREATER_EQUAL);
                starIsMultiplyOperator = false;
                ++currentOffset;
            } else {
                addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_GREATER);
                starIsMultiplyOperator = false;
            }
            break;
        //
        // [29] Literal ::= '"' [^"]* '"' | "'" [^']* "'"
        //
        case CHARTYPE_QUOTE:            // '\"' or '\''
            {
                XMLCh qchar = ch;
                if (++currentOffset == endOffset) {
                    return false; // REVISIT
                }

                ch = data[currentOffset];

                int litOffset = currentOffset;
                while (ch != qchar) {
                    if (++currentOffset == endOffset) {
                        return false; // REVISIT
                    }

                    ch = data[currentOffset];
                }

                addToken(tokens, XercesXPath::EXPRTOKEN_LITERAL);
                starIsMultiplyOperator = true;

                dataBuffer.set(data + litOffset, currentOffset - litOffset);
                tokens->addElement(fStringPool->addOrFind(dataBuffer.getRawBuffer()));
                ++currentOffset;
                break;
            }
        //
        // [30] Number ::= Digits ('.' Digits?)? | '.' Digits
        // [31] Digits ::= [0-9]+
        //
        case CHARTYPE_DIGIT:
            addToken(tokens, XercesXPath::EXPRTOKEN_NUMBER);
            starIsMultiplyOperator = true;
            currentOffset = scanNumber(data, endOffset, currentOffset, tokens);
            break;
        //
        // [36] VariableReference ::= '$' QName
        //
        case CHARTYPE_DOLLAR:
            if (++currentOffset == endOffset) {
                return false; // REVISIT
            }
            nameOffset = currentOffset;
            currentOffset = scanNCName(data, endOffset, currentOffset);

            if (currentOffset == nameOffset) {
                return false; // REVISIT
            }

            if (currentOffset < endOffset) {
                ch = data[currentOffset];
            }
            else {
                ch = 0;
            }

            dataBuffer.set(data + nameOffset, currentOffset - nameOffset);
            nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer());
            prefixHandle = -1;

            if (ch == chColon) {

                prefixHandle = nameHandle;
                if (++currentOffset == endOffset) {
                    return false; // REVISIT
                }
                nameOffset = currentOffset;
                currentOffset = scanNCName(data, endOffset, currentOffset);

                if (currentOffset == nameOffset) {
                    return false; // REVISIT
                }

                dataBuffer.set(data + nameOffset, currentOffset - nameOffset);
                nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer());
            }
            addToken(tokens, XercesXPath::EXPRTOKEN_VARIABLE_REFERENCE);
            starIsMultiplyOperator = true;
            tokens->addElement(prefixHandle);
            tokens->addElement(nameHandle);
            break;
        //
        // [37] NameTest ::= '*' | NCName ':' '*' | QName
        // [34] MultiplyOperator ::= '*'
        //
        case CHARTYPE_STAR:             // '*'
            //
            // 3.7 Lexical Structure
            //
            //  If there is a preceding token and the preceding token is not one of @, ::, (, [, , or
            //  an Operator, then a * must be recognized as a MultiplyOperator.
            //
            // Otherwise, the token must not be recognized as a MultiplyOperator.
            //
            if (starIsMultiplyOperator) {
                addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_MULT);
                starIsMultiplyOperator = false;
            } else {
                addToken(tokens, XercesXPath::EXPRTOKEN_NAMETEST_ANY);
                starIsMultiplyOperator = true;
            }

            ++currentOffset;
            break;
        //
        // NCName, QName and non-terminals
        //
        case CHARTYPE_NONASCII: // possibly a valid non-ascii 'Letter' (BaseChar | Ideographic)
        case CHARTYPE_LETTER:
        case CHARTYPE_UNDERSCORE:
            {
            //
            // 3.7 Lexical Structure
            //
            //  If there is a preceding token and the preceding token is not one of @, ::, (, [, , or
            //  an Operator, then an NCName must be recognized as an OperatorName.
            //
            //  If the character following an NCName (possibly after intervening ExprWhitespace) is (,
            //  then the token must be recognized as a NodeType or a FunctionName.
            //
            //  If the two characters following an NCName (possibly after intervening ExprWhitespace)
            //  are ::, then the token must be recognized as an AxisName.
            //
            //  Otherwise, the token must not be recognized as an OperatorName, a NodeType, a
            //  FunctionName, or an AxisName.
            //
            // [33] OperatorName ::= 'and' | 'or' | 'mod' | 'div'
            // [38] NodeType ::= 'comment' | 'text' | 'processing-instruction' | 'node'
            // [35] FunctionName ::= QName - NodeType
            // [6] AxisName ::= (see above)
            //
            // [37] NameTest ::= '*' | NCName ':' '*' | QName
            // [5] NCName ::= (Letter | '_') (NCNameChar)*
            // [?] NCNameChar ::= Letter | Digit | '.' | '-' | '_'  (ascii subset of 'NCNameChar')
            // [?] QName ::= (NCName ':')? NCName
            // [?] Letter ::= [A-Za-z]                              (ascii subset of 'Letter')
            // [?] Digit ::= [0-9]                                  (ascii subset of 'Digit')
            //
            nameOffset = currentOffset;
            currentOffset = scanNCName(data, endOffset, currentOffset);
            if (currentOffset == nameOffset) {
                return false; // REVISIT
			}

            if (currentOffset < endOffset) {
                ch = data[currentOffset];
            }
            else {
                ch = 0;
            }

            dataBuffer.set(data + nameOffset, currentOffset - nameOffset);
            nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer());

            bool isNameTestNCName = false;
            bool isAxisName = false;
            prefixHandle = -1;

            if (ch == chColon) {

                if (++currentOffset == endOffset) {
                    return false; // REVISIT
                }

                ch = data[currentOffset];

                if (ch == chAsterisk) {
                    if (++currentOffset < endOffset) {
                        ch = data[currentOffset];
                    }

                    isNameTestNCName = true;
                } else if (ch == chColon) {
                    if (++currentOffset < endOffset) {
                        ch = data[currentOffset];
                    }

                    isAxisName = true;
                } else {
                    prefixHandle = nameHandle;
                    nameOffset = currentOffset;
                    currentOffset = scanNCName(data, endOffset, currentOffset);
                    if (currentOffset == nameOffset) {
                        return false; // REVISIT
                    }
                    if (currentOffset < endOffset) {
                        ch = data[currentOffset];
                    }
                    else {
                        ch = 0;
                    }

                    dataBuffer.set(data + nameOffset, currentOffset - nameOffset);
                    nameHandle = fStringPool->addOrFind(dataBuffer.getRawBuffer());
                }
            }
            //
            // [39] ExprWhitespace ::= S
            //
            while (XMLChar1_0::isWhitespace(ch)) {
                if (++currentOffset == endOffset) {
                    break;
                }
                ch = data[currentOffset];
            }

            //
            //  If there is a preceding token and the preceding token is not one of @, ::, (, [, , or
            //  an Operator, then an NCName must be recognized as an OperatorName.
            //
            if (starIsMultiplyOperator) {
                if (nameHandle == fAndSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_AND);
                    starIsMultiplyOperator = false;
                } else if (nameHandle == fOrSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_OR);
                    starIsMultiplyOperator = false;
                } else if (nameHandle == fModSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_MOD);
                    starIsMultiplyOperator = false;
                } else if (nameHandle == fDivSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_OPERATOR_DIV);
                    starIsMultiplyOperator = false;
                } else {
                    return false; // REVISIT
                }

                if (isNameTestNCName) {
                    return false; // REVISIT - NCName:* where an OperatorName is required
                } else if (isAxisName) {
                    return false; // REVISIT - AxisName:: where an OperatorName is required
                }
                break;
            }
            //
            //  If the character following an NCName (possibly after intervening ExprWhitespace) is (,
            //  then the token must be recognized as a NodeType or a FunctionName.
            //
            if (ch == chOpenParen && !isNameTestNCName && !isAxisName) {
                if (nameHandle == fCommentSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_COMMENT);
                } else if (nameHandle == fTextSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_TEXT);
                } else if (nameHandle == fPISymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_PI);
                } else if (nameHandle == fNodeSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_NODETYPE_NODE);
                } else {
                    addToken(tokens, XercesXPath::EXPRTOKEN_FUNCTION_NAME);
                    tokens->addElement(prefixHandle);
                    tokens->addElement(nameHandle);
                }
                addToken(tokens, XercesXPath::EXPRTOKEN_OPEN_PAREN);
                starIsMultiplyOperator = false;
                ++currentOffset;
                break;
            }

            //
            //  If the two characters following an NCName (possibly after intervening ExprWhitespace)
            //  are ::, then the token must be recognized as an AxisName.
            //
            if (isAxisName ||
                (ch == chColon && currentOffset + 1 < endOffset &&
                 data[currentOffset + 1] == chColon)) {

                if (nameHandle == fAncestorSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_ANCESTOR);
                } else if (nameHandle == fAncestorOrSelfSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_ANCESTOR_OR_SELF);
                } else if (nameHandle == fAttributeSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_ATTRIBUTE);
                } else if (nameHandle == fChildSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_CHILD);
                } else if (nameHandle == fDescendantSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_DESCENDANT);
                } else if (nameHandle == fDescendantOrSelfSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_DESCENDANT_OR_SELF);
                } else if (nameHandle == fFollowingSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_FOLLOWING);
                } else if (nameHandle == fFollowingSiblingSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_FOLLOWING_SIBLING);
                } else if (nameHandle == fNamespaceSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_NAMESPACE);
                } else if (nameHandle == fParentSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_PARENT);
                } else if (nameHandle == fPrecedingSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_PRECEDING);
                } else if (nameHandle == fPrecedingSiblingSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_PRECEDING_SIBLING);
                } else if (nameHandle == fSelfSymbol) {
                    addToken(tokens, XercesXPath::EXPRTOKEN_AXISNAME_SELF);
                } else {
                    return false; // REVISIT
                }

                if (isNameTestNCName) {
                    return false; // REVISIT - "NCName:* ::" where "AxisName ::" is required
                }

                addToken(tokens, XercesXPath::EXPRTOKEN_DOUBLE_COLON);
                starIsMultiplyOperator = false;
                if (!isAxisName) {
                    currentOffset += 2;
                }
                break;
            }
            //
            //  Otherwise, the token must not be recognized as an OperatorName, a NodeType, a
            //  FunctionName, or an AxisName.
            //
            if (isNameTestNCName) {
                addToken(tokens, XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE);
                tokens->addElement(nameHandle);
            } else {
                addToken(tokens, XercesXPath::EXPRTOKEN_NAMETEST_QNAME);
                tokens->addElement(prefixHandle);
                tokens->addElement(nameHandle);
            }

            starIsMultiplyOperator = true;
            break;
            }
        default:
            {
            XMLCh str[2]= {ch, 0 };
            ThrowXMLwithMemMgr1(XPathException, XMLExcepts::XPath_InvalidChar, str, tokens->getMemoryManager());
            break;
            }
        }
    }

    return true;
}


int XPathScanner::scanNCName(const XMLCh* const data,
                             const int endOffset,
                             int currentOffset) {

    XMLCh ch = data[currentOffset];

    if (!XMLChar1_0::isFirstNCNameChar(ch)) {
        return currentOffset;
    }

    while (++currentOffset < endOffset) {

        ch = data[currentOffset];

        if (!XMLChar1_0::isNCNameChar(ch)) {
            break;
        }
    }

    return currentOffset;
}


int XPathScanner::scanNumber(const XMLCh* const data,
                             const int endOffset,
                             int currentOffset,
                             ValueVectorOf<int>* const tokens) {

    XMLCh ch = data[currentOffset];
    int   whole = 0;
    int   part = 0;

    while (ch >= chDigit_0 && ch <= chDigit_9) {

        whole = (whole * 10) + (ch - chDigit_0);

        if (++currentOffset == endOffset) {
            break;
        }

        ch = data[currentOffset];
    }

    if (ch == chPeriod) {

        if (++currentOffset < endOffset) {

            ch = data[currentOffset];

            while (ch >= chDigit_0 && ch <= chDigit_9) {

                part = (part * 10) + (ch - chDigit_0);

                if (++currentOffset == endOffset) {
                    break;
                }

                ch = data[currentOffset];
            }

            if (part != 0) {
                ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::XPath_FindSolution, tokens->getMemoryManager());
            }
        }
    }

    tokens->addElement(whole);
    tokens->addElement(part);

    return currentOffset;
}


// ---------------------------------------------------------------------------
//  XPathScannerForSchema: Constructors and Destructor
// ---------------------------------------------------------------------------
XPathScannerForSchema::XPathScannerForSchema(XMLStringPool* const stringPool)
    : XPathScanner(stringPool)
{
}


// ---------------------------------------------------------------------------
//  XPathScannerForSchema: Helper methods
// ---------------------------------------------------------------------------
void XPathScannerForSchema::addToken(ValueVectorOf<int>* const tokens,
                                     const int aToken) {

    if (aToken == XercesXPath::EXPRTOKEN_ATSIGN ||
        aToken == XercesXPath::EXPRTOKEN_AXISNAME_ATTRIBUTE ||
        aToken == XercesXPath::EXPRTOKEN_AXISNAME_CHILD ||
        //token == XercesXPath::EXPRTOKEN_AXISNAME_SELF ||
        aToken == XercesXPath::EXPRTOKEN_DOUBLE_COLON ||
        aToken == XercesXPath::EXPRTOKEN_NAMETEST_QNAME ||
        //token == XercesXPath::EXPRTOKEN_NODETYPE_NODE ||
        aToken == XercesXPath::EXPRTOKEN_OPERATOR_SLASH ||
        aToken == XercesXPath::EXPRTOKEN_PERIOD ||
        aToken == XercesXPath::EXPRTOKEN_NAMETEST_ANY ||
        aToken == XercesXPath::EXPRTOKEN_NAMETEST_NAMESPACE ||
        aToken == XercesXPath::EXPRTOKEN_OPERATOR_DOUBLE_SLASH ||
        aToken == XercesXPath::EXPRTOKEN_OPERATOR_UNION) {

        tokens->addElement(aToken);
        return;
    }

    ThrowXMLwithMemMgr(XPathException, XMLExcepts::XPath_TokenNotSupported, tokens->getMemoryManager());
}

XERCES_CPP_NAMESPACE_END

/**
  * End of file XercesPath.cpp
  */

