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

#include "StylesheetExecutionContextDefault.hpp"



#include <algorithm>
#include <cassert>



#include <xalanc/Include/STLHelper.hpp>



#include <xalanc/PlatformSupport/DOMStringPrintWriter.hpp>
#include <xalanc/PlatformSupport/XalanOutputStream.hpp>
#include <xalanc/PlatformSupport/XalanNumberFormat.hpp>
#include <xalanc/PlatformSupport/XalanOutputStreamPrintWriter.hpp>
#include <xalanc/PlatformSupport/XalanStdOutputStream.hpp>
#include <xalanc/PlatformSupport/XalanFileOutputStream.hpp>
#include <xalanc/PlatformSupport/XalanFStreamOutputStream.hpp>
#include <xalanc/PlatformSupport/XalanMessageLoader.hpp>
#include <xalanc/PlatformSupport/XalanTranscodingServices.hpp>



#include <xalanc/XPath/XObjectFactory.hpp>
#include <xalanc/XPath/XPath.hpp>
#include <xalanc/XPath/XPathEnvSupport.hpp>
#include <xalanc/XPath/XPathExecutionContext.hpp>
#include <xalanc/XPath/XObject.hpp>



#include <xalanc/XMLSupport/XalanXMLSerializerFactory.hpp>
#include <xalanc/XMLSupport/FormatterToHTML.hpp>
#include <xalanc/XMLSupport/FormatterToText.hpp>
#include <xalanc/XMLSupport/XMLParserLiaison.hpp>



#include <xalanc/XalanSourceTree/FormatterToSourceTree.hpp>
#include <xalanc/XalanSourceTree/XalanSourceTreeDocument.hpp>
#include <xalanc/XalanSourceTree/XalanSourceTreeDocumentFragment.hpp>



#include "Constants.hpp"
#include "ElemTemplateElement.hpp"
#include "ElemWithParam.hpp"
#include "KeyTable.hpp"
#include "StylesheetConstructionContextDefault.hpp"
#include "StylesheetRoot.hpp"
#include "XSLTEngineImpl.hpp"
#include "XSLTProcessorException.hpp"



//#define XALAN_VQ_SPECIAL_TRACE
#if defined(XALAN_VQ_SPECIAL_TRACE)
#include "C:/Program Files/Rational/Quantify/pure.h"
#endif



namespace XALAN_CPP_NAMESPACE {



StylesheetExecutionContextDefault::XalanNumberFormatFactory         StylesheetExecutionContextDefault::s_defaultXalanNumberFormatFactory;

StylesheetExecutionContextDefault::XalanNumberFormatFactory*        StylesheetExecutionContextDefault::s_xalanNumberFormatFactory =
        &StylesheetExecutionContextDefault::getDefaultXalanNumberFormatFactory();

const StylesheetExecutionContextDefault::DefaultCollationCompareFunctor     StylesheetExecutionContextDefault::s_defaultCollationFunctor;



StylesheetExecutionContextDefault::StylesheetExecutionContextDefault(
            MemoryManager&      theManager,
            XSLTEngineImpl&         xsltProcessor,
            XPathEnvSupport&        theXPathEnvSupport,
            DOMSupport&             theDOMSupport,
            XObjectFactory&         theXObjectFactory,
            XalanNode*              theCurrentNode,
            const NodeRefListBase*  theContextNodeList,
            const PrefixResolver*   thePrefixResolver) :
    StylesheetExecutionContext(theManager, &theXObjectFactory),
    m_xpathExecutionContextDefault(theXPathEnvSupport,
                                   theDOMSupport,
                                   theXObjectFactory,
                                   theCurrentNode,
                                   theContextNodeList,
                                   thePrefixResolver),
    m_xsltProcessor(&xsltProcessor),
    m_rootDocument(0),
    m_elementRecursionStack(theManager),
    m_stylesheetRoot(0),
    m_formatterListeners(theManager),
    m_printWriters(theManager),
    m_outputStreams(theManager),
    m_collationCompareFunctor(0),
    m_formatNumberFunctor(0),
    m_variablesStack(theManager),
    m_paramsVector(theManager),
    m_matchPatternCache(theManager),
    m_keyTables(theManager),
    m_countersTable(theManager),
    m_sourceTreeResultTreeFactory(),
    m_mode(0),
    m_currentTemplateStack(theManager),
    m_indentAmount(-1),
    m_xresultTreeFragAllocator(theManager, eXResultTreeFragAllocatorBlockSize),
    m_documentFragmentAllocator(theManager, eDocumentFragmentAllocatorBlockSize),
    m_documentAllocator(theManager, eDocumentAllocatorBlockSize),
    m_copyTextNodesOnlyStack(theManager),
    m_modeStack(theManager),
    m_currentIndexStack(theManager),
#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
    m_xobjectPtrStack(theManager),
    m_mutableNodeRefListStack(theManager),
    m_nodesToTransformStack(theManager),
    m_processCurrentAttributeStack(theManager),
    m_executeIfStack(theManager),
    m_stringStack(theManager),
    m_formatterToTextStack(theManager),
    m_skipElementAttributesStack(theManager),
    m_formatterToSourceTreeStack(theManager),
    m_paramsVectorStack(theManager),
    m_elementInvokerStack(theManager),
    m_useAttributeSetIndexesStack(theManager),
    m_nodeSorter(theManager),
#else
    m_formatterToTextCache(theManager),
    m_formatterToSourceTreeCache(theManager),
    m_nodeSorterCache(theManager),
#endif
    m_usePerInstanceDocumentFactory(false),
    m_escapeURLs(eEscapeURLsDefault),
    m_omitMETATag(eOmitMETATagDefault)
{
    m_currentTemplateStack.push_back(0);
}



StylesheetExecutionContextDefault::StylesheetExecutionContextDefault(
            MemoryManager&          theManager,
            XalanNode*              theCurrentNode,
            const NodeRefListBase*  theContextNodeList,
            const PrefixResolver*   thePrefixResolver) :
    StylesheetExecutionContext(theManager),
    m_xpathExecutionContextDefault(theManager,
                                   theCurrentNode,
                                   theContextNodeList,
                                   thePrefixResolver),
    m_xsltProcessor(0),
    m_rootDocument(0),
    m_elementRecursionStack(theManager),
    m_stylesheetRoot(0),
    m_formatterListeners(theManager),
    m_printWriters(theManager),
    m_outputStreams(theManager),
    m_collationCompareFunctor(0),
    m_formatNumberFunctor(0),
    m_variablesStack(theManager),
    m_paramsVector(theManager),
    m_matchPatternCache(theManager),
    m_keyTables(theManager),
    m_countersTable(theManager),
    m_sourceTreeResultTreeFactory(),
    m_mode(0),
    m_currentTemplateStack(theManager),
    m_indentAmount(-1),
    m_xresultTreeFragAllocator(theManager, eXResultTreeFragAllocatorBlockSize),
    m_documentFragmentAllocator(theManager, eDocumentFragmentAllocatorBlockSize),
    m_documentAllocator(theManager, eDocumentAllocatorBlockSize),
    m_copyTextNodesOnlyStack(theManager),
    m_modeStack(theManager),
    m_currentIndexStack(theManager),
#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
    m_xobjectPtrStack(theManager),
    m_mutableNodeRefListStack(theManager),
    m_nodesToTransformStack(theManager),
    m_processCurrentAttributeStack(theManager),
    m_executeIfStack(theManager),
    m_stringStack(theManager),
    m_formatterToTextStack(theManager),
    m_skipElementAttributesStack(theManager),
    m_formatterToSourceTreeStack(theManager),
    m_paramsVectorStack(theManager),
    m_elementInvokerStack(theManager),
    m_useAttributeSetIndexesStack(theManager),
    m_nodeSorter(theManager),
#else
    m_formatterToTextCache(theManager),
    m_formatterToSourceTreeCache(theManager),
    m_nodeSorterCache(theManager),
#endif
    m_usePerInstanceDocumentFactory(false),
    m_escapeURLs(eEscapeURLsDefault),
    m_omitMETATag(eOmitMETATagDefault)
{
    m_currentTemplateStack.push_back(0);
}



StylesheetExecutionContextDefault*
StylesheetExecutionContextDefault::create(
            MemoryManager&          theManager,
            XalanNode*              theCurrentNode,
            const NodeRefListBase*  theContextNodeList,
            const PrefixResolver*   thePrefixResolver)
{
    typedef StylesheetExecutionContextDefault   ThisType;

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

    ThisType* const     theResult =
        new (theGuard.get()) ThisType(
                                theManager,
                                theCurrentNode,
                                theContextNodeList,
                                thePrefixResolver);
    theGuard.release();

    return theResult;
}



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



void
StylesheetExecutionContextDefault::problem(
            eSource                 source,
            eClassification         classification,
            const XalanDOMString&   msg,
            const Locator*          locator,
            const XalanNode*        sourceNode)
{
    m_xsltProcessor->problem(
        source,
        classification,
        msg,
        locator,
        sourceNode);
}



void
StylesheetExecutionContextDefault::problem(
            eSource                 source,
            eClassification         classification,
            const XalanDOMString&   msg,
            const XalanNode*        sourceNode)
{
    m_xsltProcessor->problem(
        source,
        classification,
        msg,
        sourceNode);
}



bool
StylesheetExecutionContextDefault::getQuietConflictWarnings() const
{
    assert(m_xsltProcessor != 0);

    return m_xsltProcessor->getQuietConflictWarnings();
}



bool
StylesheetExecutionContextDefault::getCopyTextNodesOnly() const
{
    if (m_copyTextNodesOnlyStack.size() == 0)
    {
        return false;
    }
    else
    {
        return m_copyTextNodesOnlyStack.back();
    }
}





XalanNode*
StylesheetExecutionContextDefault::getRootDocument() const
{
    return m_rootDocument;
}



void
StylesheetExecutionContextDefault::setRootDocument(XalanNode*   theDocument)
{
    m_rootDocument = theDocument;
}



void
StylesheetExecutionContextDefault::setStylesheetRoot(const StylesheetRoot*  theStylesheet)
{
    assert(m_xsltProcessor != 0);

    m_stylesheetRoot = theStylesheet;

    m_hasPreserveOrStripConditions = theStylesheet->hasPreserveOrStripSpaceElements();

    m_xsltProcessor->setStylesheetRoot(theStylesheet);

    if (theStylesheet == 0)
    {
        m_xsltProcessor->setExecutionContext(0);
    }
    else
    {
        m_xsltProcessor->setExecutionContext(this);

        m_countersTable.resize(theStylesheet->getElemNumberCount());
    }
}



const XalanQName*
StylesheetExecutionContextDefault::getCurrentMode() const
{
    if (m_modeStack.size() == 0) 
    {
        return 0;
    }
    else
    {
        return m_modeStack.back();
    }
}



void
StylesheetExecutionContextDefault::pushCurrentMode(const XalanQName*        theMode)
{       
    m_modeStack.push_back(theMode);
}



void
StylesheetExecutionContextDefault::popCurrentMode()
{       
    m_modeStack.pop_back();
}




const ElemTemplate*
StylesheetExecutionContextDefault::getCurrentTemplate() const
{
    return m_currentTemplateStack.back();
}



void
StylesheetExecutionContextDefault::pushCurrentTemplate(const ElemTemplate*  theTemplate)
{       
    m_currentTemplateStack.push_back(theTemplate);
}



void
StylesheetExecutionContextDefault::popCurrentTemplate()
{       
    m_currentTemplateStack.pop_back();
}



bool
StylesheetExecutionContextDefault::isElementPending() const
{
    assert(m_xsltProcessor != 0);

    return m_xsltProcessor->isElementPending();
}



void
StylesheetExecutionContextDefault::replacePendingAttribute(
            const XalanDOMChar*     theName,
            const XalanDOMChar*     theNewType,
            const XalanDOMChar*     theNewValue)
{
    assert(m_xsltProcessor != 0);

    // Remove the old attribute, then add the new one.  AttributeListImpl::addAttribute()
    // does this for us.
    m_xsltProcessor->replacePendingAttribute(theName, theNewType, theNewValue);
}



void
StylesheetExecutionContextDefault::pushOutputContext(FormatterListener*     flistener)
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->pushOutputContext(flistener);
}



void
StylesheetExecutionContextDefault::popOutputContext()
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->popOutputContext();
}



void
StylesheetExecutionContextDefault::addResultAttribute(
            const XalanDOMString&   aname,
            const XalanDOMString&   value)
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->addResultAttribute(aname, value);
}



void
StylesheetExecutionContextDefault::addResultAttribute(
            const XalanDOMString&   aname,
            const XalanDOMChar*     value)
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->addResultAttribute(aname, value);
}



void
StylesheetExecutionContextDefault::copyNamespaceAttributes(const XalanNode&     src)
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->copyNamespaceAttributes(src);
}



const XalanDOMString*
StylesheetExecutionContextDefault::getResultPrefixForNamespace(const XalanDOMString&    theNamespace) const
{
    assert(m_xsltProcessor != 0);

    return m_xsltProcessor->getResultPrefixForNamespace(theNamespace);
}



const XalanDOMString*
StylesheetExecutionContextDefault::getResultNamespaceForPrefix(const XalanDOMString&    thePrefix) const
{
    assert(m_xsltProcessor != 0);

    return m_xsltProcessor->getResultNamespaceForPrefix(thePrefix);
}



bool
StylesheetExecutionContextDefault::isPendingResultPrefix(const XalanDOMString&  thePrefix)
{
    assert(m_xsltProcessor != 0);

    return m_xsltProcessor->isPendingResultPrefix(thePrefix);
}


void
StylesheetExecutionContextDefault::getUniqueNamespaceValue(XalanDOMString&  theValue) const
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->getUniqueNamespaceValue(theValue);
}



FormatterListener*
StylesheetExecutionContextDefault::getFormatterListener() const
{
    assert(m_xsltProcessor != 0);

    return m_xsltProcessor->getFormatterListener();
}



void
StylesheetExecutionContextDefault::setFormatterListener(FormatterListener*  flistener)
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->setFormatterListener(flistener);
}



int
StylesheetExecutionContextDefault::getIndent() const
{
    if (m_indentAmount != -1)
    {
        return m_indentAmount;
    }
    else
    {
        assert(m_xsltProcessor != 0);

        return m_xsltProcessor->getXMLParserLiaison().getIndent();
    }
}



void
StylesheetExecutionContextDefault::setIndent(int    indentAmount)
{
    m_indentAmount = indentAmount;
}



const XPath*
StylesheetExecutionContextDefault::createMatchPattern(
            const XalanDOMString&   str,
            const PrefixResolver&   resolver)
{
    assert(m_xsltProcessor != 0);

    const XPath*    theResult = 0;

    // We won't cache any xpath that has a namespace, since
    // we have no idea how that might be resolved.  We could
    // enhance XPath so that we can tell if str would match
    // the XPath, once the namespace is resolved, but it may
    // not be worth it...
    const XalanDOMString::size_type     index = indexOf(str, XalanUnicode::charColon);
    const XalanDOMString::size_type     len = str.length();

    // If we found a ':' before the end of the string, and
    // it's by itself (:: would indicate an axis), don't
    // try to cache the XPath...
    if (index < len - 1 && str[index + 1] != XalanUnicode::charColon)
    {
        theResult = m_xsltProcessor->createMatchPattern(str, resolver);
    }
    else
    {
        const XPathCacheMapType::iterator   i =
            m_matchPatternCache.find(str);

        if (i != m_matchPatternCache.end())
        {
            // Update hit time...
            (*i).second.second = std::clock();

            theResult = (*i).second.first;
        }
        else
        {
            theResult = m_xsltProcessor->createMatchPattern(str, resolver);

            addToXPathCache(str, theResult);
        }
    }

    return theResult;
}



void
StylesheetExecutionContextDefault::returnXPath(const XPath*     xpath)
{
    assert(m_xsltProcessor != 0);

    if (isCached(xpath) == false)
    {
        m_xsltProcessor->returnXPath(xpath);
    }
}



void
StylesheetExecutionContextDefault::pushTopLevelVariables(const ParamVectorType&     topLevelParams)
{
    assert(m_stylesheetRoot != 0);

    m_stylesheetRoot->pushTopLevelVariables(*this, topLevelParams);
}



const XObjectPtr
StylesheetExecutionContextDefault::createVariable(
            const XPath&                xpath,
            XalanNode*                  contextNode,
            const PrefixResolver&       resolver)
{
    XalanNode* const    theCurrentNode = getCurrentNode();
            
    if (theCurrentNode == contextNode)
    {
        return xpath.execute(resolver, *this);
    }
    else
    {
        return xpath.execute(contextNode, resolver, *this);
    }
}


#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
const XObjectPtr
StylesheetExecutionContextDefault::createVariable(
            const ElemTemplateElement&  templateChild,
            XalanNode*                  sourceNode)
{
    return createXResultTreeFrag(templateChild, sourceNode);
}
#endif



void
StylesheetExecutionContextDefault::pushVariable(
            const XalanQName&           name,
            const ElemTemplateElement*  element,
            const XalanDOMString&       str,
            XalanNode*                  contextNode,
            const PrefixResolver&       resolver)
{
    assert(m_xsltProcessor != 0);

    if (str.empty() == false)
    {
        m_variablesStack.pushVariable(
            name,
            m_xsltProcessor->evalXPathStr(
                            str,
                            contextNode,
                            resolver,
                            *this),
            element);
    }
}



void
StylesheetExecutionContextDefault::pushVariable(
            const XalanQName&           name,
            const XObjectPtr            val,
            const ElemTemplateElement*  element)
{
    m_variablesStack.pushVariable(name, val, element);
}



void
StylesheetExecutionContextDefault::pushVariable(
            const XalanQName&           name,
            const ElemVariable*         var,
            const ElemTemplateElement*  element)
{
    m_variablesStack.pushVariable(name, var, element);
}



void
StylesheetExecutionContextDefault::pushVariable(
            const XalanQName&           name,
            const ElemTemplateElement*  element,
            const XPath&                xpath,
            XalanNode*                  contextNode,
            const PrefixResolver&       resolver)
{
    m_variablesStack.pushVariable(name, xpath.execute(contextNode, resolver, *this), element);
}



#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
void
StylesheetExecutionContextDefault::pushVariable(
            const XalanQName&           name,
            const ElemTemplateElement*  element,
            const ElemTemplateElement&  templateChild,
            XalanNode*                  sourceNode)
{

    m_variablesStack.pushVariable(name, createXResultTreeFrag(templateChild, sourceNode), element);
}
#endif



void
StylesheetExecutionContextDefault::pushContextMarker()
{
    m_variablesStack.pushContextMarker();
}



void
StylesheetExecutionContextDefault::popContextMarker()
{
    m_variablesStack.popContextMarker();
}



void
StylesheetExecutionContextDefault::resolveTopLevelParams()
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->resolveTopLevelParams(*this);

    m_variablesStack.markGlobalStackFrame();
}



void
StylesheetExecutionContextDefault::clearTopLevelParams()
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->clearTopLevelParams();

    m_variablesStack.unmarkGlobalStackFrame();
}



#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
void
StylesheetExecutionContextDefault::beginParams()
{
    m_paramsVectorStack.resize(m_paramsVectorStack.size() + 1);
}



void
StylesheetExecutionContextDefault::endParams()
{
    assert(m_paramsVectorStack.size() > 0);

    m_variablesStack.pushParams(m_paramsVectorStack.back());

    m_paramsVectorStack.pop_back();
}



void
StylesheetExecutionContextDefault::pushParam(
        const XalanQName& qName,
        const XObjectPtr& theValue)
{
    assert(m_paramsVectorStack.empty() == false);

    ParamsVectorType&   currentParamVector = m_paramsVectorStack.back();

    currentParamVector.push_back(ParamsVectorType::value_type(&qName, theValue));
}
#endif


#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
void
StylesheetExecutionContextDefault::pushParams(const ElemTemplateElement&    xslCallTemplateElement)
{

    // We have a params vector that we reuse, but occasionally, a
    // param will result in recursive execution, so we'll use a
    // temporary when we detect such a situation.
    if(m_paramsVector.empty() == true)
    {
        // This will ensure that the contents of m_paramsVector are
        // cleared.
        CollectionClearGuard<ParamsVectorType>  theGuard(m_paramsVector);

        // Make sure we have the default capacity for the params
        // vector...
        if (m_paramsVector.capacity() == 0)
        {
             m_paramsVector.reserve(eDefaultParamsVectorSize);
        }

        getParams(xslCallTemplateElement, m_paramsVector);

        m_variablesStack.pushParams(m_paramsVector);
    }
    else
    {
        ParamsVectorType    tempParams(getMemoryManager());

        getParams(xslCallTemplateElement, tempParams);

        m_variablesStack.pushParams(tempParams);
    }
}
#endif



const XObjectPtr
StylesheetExecutionContextDefault::getParamVariable(const XalanQName&   theName)
{
    bool    fFound;

    return m_variablesStack.getParamVariable(theName, *this, fFound);
}



void
StylesheetExecutionContextDefault::pushElementFrame(const ElemTemplateElement*  elem)
{
    m_variablesStack.pushElementFrame(elem);
}



void
StylesheetExecutionContextDefault::popElementFrame()
{
    m_variablesStack.popElementFrame();
}



int
StylesheetExecutionContextDefault::getGlobalStackFrameIndex() const
{
    return m_variablesStack.getGlobalStackFrameIndex();
}



int
StylesheetExecutionContextDefault::getCurrentStackFrameIndex() const
{
    return m_variablesStack.getCurrentStackFrameIndex();
}




void
StylesheetExecutionContextDefault::pushCurrentStackFrameIndex(int currentStackFrameIndex)
{
    m_currentIndexStack.push_back(getCurrentStackFrameIndex());
    m_variablesStack.setCurrentStackFrameIndex(currentStackFrameIndex);

}



void
StylesheetExecutionContextDefault::popCurrentStackFrameIndex()
{
    assert (m_currentIndexStack.size() > 0);

    int previousStackFrameIndex = m_currentIndexStack.back();

    m_currentIndexStack.pop_back();

    m_variablesStack.setCurrentStackFrameIndex(previousStackFrameIndex);
}

void
StylesheetExecutionContextDefault::startDocument()
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->startDocument();
}



void
StylesheetExecutionContextDefault::endDocument()
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->endDocument();

    cleanUpTransients();

    setFormatterListener(0);
}



void
StylesheetExecutionContextDefault::characters(
            const XalanDOMChar*     ch,
            fl_size_type            start,
            fl_size_type            length)
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->characters(ch, start, length);
}



void
StylesheetExecutionContextDefault::charactersRaw(
            const XalanDOMChar*     ch,
            fl_size_type            start,
            fl_size_type            length)
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->charactersRaw(ch, start, length);
}



void
StylesheetExecutionContextDefault::comment(const XalanDOMChar*  data)
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->comment(data);
}



void
StylesheetExecutionContextDefault::processingInstruction(
            const XalanDOMChar*     target,
            const XalanDOMChar*     data)
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->processingInstruction(target, data);
}



void
StylesheetExecutionContextDefault::startElement(const XalanDOMChar*     name)
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->startElement(name);
}



void
StylesheetExecutionContextDefault::endElement(const XalanDOMChar*   name)
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->endElement(name);
}



void
StylesheetExecutionContextDefault::flushPending()
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->flushPending();
}



void
StylesheetExecutionContextDefault::cloneToResultTree(
            const XalanNode&    node,
            const Locator*      locator)
{
    m_xsltProcessor->cloneToResultTree(node, getCopyTextNodesOnly(), locator);
}



void
StylesheetExecutionContextDefault::cloneToResultTree(
            const XalanNode&        node,
            XalanNode::NodeType     nodeType,
            bool                    overrideStrip,
            bool                    shouldCloneAttributes,
            const Locator*          locator)
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->cloneToResultTree(
            node,
            nodeType,
            overrideStrip,
            shouldCloneAttributes,
            getCopyTextNodesOnly(),
            locator);
}


#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
void
StylesheetExecutionContextDefault::beginCreateXResultTreeFrag(XalanNode*    sourceNode)
{
    assert(m_xsltProcessor != 0);

    XalanSourceTreeDocument* const  theDocument = m_usePerInstanceDocumentFactory == true ?
        m_documentAllocator.create(
            eDefaultAttributeAllocatorBlockSize,
            eDefaultAttributeNSAllocatorBlockSize,
            eDefaultCommentAllocatorBlockSize,
            eDefaultElementAllocatorBlockSize,
            eDefaultElementNSAllocatorBlockSize,
            eDefaultPIAllocatorBlockSize,
            eDefaultTextAllocatorBlockSize,
            eDefaultTextIWSAllocatorBlockSize) :
        getSourceTreeFactory(getMemoryManager());
    assert(theDocument != 0);

    XalanSourceTreeDocumentFragment* const  theDocumentFragment =
        m_documentFragmentAllocator.create(*theDocument);
    assert(theDocumentFragment != 0);

    FormatterToSourceTree* const    theFormatter = m_formatterToSourceTreeStack.get();
    assert(theFormatter != 0);

    theFormatter->setDocument(theDocument);

    theFormatter->setDocumentFragment(theDocumentFragment);

    theFormatter->setPrefixResolver(m_xsltProcessor);

    pushOutputContext(theFormatter);

    theFormatter->startDocument();

    pushCurrentNode(sourceNode);
}



const XObjectPtr
StylesheetExecutionContextDefault::endCreateXResultTreeFrag()
{    
    FormatterToSourceTree* const    theFormatter =
        m_formatterToSourceTreeStack.top();

    assert (theFormatter != 0);

    theFormatter->endDocument();

    XalanSourceTreeDocumentFragment* const  theDocumentFragment =
        theFormatter->getDocumentFragment();

    assert(theDocumentFragment != 0);

    XResultTreeFrag* const  theXResultTreeFrag =
        m_xresultTreeFragAllocator.create(*theDocumentFragment);

    theXResultTreeFrag->setExecutionContext(this);

    popCurrentNode();
    popOutputContext();

    m_formatterToSourceTreeStack.release();

    return XObjectPtr(theXResultTreeFrag);
}
#endif



#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
const XObjectPtr
StylesheetExecutionContextDefault::createXResultTreeFrag(
            const ElemTemplateElement&  templateChild,
            XalanNode*                  sourceNode)
{
    assert(m_xsltProcessor != 0);

    XalanSourceTreeDocument* const  theDocument = m_usePerInstanceDocumentFactory == true ?
        m_documentAllocator.create(
            eDefaultAttributeAllocatorBlockSize,
            eDefaultAttributeNSAllocatorBlockSize,
            eDefaultCommentAllocatorBlockSize,
            eDefaultElementAllocatorBlockSize,
            eDefaultElementNSAllocatorBlockSize,
            eDefaultPIAllocatorBlockSize,
            eDefaultTextAllocatorBlockSize,
            eDefaultTextIWSAllocatorBlockSize) :
        getSourceTreeFactory(getMemoryManager());
    assert(theDocument != 0);

    XalanSourceTreeDocumentFragment* const  theDocumentFragment =
        m_documentFragmentAllocator.create(*theDocument);
    assert(theDocumentFragment != 0);

    GuardCachedObject<FormatterToSourceTreeCacheType>   theGuard(m_formatterToSourceTreeCache);

    FormatterToSourceTree* const    theFormatter = theGuard.get();
    assert(theFormatter != 0);

    theFormatter->setDocument(theDocument);

    theFormatter->setDocumentFragment(theDocumentFragment);

    theFormatter->setPrefixResolver(m_xsltProcessor);

    StylesheetExecutionContext::OutputContextPushPop    theOutputContextPushPop(
                *this,
                theFormatter);

    theFormatter->startDocument();

    templateChild.executeChildren(*this, sourceNode);

    theFormatter->endDocument();

    XResultTreeFrag* const  theXResultTreeFrag =
        m_xresultTreeFragAllocator.create(*theDocumentFragment);

    theXResultTreeFrag->setExecutionContext(this);

    return XObjectPtr(theXResultTreeFrag);
}
#endif



void
StylesheetExecutionContextDefault::outputToResultTree(
            const XObject&      xobj,
            const Locator*      locator)
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->outputToResultTree(xobj, getCopyTextNodesOnly(), locator);
}



void
StylesheetExecutionContextDefault::outputResultTreeFragment(
            const XObject&      theTree,
            const Locator*      locator)
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->outputResultTreeFragment(theTree, getCopyTextNodesOnly(), locator);
}



const XalanDOMString&
StylesheetExecutionContextDefault::getXSLNameSpaceURL() const
{
    assert(m_xsltProcessor != 0);

    return m_xsltProcessor->getXSLNameSpaceURL();
}



const XalanDOMString&
StylesheetExecutionContextDefault::getXalanXSLNameSpaceURL() const
{
    assert(m_xsltProcessor != 0);

    return m_xsltProcessor->getXalanXSLNameSpaceURL();
}



bool
StylesheetExecutionContextDefault::getTraceSelects() const
{
    assert(m_xsltProcessor != 0);

    return m_xsltProcessor->getTraceSelects();
}



void
StylesheetExecutionContextDefault::traceSelect(
            const ElemTemplateElement&  theTemplate,
            const NodeRefListBase&      nl,
            const XPath*                xpath)
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->traceSelect(*this, theTemplate, nl, xpath);
}



bool
StylesheetExecutionContextDefault::findOnElementRecursionStack(const ElemTemplateElement*   theElement) const
{
    assert(theElement != 0);

    using std::find;

    const ElementTemplateElementStackType::const_iterator   i =
                find(m_elementRecursionStack.begin(),
                     m_elementRecursionStack.end(),
                     theElement);

    return i == m_elementRecursionStack.end() ? false : true;
}



void
StylesheetExecutionContextDefault::pushOnElementRecursionStack(const ElemTemplateElement*   theElement)
{
    assert(theElement != 0);

    if (findOnElementRecursionStack(theElement) == true)
    {
        const Locator* const    theLocator = theElement->getLocator();

        const GetCachedString   theGuard(*this);

        throw XSLTProcessorException(
                getMemoryManager(),
                XalanMessageLoader::getMessage(
                    theGuard.get(),
                    XalanMessages::InfiniteRecursion_1Param,
                    theElement->getElementName()),
                theLocator);
    }

    m_elementRecursionStack.push_back(theElement);
}



const ElemTemplateElement*
StylesheetExecutionContextDefault::popElementRecursionStack()
{
    assert(m_elementRecursionStack.empty() == false);

    const ElemTemplateElement* const    theTemp =
        m_elementRecursionStack.back();

    m_elementRecursionStack.pop_back();

    return theTemp;
}



bool
StylesheetExecutionContextDefault::returnXResultTreeFrag(XResultTreeFrag*   theXResultTreeFrag)
{
    assert(theXResultTreeFrag != 0);

    if (m_xresultTreeFragAllocator.ownsObject(theXResultTreeFrag) == false)
    {
        return false;
    }
    else
    {
        XalanDocumentFragment* const    theDocumentFragment =
            theXResultTreeFrag->release();

        const KeyTablesTableType::iterator  i =
            m_keyTables.find(theDocumentFragment);

        if (i != m_keyTables.end())
        {
            KeyTable* const     theTable = (*i).second;

            m_keyTables.erase(i);

            theTable->~KeyTable();

            m_keyTables.getMemoryManager().deallocate((void*)theTable);
        }

        m_xresultTreeFragAllocator.destroy(theXResultTreeFrag);

        if (m_usePerInstanceDocumentFactory == true)
        {
            m_documentAllocator.destroy(static_cast<XalanSourceTreeDocument*>(theDocumentFragment->getOwnerDocument()));
        }

        m_documentFragmentAllocator.destroy(static_cast<XalanSourceTreeDocumentFragment*>(theDocumentFragment));

        return true;
    }
}



StylesheetExecutionContextDefault::eEscapeURLs
StylesheetExecutionContextDefault::getEscapeURLs() const
{
    return m_escapeURLs;
}



void
StylesheetExecutionContextDefault::setEscapeURLs(eEscapeURLs    value)
{
    m_escapeURLs = value;
}



StylesheetExecutionContextDefault::eOmitMETATag
StylesheetExecutionContextDefault::getOmitMETATag() const
{
    return m_omitMETATag;
}



void
StylesheetExecutionContextDefault::setOmitMETATag(eOmitMETATag  value)
{
    m_omitMETATag = value;
}



FormatterListener*
StylesheetExecutionContextDefault::createFormatterToXML(
            Writer&                 writer,
            const XalanDOMString&   version,
            bool                    doIndent,
            int                     indent,
            const XalanDOMString&   encoding,
            const XalanDOMString&   mediaType,
            const XalanDOMString&   doctypeSystem,
            const XalanDOMString&   doctypePublic,
            bool                    xmlDecl,
            const XalanDOMString&   standalone)
{
    m_formatterListeners.push_back(0);

    FormatterListener* const    theFormatterListener =
        XalanXMLSerializerFactory::create(
            getMemoryManager(),
            writer,
            version,
            doIndent,
            indent,
            encoding,
            mediaType,
            doctypeSystem,
            doctypePublic,
            xmlDecl,
            standalone);
    assert(theFormatterListener != 0);

    m_formatterListeners.back() = theFormatterListener;

    return theFormatterListener;
}



FormatterListener*
StylesheetExecutionContextDefault::createFormatterToHTML(
            Writer&                 writer,
            const XalanDOMString&   encoding,
            const XalanDOMString&   mediaType,
            const XalanDOMString&   doctypeSystem,
            const XalanDOMString&   doctypePublic,
            bool                    doIndent,
            int                     indent,
            bool                    escapeURLs,
            bool                    omitMetaTag)
{
    m_formatterListeners.push_back(0);

    FormatterToHTML* const  theFormatter =
        FormatterToHTML::create(
            getMemoryManager(),
            writer,
            encoding,
            mediaType,
            doctypeSystem,
            doctypePublic,
            doIndent,
            indent,
            escapeURLs,
            omitMetaTag);

    m_formatterListeners.back() = theFormatter;

    theFormatter->setPrefixResolver(m_xsltProcessor);

    return theFormatter;
}



FormatterListener*
StylesheetExecutionContextDefault::createFormatterToText(
            Writer&                 writer,
            const XalanDOMString&   encoding)
{
    m_formatterListeners.push_back(0);

    FormatterToText* const  theFormatter =
        FormatterToText::create(getMemoryManager(), writer, encoding);

    m_formatterListeners.back() = theFormatter;

    return theFormatter;
}


#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
FormatterToText*
StylesheetExecutionContextDefault::borrowFormatterToText()
{
    return m_formatterToTextCache.get();
}



bool
StylesheetExecutionContextDefault::returnFormatterToText(FormatterToText*   theFormatter)
{
    return m_formatterToTextCache.release(theFormatter);
}
#endif



#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
NodeSorter*
StylesheetExecutionContextDefault::getNodeSorter()
{
    return &m_nodeSorter;
}
#endif


#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
NodeSorter*
StylesheetExecutionContextDefault::borrowNodeSorter()
{
    return m_nodeSorterCache.get();
}



bool
StylesheetExecutionContextDefault::returnNodeSorter(NodeSorter*     theSorter)
{
    return m_nodeSorterCache.release(theSorter);
}
#endif



StylesheetExecutionContextDefault::XalanNumberFormatAutoPtr
StylesheetExecutionContextDefault::createXalanNumberFormat()
{
    return XalanNumberFormatAutoPtr(getMemoryManager(), s_xalanNumberFormatFactory->create(getMemoryManager()));
}



StylesheetExecutionContextDefault::XalanNumberFormatFactory::XalanNumberFormatFactory()
{
}



StylesheetExecutionContextDefault::XalanNumberFormatFactory::~XalanNumberFormatFactory()
{
}



XalanNumberFormat*
StylesheetExecutionContextDefault::XalanNumberFormatFactory::create(MemoryManager& theManager)
{
    return XalanNumberFormat::create(theManager);
}



StylesheetExecutionContextDefault::XalanNumberFormatFactory*
StylesheetExecutionContextDefault::installXalanNumberFormatFactory(XalanNumberFormatFactory*    theFactory)
{
    XalanNumberFormatFactory* const     theOldFactory =
        s_xalanNumberFormatFactory;

    if (theFactory == 0)
    {
        s_xalanNumberFormatFactory = &s_defaultXalanNumberFormatFactory;
    }
    else
    {
        s_xalanNumberFormatFactory = theFactory;
    }

    return theOldFactory;
}



int
StylesheetExecutionContextDefault::collationCompare(
            const XalanDOMString&               theLHS,
            const XalanDOMString&               theRHS,
            XalanCollationServices::eCaseOrder  theCaseOrder)
{
    if (m_collationCompareFunctor == 0)
    {
        return s_defaultCollationFunctor(theLHS.c_str(), theRHS.c_str(), theCaseOrder);
    }
    else
    {
        return (*m_collationCompareFunctor)(theLHS.c_str(), theRHS.c_str(), theCaseOrder);
    }
}



int
StylesheetExecutionContextDefault::collationCompare(
            const XalanDOMString&               theLHS,
            const XalanDOMString&               theRHS,
            const XalanDOMString&               theLocale,
            XalanCollationServices::eCaseOrder  theCaseOrder)
{
    if (m_collationCompareFunctor == 0)
    {
        return s_defaultCollationFunctor(theLHS.c_str(), theRHS.c_str(), theLocale.c_str(), theCaseOrder);
    }
    else
    {
        return (*m_collationCompareFunctor)(theLHS.c_str(), theRHS.c_str(), theLocale.c_str(), theCaseOrder);
    }
}



int
StylesheetExecutionContextDefault::collationCompare(
            const XalanDOMChar*                 theLHS,
            const XalanDOMChar*                 theRHS,
            XalanCollationServices::eCaseOrder  theCaseOrder)
{
    assert(theLHS != 0 && theRHS != 0);

    if (m_collationCompareFunctor == 0)
    {
        return s_defaultCollationFunctor(theLHS, theRHS, theCaseOrder);
    }
    else
    {
        return (*m_collationCompareFunctor)(theLHS, theRHS, theCaseOrder);
    }
}



int
StylesheetExecutionContextDefault::collationCompare(
            const XalanDOMChar*                 theLHS,
            const XalanDOMChar*                 theRHS,
            const XalanDOMChar*                 theLocale,
            XalanCollationServices::eCaseOrder  theCaseOrder)
{
    assert(theLHS != 0 && theRHS != 0);

    if (m_collationCompareFunctor == 0)
    {
        return s_defaultCollationFunctor(theLHS, theRHS, theLocale, theCaseOrder);
    }
    else
    {
        return (*m_collationCompareFunctor)(theLHS, theRHS, theLocale, theCaseOrder);
    }
}



StylesheetExecutionContextDefault::DefaultCollationCompareFunctor::DefaultCollationCompareFunctor()
{
}



StylesheetExecutionContextDefault::DefaultCollationCompareFunctor::~DefaultCollationCompareFunctor()
{
}



int
StylesheetExecutionContextDefault::DefaultCollationCompareFunctor::operator()(
            const XalanDOMChar*                 theLHS,
            const XalanDOMChar*                 theRHS,
            XalanCollationServices::eCaseOrder  /* theCaseOrder */) const
{
    return xalanc::collationCompare(theLHS, theRHS);
}



int
StylesheetExecutionContextDefault::DefaultCollationCompareFunctor::operator()(
            const XalanDOMChar*                 theLHS,
            const XalanDOMChar*                 theRHS,
            const XalanDOMChar*                 /* theLocale */,
            XalanCollationServices::eCaseOrder  theCaseOrder) const
{
    return (*this)(theLHS, theRHS, theCaseOrder);
}



const StylesheetExecutionContextDefault::CollationCompareFunctor*
StylesheetExecutionContextDefault::installCollationCompareFunctor(CollationCompareFunctor*  theFunctor)
{
    assert(theFunctor != 0);

    const CollationCompareFunctor* const    temp = m_collationCompareFunctor;

    m_collationCompareFunctor = theFunctor;

    return temp;
}



StylesheetExecutionContextDefault::CollationCompareFunctor*
StylesheetExecutionContextDefault::uninstallCollationCompareFunctor()
{
    if (m_collationCompareFunctor == 0)
    {
        return 0;
    }
    else
    {
        CollationCompareFunctor* const  temp = m_collationCompareFunctor;

        m_collationCompareFunctor = 0;

        return temp;
    }
}



static const XalanQNameByValue  theEmptyQName(XalanMemMgrs::getDummyMemMgr());



void 
StylesheetExecutionContextDefault::formatNumber(
            double                              number,
            const XalanDOMString&               pattern,
            XalanDOMString&                     theResult,
            const XalanNode*                    context,
            const Locator*                      locator)
{
    const XalanDecimalFormatSymbols * theDFS = getDecimalFormatSymbols(theEmptyQName);

    if (m_formatNumberFunctor == 0) 
    {
        m_xpathExecutionContextDefault.doFormatNumber(
            number,
            pattern,
            theDFS,
            theResult,
            context,
            locator);
    } 
    else 
    {
        (*m_formatNumberFunctor)(
            *this,
            number,
            pattern,
            theDFS,
            theResult,
            context,
            locator);
    }
}
 


void 
StylesheetExecutionContextDefault::formatNumber(
            double                  number,
            const XalanDOMString&   pattern,
            const XalanDOMString&   dfsName,
            XalanDOMString&         theResult,
            const XalanNode*        context,
            const Locator*          locator)
{
    XalanQNameByValue&  theDFSQName = m_xpathExecutionContextDefault.getScratchQName();

    theDFSQName.set(dfsName, getPrefixResolver(), locator);

    const XalanDecimalFormatSymbols*    theDFS = getDecimalFormatSymbols(theDFSQName);

    if (theDFS == 0)
    {
        const GetCachedString   theGuard(*this);

        problem(
            eXSLTProcessor,
            eWarning,
            XalanMessageLoader::getMessage(
                theGuard.get(),
                XalanMessages::Decimal_formatElementNotFound_1Param,
                "format-number()"),
            locator,
            context);

        theDFS = getDecimalFormatSymbols(theEmptyQName);
        
    }

    if (m_formatNumberFunctor == 0) 
    {
        m_xpathExecutionContextDefault.doFormatNumber(number,pattern,theDFS,theResult,context,locator);
    } 
    else 
    {   
        (*m_formatNumberFunctor)(*this, number, pattern, theDFS, theResult, context, locator);
    }
}



const StylesheetExecutionContextDefault::FormatNumberFunctor*
StylesheetExecutionContextDefault::installFormatNumberFunctor(FormatNumberFunctor*  theFunctor)
{
    assert(theFunctor != 0);

    const FormatNumberFunctor * const   temp = m_formatNumberFunctor;

    m_formatNumberFunctor = theFunctor;

    return temp;
}



StylesheetExecutionContextDefault::FormatNumberFunctor*
StylesheetExecutionContextDefault::uninstallFormatNumberFunctor()
{
    if (m_formatNumberFunctor == 0)
    {
        return 0;
    }
    else
    {
        FormatNumberFunctor * const temp = m_formatNumberFunctor;

        m_formatNumberFunctor = 0;

        return temp;
    }
}



void
StylesheetExecutionContextDefault::reset()
{
#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
    assert(m_elementRecursionStack.empty() == true);
#endif

    m_variablesStack.reset();

#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
    m_xobjectPtrStack.clear();
    m_paramsVectorStack.clear();
    m_elementRecursionStack.clear();
#endif

    if (m_xsltProcessor != 0)
    {
        m_xsltProcessor->reset();
    }

    m_rootDocument = 0;
    m_stylesheetRoot = 0;
    m_mode = 0;

    m_currentTemplateStack.clear();
    m_currentTemplateStack.push_back(0);

#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
    m_formatterToTextCache.reset();
    m_formatterToSourceTreeCache.reset();
    m_nodeSorterCache.reset();
#endif

    m_xresultTreeFragAllocator.reset();
    m_documentFragmentAllocator.reset();
    m_documentAllocator.reset();

    // Just in case endDocument() was not called,
    // clean things up...
    cleanUpTransients();

    // Destroy the source tree factory, which
    // will destroy all result tree fragment nodes
    // that were generated...
    m_sourceTreeResultTreeFactory.reset();

    // Reset the default execution context...
    m_xpathExecutionContextDefault.reset();

    m_copyTextNodesOnlyStack.clear();

    m_modeStack.clear();

    m_currentIndexStack.clear();

#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
    m_nodesToTransformStack.clear();
    m_processCurrentAttributeStack.clear();
    m_skipElementAttributesStack.clear();
    m_executeIfStack.clear();
    m_elementInvokerStack.clear();
    m_useAttributeSetIndexesStack.clear();
    m_formatterToSourceTreeStack.reset();
    m_stringStack.reset();
    m_mutableNodeRefListStack.reset();
    m_formatterToTextStack.reset();
#endif
}



XalanNode*
StylesheetExecutionContextDefault::getCurrentNode() const
{
    return m_xpathExecutionContextDefault.getCurrentNode();
}



void
StylesheetExecutionContextDefault::pushCurrentNode(XalanNode*   theCurrentNode)
{
    m_xpathExecutionContextDefault.pushCurrentNode(theCurrentNode);
}



void
StylesheetExecutionContextDefault::popCurrentNode()
{
    m_xpathExecutionContextDefault.popCurrentNode();
}



bool
StylesheetExecutionContextDefault::isNodeAfter(
            const XalanNode&    node1,
            const XalanNode&    node2) const
{
    return m_xpathExecutionContextDefault.isNodeAfter(node1, node2);
}



void
StylesheetExecutionContextDefault::pushContextNodeList(const NodeRefListBase&   theContextNodeList)
{
    m_xpathExecutionContextDefault.pushContextNodeList(theContextNodeList);
}



void
StylesheetExecutionContextDefault::popContextNodeList()
{
    m_xpathExecutionContextDefault.popContextNodeList();
}



const NodeRefListBase&
StylesheetExecutionContextDefault::getContextNodeList() const
{
    return m_xpathExecutionContextDefault.getContextNodeList();
}



StylesheetExecutionContextDefault::size_type
StylesheetExecutionContextDefault::getContextNodeListLength() const
{
    return m_xpathExecutionContextDefault.getContextNodeListLength();
}



StylesheetExecutionContextDefault::size_type
StylesheetExecutionContextDefault::getContextNodeListPosition(const XalanNode&  contextNode) const
{
    return m_xpathExecutionContextDefault.getContextNodeListPosition(contextNode);
}



bool
StylesheetExecutionContextDefault::elementAvailable(const XalanQName&   theQName) const
{
    if (theQName.getNamespace() == XSLTEngineImpl::getXSLNameSpaceURL())
    {
        const int   xslToken = StylesheetConstructionContextDefault::getElementNameToken(theQName.getLocalPart());

        return xslToken < 0 ? false : true;
    }
    else
    {
        return m_xpathExecutionContextDefault.elementAvailable(theQName);
    }
}



bool
StylesheetExecutionContextDefault::elementAvailable(
            const XalanDOMString&   theName, 
            const Locator*          theLocator) const
{
    XalanQNameByValue&  theQName = m_xpathExecutionContextDefault.getScratchQName();

    theQName.set(theName, getPrefixResolver(), theLocator);

    return elementAvailable(theQName);
}



bool
StylesheetExecutionContextDefault::functionAvailable(const XalanQName&  theQName) const
{
    return m_xpathExecutionContextDefault.functionAvailable(theQName);
}



bool
StylesheetExecutionContextDefault::functionAvailable(
            const XalanDOMString&   theName, 
            const Locator*          theLocator) const
{
    return m_xpathExecutionContextDefault.functionAvailable(theName, theLocator);
}



const XObjectPtr
StylesheetExecutionContextDefault::extFunction(
            const XalanDOMString&           theNamespace,
            const XalanDOMString&           functionName,
            XalanNode*                      context,
            const XObjectArgVectorType&     argVec,
            const Locator*                  locator)
{
    assert(m_xpathExecutionContextDefault.getXPathEnvSupport() != 0);

    return m_xpathExecutionContextDefault.getXPathEnvSupport()->extFunction(*this, theNamespace, functionName, context, argVec, locator);
}



XalanDocument*
StylesheetExecutionContextDefault::parseXML(
            MemoryManager&      theManager,
            const XalanDOMString&   urlString,
            const XalanDOMString&   base,
            ErrorHandler*           theErrorHandler) const
{
    return m_xpathExecutionContextDefault.parseXML(
                theManager,
                urlString,
                base,
                theErrorHandler);
}



MutableNodeRefList*
StylesheetExecutionContextDefault::borrowMutableNodeRefList()
{
    return m_xpathExecutionContextDefault.borrowMutableNodeRefList();
}



bool
StylesheetExecutionContextDefault::returnMutableNodeRefList(MutableNodeRefList*     theList)
{
    return m_xpathExecutionContextDefault.returnMutableNodeRefList(theList);
}



void
StylesheetExecutionContextDefault::pushCopyTextNodesOnly(bool copyTextNodesOnly)
{
    m_copyTextNodesOnlyStack.push_back(copyTextNodesOnly);
}



bool
StylesheetExecutionContextDefault::popCopyTextNodesOnly()
{
    assert (m_copyTextNodesOnlyStack.size() > 0);

    bool copyTextNodesOnly = m_copyTextNodesOnlyStack.back();

    m_copyTextNodesOnlyStack.pop_back();

    return copyTextNodesOnly;
}



MutableNodeRefList*
StylesheetExecutionContextDefault::createMutableNodeRefList(MemoryManager& theManager) const
{
    return m_xpathExecutionContextDefault.createMutableNodeRefList(theManager);
}



XalanDOMString&
StylesheetExecutionContextDefault::getCachedString()
{
    return m_xpathExecutionContextDefault.getCachedString();
}



bool
StylesheetExecutionContextDefault::releaseCachedString(XalanDOMString&  theString)
{
    return m_xpathExecutionContextDefault.releaseCachedString(theString);
}



void
StylesheetExecutionContextDefault::getNodeSetByKey(
            XalanNode*              context,
            const XalanQName&       qname,
            const XalanDOMString&   ref,
            const Locator*          locator,
            MutableNodeRefList&     nodelist)
{
    assert(m_stylesheetRoot != 0);

    m_stylesheetRoot->getNodeSetByKey(
        context,
        qname,
        ref,
        *getPrefixResolver(),
        nodelist,
        *this,
        locator,
        m_keyTables);
}



void
StylesheetExecutionContextDefault::getNodeSetByKey(
            XalanNode*              context,
            const XalanDOMString&   name,
            const XalanDOMString&   ref,
            const Locator*          locator,
            MutableNodeRefList&     nodelist)
{
    assert(m_stylesheetRoot != 0);

    const PrefixResolver* const     resolver =
                getPrefixResolver();
    assert(resolver != 0);

    XalanQNameByValue&  theQName =
        m_xpathExecutionContextDefault.getScratchQName();

    theQName.set(name, resolver, locator);

    m_stylesheetRoot->getNodeSetByKey(
        context,
        theQName,
        ref,
        *resolver,
        nodelist,
        *this,
        locator,
        m_keyTables);
}



const XObjectPtr
StylesheetExecutionContextDefault::getVariable(
            const XalanQName&   name,
            const Locator*      locator)
{
    bool                fFound;

    const XObjectPtr    theValue(m_variablesStack.getVariable(name, *this, fFound));

    if(fFound == true)
    {
        assert(theValue.null() == false);

        return theValue;
    }
    else
    {
        const GetCachedString   theGuard(*this);

        problem(
            eXSLTProcessor,
            eWarning,
            XalanMessageLoader::getMessage(
                theGuard.get(),
                XalanMessages::VariableIsNotDefined_1Param,
                name.getLocalPart()),
            locator,
            getCurrentNode());

        return getXObjectFactory().createUnknown(name.getLocalPart());
    }
}



const PrefixResolver*
StylesheetExecutionContextDefault::getPrefixResolver() const
{
    return m_xpathExecutionContextDefault.getPrefixResolver();
}



void
StylesheetExecutionContextDefault::setPrefixResolver(const PrefixResolver*  thePrefixResolver)
{
    m_xpathExecutionContextDefault.setPrefixResolver(thePrefixResolver);
}



const XalanDOMString*
StylesheetExecutionContextDefault::getNamespaceForPrefix(const XalanDOMString&  prefix) const
{
    return m_xpathExecutionContextDefault.getNamespaceForPrefix(prefix);
}



const XalanDOMString&
StylesheetExecutionContextDefault::findURIFromDoc(const XalanDocument*  owner) const
{
    return m_xpathExecutionContextDefault.findURIFromDoc(owner);
}



const XalanDOMString&
StylesheetExecutionContextDefault::getUnparsedEntityURI(
            const XalanDOMString&   theName,
            const XalanDocument&    theDocument) const
{
    return m_xpathExecutionContextDefault.getUnparsedEntityURI(theName, theDocument);
}



bool
StylesheetExecutionContextDefault::shouldStripSourceNode(const XalanText&   node)
{
    assert(m_stylesheetRoot != 0);
//    assert(node.getData().length() != 0);

    return m_stylesheetRoot->shouldStripSourceNode(node);
}



XalanDocument*
StylesheetExecutionContextDefault::getSourceDocument(const XalanDOMString&  theURI) const
{
    return m_xpathExecutionContextDefault.getSourceDocument(theURI);
}



void
StylesheetExecutionContextDefault::setSourceDocument(
            const XalanDOMString&   theURI,
            XalanDocument*          theDocument)
{
    m_xpathExecutionContextDefault.setSourceDocument(theURI, theDocument);
}



const XalanDecimalFormatSymbols*
StylesheetExecutionContextDefault::getDecimalFormatSymbols(const XalanQName&    qname)
{
    if (m_stylesheetRoot == 0)
    {
        return 0; 
    }
    else
    {
        return m_stylesheetRoot->getDecimalFormatSymbols(qname);
    }
}



PrintWriter*
StylesheetExecutionContextDefault::createPrintWriter(XalanOutputStream* theTextOutputStream)
{
    assert(theTextOutputStream != 0);

    PrintWriter* const  thePrintWriter =
        XalanOutputStreamPrintWriter::create(*theTextOutputStream);

    m_printWriters.push_back(thePrintWriter);

    return thePrintWriter;
}



PrintWriter*
StylesheetExecutionContextDefault::createPrintWriter(
            const XalanDOMString&       theFileName,
            const XalanDOMString&       /* theEncoding */)
{
    XalanOutputStream* const    theOutputStream =
        XalanFileOutputStream::create( theFileName, getMemoryManager());

    m_outputStreams.push_back(theOutputStream);

    return createPrintWriter(theOutputStream);
}



PrintWriter*
StylesheetExecutionContextDefault::createPrintWriter(StreamType&    theStream)
{
    XalanOutputStream* const        theOutputStream =
        XalanStdOutputStream::create(theStream, getMemoryManager());

    m_outputStreams.push_back(theOutputStream);

    return createPrintWriter(theOutputStream);
}



PrintWriter*
StylesheetExecutionContextDefault::createPrintWriter(FILE*  theStream)
{
    XalanOutputStream* const        theOutputStream =
        XalanFStreamOutputStream::create(theStream, getMemoryManager());

    m_outputStreams.push_back(theOutputStream);

    return createPrintWriter(theOutputStream);
}



CountersTable&
StylesheetExecutionContextDefault::getCountersTable()
{
    return m_countersTable;
}



void
StylesheetExecutionContextDefault::characters(const XalanNode&  node)
{
    m_xsltProcessor->characters(node);
}


void
StylesheetExecutionContextDefault::characters(const XObjectPtr&     xobject)
{
    m_xsltProcessor->characters(xobject);
}



void
StylesheetExecutionContextDefault::charactersRaw(const XalanNode&   node)
{
    m_xsltProcessor->charactersRaw(node);
}



void
StylesheetExecutionContextDefault::charactersRaw(const XObjectPtr&  xobject)
{
    m_xsltProcessor->charactersRaw(xobject);
}



StylesheetExecutionContextDefault::tl_size_type
StylesheetExecutionContextDefault::getTraceListeners() const
{
    assert(m_xsltProcessor != 0);

    return m_xsltProcessor->getTraceListeners();
}



void
StylesheetExecutionContextDefault::fireGenerateEvent(const GenerateEvent&   ge)
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->fireGenerateEvent(ge);
}



void
StylesheetExecutionContextDefault::fireTraceEvent(const TracerEvent&    te)
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->fireTraceEvent(te);
}



void
StylesheetExecutionContextDefault::fireSelectEvent(const SelectionEvent&    se)
{
    assert(m_xsltProcessor != 0);

    m_xsltProcessor->fireSelectEvent(se);
}



class PopAndPushContextMarker
{
public:

    PopAndPushContextMarker(StylesheetExecutionContext& theExecutionContext) :
        m_executionContext(theExecutionContext)
    {
        m_executionContext.popContextMarker();
    }

    ~PopAndPushContextMarker()
    {
        m_executionContext.pushContextMarker();
    }

private:

    StylesheetExecutionContext&     m_executionContext;
};



#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
void
StylesheetExecutionContextDefault::getParams(
            const ElemTemplateElement&  xslCallTemplateElement,
            ParamsVectorType&           params)
{
    assert(getCurrentNode() != 0);
    assert(params.empty() == true);

    const ElemTemplateElement*  child =
            xslCallTemplateElement.getFirstChildElem();

    if (0 != child)
    {
        // This object will take care of popping, then
        // pushing the context marker at the top of the
        // stack, even if an exception is thrown.
        PopAndPushContextMarker     thePopPush(*this);

        while(0 != child)
        {
            if(StylesheetConstructionContext::ELEMNAME_WITH_PARAM == child->getXSLToken())
            {
                const XPath* const  pxpath = child->getXPath();

                XObjectPtr  theXObject;

                if(0 != pxpath)
                {
                    theXObject =
                        createVariable(
                            *pxpath,
                            getCurrentNode(),
                            *child);
                }
                else
                {
                    theXObject =
                        createVariable(
                            *child,
                            getCurrentNode());
                }

                const ElemWithParam* const  xslParamElement =
                        static_cast<const ElemWithParam*>(child);

                params.push_back(ParamsVectorType::value_type(&xslParamElement->getQName(), theXObject));
            }

            child = child->getNextSiblingElem();
        }
    }
}
#endif


XalanSourceTreeDocument*
StylesheetExecutionContextDefault::getSourceTreeFactory(MemoryManager& theManager) const
{
    assert(m_xsltProcessor != 0);

    if (m_sourceTreeResultTreeFactory.get() == 0)
    {
        m_sourceTreeResultTreeFactory.reset(
            &theManager, 
            XalanSourceTreeDocument::create(theManager));
    }

    return m_sourceTreeResultTreeFactory.get();
}



bool
StylesheetExecutionContextDefault::isCached(const XPath*    theXPath)
{
    XPathCacheMapType::const_iterator   i =
        m_matchPatternCache.begin();

    const XPathCacheMapType::const_iterator     theEnd =
        m_matchPatternCache.end();

    while (i != theEnd)
    {
        if ((*i).second.first == theXPath)
        {
            return true;
        }
        else
        {
            ++i;
        }
    }

    return false;
}



void
StylesheetExecutionContextDefault::XPathCacheReturnFunctor::operator()(const XPathCacheMapType::value_type&     theCacheEntry)
{
    m_xsltProcessor.returnXPath(theCacheEntry.second.first);
}




void
StylesheetExecutionContextDefault::clearXPathCache()
{
    using std::for_each;

    assert(m_matchPatternCache.empty() == true || m_xsltProcessor != 0);

    if (m_xsltProcessor != 0)
    {
        for_each(m_matchPatternCache.begin(),
                 m_matchPatternCache.end(),
                 XPathCacheReturnFunctor(*m_xsltProcessor));
    }

    m_matchPatternCache.clear();
}



void
StylesheetExecutionContextDefault::addToXPathCache(
            const XalanDOMString&   pattern,
            const XPath*            theXPath)
{
    assert(m_xsltProcessor != 0);

    ClockType   addClock = std::clock();

    if (m_matchPatternCache.size() == eXPathCacheMax)
    {
        // OK, we need to clear something out of the cache...

        // Initialize the lowest clock time found so far
        // with the current clock...
        ClockType   lowest = addClock;

        // Get some iterators ready to search the cache...
        XPathCacheMapType::iterator     i =
            m_matchPatternCache.begin();

        const XPathCacheMapType::iterator   theEnd =
            m_matchPatternCache.end();

        XPathCacheMapType::iterator     earliest(theEnd);

        while(i != theEnd)
        {
            const ClockType     current = (*i).second.second;

            if (current < lowest)
            {
                // OK, found a lower clock time, so
                // update the everything...
                lowest = current;

                earliest = i;
            }
            else
            {
                ++i;
            }
        }
        assert(earliest != theEnd);

        // Return the XPath and erase it from the cache.
        m_xsltProcessor->returnXPath((*earliest).second.first);

        m_matchPatternCache.erase(earliest);
    }

    // Add the XPath with the current clock
    m_matchPatternCache.insert(pattern, XPathCacheEntry(theXPath, addClock));
}



void
StylesheetExecutionContextDefault::cleanUpTransients()
{
    using std::for_each;

    for_each(m_formatterListeners.begin(),
             m_formatterListeners.end(),
             DeleteFunctor<FormatterListener>(getMemoryManager()));

    m_formatterListeners.clear();

    for_each(m_printWriters.begin(),
             m_printWriters.end(),
             DeleteFunctor<PrintWriter>(getMemoryManager()));

    m_printWriters.clear();

    for_each(m_outputStreams.begin(),
             m_outputStreams.end(),
             DeleteFunctor<XalanOutputStream>(getMemoryManager()));

    m_outputStreams.clear();

    // Clean up the key table vector
    for_each(m_keyTables.begin(),
             m_keyTables.end(),
             makeMapValueDeleteFunctor(m_keyTables));

    m_keyTables.clear();

    m_countersTable.reset();

    // Clear any cached XPaths...
    clearXPathCache();
  
    assert(m_matchPatternCache.empty() == true);
}



#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
void
StylesheetExecutionContextDefault::createUseAttributeSetIndexesOnStack()
{
    UseAttributeSetIndexes useAttributeSetIndexes;
    m_useAttributeSetIndexesStack.push_back(useAttributeSetIndexes);
}



StylesheetExecutionContextDefault::UseAttributeSetIndexes&
StylesheetExecutionContextDefault::getUseAttributeSetIndexes()
{
    assert(m_useAttributeSetIndexesStack.size() > 0);

    return m_useAttributeSetIndexesStack.back();
}



void
StylesheetExecutionContextDefault::popUseAttributeSetIndexesFromStack()
{   
    assert(m_useAttributeSetIndexesStack.size() > 0);

    m_useAttributeSetIndexesStack.pop_back();

}



void
StylesheetExecutionContextDefault::pushInvoker(const ElemTemplateElement * invoker)
{
    m_elementInvokerStack.push_back(invoker);
}



void
StylesheetExecutionContextDefault::popInvoker()
{
    assert (m_elementInvokerStack.size() > 0);

    m_elementInvokerStack.pop_back();
}



const ElemTemplateElement*
StylesheetExecutionContextDefault::getInvoker() const
{
     assert (m_elementInvokerStack.size() > 0);

     return m_elementInvokerStack.back();
}




XalanDOMString&
StylesheetExecutionContextDefault::getAndPushCachedString()
{
    XalanDOMString& theString = *(m_stringStack.get());

    theString.clear();

    return theString;
}



XalanDOMString&
StylesheetExecutionContextDefault::getLastCachedString()
{
    return *(m_stringStack.top());
}



XalanDOMString&
StylesheetExecutionContextDefault::getAndPopCachedString()
{
    return *(m_stringStack.release());
}



void
StylesheetExecutionContextDefault::pushProcessCurrentAttribute(const bool processAttribute)
{
    m_processCurrentAttributeStack.push_back(processAttribute);
}



bool
StylesheetExecutionContextDefault::popProcessCurrentAttribute()
{
    assert (m_processCurrentAttributeStack.size() > 0);

    bool processAttribute = m_processCurrentAttributeStack.back();
    m_processCurrentAttributeStack.pop_back();
    return processAttribute;
}



void
StylesheetExecutionContextDefault::pushSkipElementAttributes(bool skipAttributes)
{
    m_skipElementAttributesStack.push_back(skipAttributes);
}



bool
StylesheetExecutionContextDefault::getSkipElementAttributes() const
{
    if (m_skipElementAttributesStack.size() == 0)
    {
        return false;
    }
    else
    {
        return m_skipElementAttributesStack.back();
    }
}



bool
StylesheetExecutionContextDefault::popSkipElementAttributes()
{
    assert(m_skipElementAttributesStack.size() > 0);

    bool skipAttributes = m_skipElementAttributesStack.back();

    m_skipElementAttributesStack.pop_back();

    return skipAttributes;
}



void
StylesheetExecutionContextDefault::pushExecuteIf(bool executeIf)
{
    m_executeIfStack.push_back(executeIf);
}



bool
StylesheetExecutionContextDefault::popExecuteIf()
{
    assert(m_executeIfStack.size() > 0);

    bool executeIf = m_executeIfStack.back();

    m_executeIfStack.pop_back();

    return executeIf;
}



void
StylesheetExecutionContextDefault::beginFormatToText(XalanDOMString&  theResult)
{
    FormatterToTextDOMString* const     theFormatter =
        m_formatterToTextStack.get();
    assert(theFormatter != 0);

    theFormatter->setDOMString(theResult);

    pushOutputContext(theFormatter);
    
    theFormatter->startDocument();
}



void
StylesheetExecutionContextDefault::endFormatToText()
{
    FormatterToText* const  theFormatter = m_formatterToTextStack.top();
    assert(
        theFormatter != 0 &&
        theFormatter->getEncoding().empty() == true &&
        theFormatter->getNormalizeLinefeed() == false &&
        theFormatter->getHandleIgnorableWhitespace() == true);

    theFormatter->endDocument();

    popOutputContext();

    m_formatterToTextStack.release();
}



void
StylesheetExecutionContextDefault::pushXObjectPtr(const XObjectPtr & xobjectPtr)
{   
    m_xobjectPtrStack.push_back(xobjectPtr);
}



void 
StylesheetExecutionContextDefault::popXObjectPtr()
{
    assert(m_xobjectPtrStack.size() > 0);

    m_xobjectPtrStack.back().release();
    m_xobjectPtrStack.pop_back();
}



MutableNodeRefList&
StylesheetExecutionContextDefault::createAndPushMutableNodeRefList()
{
    MutableNodeRefList& nodeList = *(m_mutableNodeRefListStack.get());

    nodeList.clear();

    return nodeList;
}



void 
StylesheetExecutionContextDefault::releaseAndPopMutableNodeRefList()
{
    m_mutableNodeRefListStack.release();
}



void
StylesheetExecutionContextDefault::createAndPushNodesToTransformList(const NodeRefListBase* nodeList)
{
    assert(nodeList != 0);

    NodesToTransform nodesToTransform(nodeList);
    m_nodesToTransformStack.push_back(nodesToTransform);
}



XalanNode* 
StylesheetExecutionContextDefault::getNextNodeToTransform()
{
    assert(m_nodesToTransformStack.size() > 0);

    return m_nodesToTransformStack.back().next();
}



void 
StylesheetExecutionContextDefault::popNodesToTransformList()
{
    assert(m_nodesToTransformStack.size() > 0);

    m_nodesToTransformStack.pop_back();
}


XalanDOMString  StylesheetExecutionContextDefault::FormatterToTextDOMString::s_dummyString(XalanMemMgrs::getDummyMemMgr());



StylesheetExecutionContextDefault::FormatterToTextDOMString::FormatterToTextDOMString(MemoryManager&    theManager) :
    FormatterToText(theManager),
    m_printWriter(s_dummyString)
{
    setNormalizeLinefeed(false);

    setWriter(&m_printWriter);
}


StylesheetExecutionContextDefault::FormatterToTextDOMString::~FormatterToTextDOMString()
{
    assert(s_dummyString.capacity() == 0);
}
#endif


}
