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



// Base class include file.
#include <xalanc/XSLT/StylesheetExecutionContext.hpp>



#include <ctime>
#include <memory>



#include <xalanc/Include/XalanVector.hpp>
#include <xalanc/Include/XalanMap.hpp>
#include <xalanc/Include/XalanSet.hpp>
#include <xalanc/Include/XalanObjectCache.hpp>
#include <xalanc/Include/XalanObjectStackCache.hpp>


#include <xalanc/PlatformSupport/DOMStringHelper.hpp>


#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
#include <xalanc/PlatformSupport/DOMStringPrintWriter.hpp>
#endif



#include <xalanc/XPath/XPathExecutionContextDefault.hpp>



#include <xalanc/XMLSupport/FormatterToText.hpp>



#if defined(XALAN_AUTO_PTR_REQUIRES_DEFINITION)
#include <xalanc/XalanSourceTree/XalanSourceTreeDocument.hpp>
#endif
#include <xalanc/XalanSourceTree/FormatterToSourceTree.hpp>
#include <xalanc/XalanSourceTree/XalanSourceTreeDocumentFragment.hpp>



#include <xalanc/XSLT/CountersTable.hpp>
#include <xalanc/XSLT/NodeSorter.hpp>
#include <xalanc/XSLT/Stylesheet.hpp>
#include <xalanc/XSLT/VariablesStack.hpp>
#include <xalanc/XSLT/XResultTreeFragAllocator.hpp>
#include <xalanc/XSLT/XalanSourceTreeDocumentAllocator.hpp>
#include <xalanc/XSLT/XalanSourceTreeDocumentFragmentAllocator.hpp>



XALAN_CPP_NAMESPACE_BEGIN



class XalanSourceTreeDocument;
class XPathProcessor;
class XSLTEngineImpl;

typedef VariablesStack::ParamsVectorType            ParamsVectorTypeDecl;
XALAN_USES_MEMORY_MANAGER(ParamsVectorTypeDecl)
//
// An class which provides support for executing stylesheets.
//
class XALAN_XSLT_EXPORT StylesheetExecutionContextDefault : public StylesheetExecutionContext
{
public:

#if defined(XALAN_STRICT_ANSI_HEADERS)
    typedef std::clock_t    ClockType;
#else
    typedef clock_t         ClockType;
#endif

    typedef XalanVector<FormatterListener*>             FormatterListenerVectorType;
    typedef XalanVector<PrintWriter*>                   PrintWriterVectorType;
    typedef XalanVector<XalanOutputStream*>             OutputStreamVectorType;

    typedef XalanVector<const ElemTemplateElement*> ElementTemplateElementStackType;
    typedef XALAN_STD_QUALIFIER pair<const XPath*, ClockType>       XPathCacheEntry;
    typedef XalanMap <XalanDOMString, XPathCacheEntry>              XPathCacheMapType;
    typedef XalanVector<const ElemTemplate*>            CurrentTemplateStackType;

    typedef Stylesheet::KeyTablesTableType              KeyTablesTableType;
    typedef ParamsVectorTypeDecl                        ParamsVectorType;

    /**
     * Construct a StylesheetExecutionContextDefault object
     *
     * @param theXPathEnvSupport XPath environment support class instance
     * @param theDOMSupport      DOMSupport class instance
     * @param theXobjectFactory  factory class instance for XObjects
     * @param theCurrentNode     current node in the source tree
     * @param theContextNodeList node list for current context
     * @param thePrefixResolver  pointer to prefix resolver to use
     */ 
    StylesheetExecutionContextDefault(
            MemoryManager&      theManager,
            XSLTEngineImpl&         xsltProcessor,
            XPathEnvSupport&        theXPathEnvSupport,
            DOMSupport&             theDOMSupport,
            XObjectFactory&         theXObjectFactory,
            XalanNode*              theCurrentNode = 0,
            const NodeRefListBase*  theContextNodeList = 0,
            const PrefixResolver*   thePrefixResolver = 0);

    /**
     * Construct a StylesheetExecutionContextDefault object
     *
     * @param theXPathEnvSupport XPath environment support class instance
     * @param theDOMSupport      DOMSupport class instance
     * @param theXobjectFactory  factory class instance for XObjects
     * @param theCurrentNode     current node in the source tree
     * @param theContextNodeList node list for current context
     * @param thePrefixResolver  pointer to prefix resolver to use
     */
    explicit
    StylesheetExecutionContextDefault(
            MemoryManager&      theManager,
            XalanNode*              theCurrentNode = 0,
            const NodeRefListBase*  theContextNodeList = 0,
            const PrefixResolver*   thePrefixResolver = 0);

    static StylesheetExecutionContextDefault*
    create(
            MemoryManager&      theManager,
            XalanNode*              theCurrentNode = 0,
            const NodeRefListBase*  theContextNodeList = 0,
            const PrefixResolver*   thePrefixResolver = 0);

    virtual
    ~StylesheetExecutionContextDefault();


    /**
     * Set the XPathEnvSupport instance.
     *
     * @param theSupport a reference to the instance to use.
     */
    void
    setXPathEnvSupport(XPathEnvSupport*     theSupport)
    {
        m_xpathExecutionContextDefault.setXPathEnvSupport(theSupport);
    }

    /**
     * Set the DOMSupport instance.
     *
     * @param theDOMSupport a reference to the instance to use.
     */
    void
    setDOMSupport(DOMSupport*   theDOMSupport)
    {
        m_xpathExecutionContextDefault.setDOMSupport(theDOMSupport);
    }

    /**
     * Set the XObjectFactory instance.
     *
     * @param theFactory a reference to the instance to use.
     */
    void
    setXObjectFactory(XObjectFactory*   theXObjectFactory)
    {
        m_xpathExecutionContextDefault.setXObjectFactory(theXObjectFactory);

        m_xobjectFactory = theXObjectFactory;
    }


    /**
     * Set the DOMSupport instance.
     *
     * @param theDOMSupport a reference to the instance to use.
     */
    void
    setXSLTProcessor(XSLTEngineImpl*    theProcessor)
    {
        m_xsltProcessor = theProcessor;
    }

    bool
    getUsePerInstanceDocumentFactory() const
    {
        return m_usePerInstanceDocumentFactory;
    }

    void
    setUsePerInstanceDocumentFactory(bool   fValue)
    {
        m_usePerInstanceDocumentFactory = fValue;
    }


    // These interfaces are inherited from StylesheetExecutionContext...

    virtual bool
    getQuietConflictWarnings() const;

    virtual bool
    getCopyTextNodesOnly() const;

    virtual void
    pushCopyTextNodesOnly(bool copyTextNodesOnly);

    virtual bool
    popCopyTextNodesOnly();

#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
    virtual void
    pushProcessCurrentAttribute(bool processAttribute);

    virtual bool
    popProcessCurrentAttribute();

    virtual void
    pushSkipElementAttributes(bool skipAttributes);

    virtual bool
    getSkipElementAttributes() const;

    virtual bool
    popSkipElementAttributes();

    virtual void
    pushExecuteIf(bool executeIf);
    
    virtual bool
    popExecuteIf();
#endif

    virtual XalanNode*
    getRootDocument() const;

    virtual void
    setRootDocument(XalanNode*  theDocument);

    virtual void
    setStylesheetRoot(const StylesheetRoot*     theStylesheet);

    virtual const XalanQName*
    getCurrentMode() const;

    virtual void
    pushCurrentMode(const XalanQName*   theMode);
    
    virtual void
    popCurrentMode();

    virtual const ElemTemplate*
    getCurrentTemplate() const;

    virtual void
    pushCurrentTemplate(const ElemTemplate* theTemplate);

    virtual void
    popCurrentTemplate();

    virtual bool
    isElementPending() const;

    virtual void
    replacePendingAttribute(
            const XalanDOMChar*     theName,
            const XalanDOMChar*     theNewType,
            const XalanDOMChar*     theNewValue);

    virtual void
    pushOutputContext(FormatterListener*    flistener = 0);

    virtual void
    popOutputContext();

    virtual void
    addResultAttribute(
            const XalanDOMString&   aname,
            const XalanDOMString&   value);

    virtual void
    addResultAttribute(
            const XalanDOMString&   aname,
            const XalanDOMChar*     value);

    virtual void
    copyNamespaceAttributes(const XalanNode&    src);

    virtual const XalanDOMString*
    getResultPrefixForNamespace(const XalanDOMString&   theNamespace) const;

    virtual const XalanDOMString*
    getResultNamespaceForPrefix(const XalanDOMString&   thePrefix) const;

    virtual bool
    isPendingResultPrefix(const XalanDOMString& thePrefix);

    virtual void
    getUniqueNamespaceValue(XalanDOMString&     theValue) const;

    virtual FormatterListener*
    getFormatterListener() const;

    virtual void
    setFormatterListener(FormatterListener*     flistener);

    virtual int
    getIndent() const;

    virtual void
    setIndent(int   indentAmount);

    virtual const XPath*
    createMatchPattern(
            const XalanDOMString&   str,
            const PrefixResolver&   resolver);

    virtual void
    returnXPath(const XPath*    xpath);

    virtual void
    pushTopLevelVariables(const ParamVectorType&    topLevelParams);


    virtual const XObjectPtr
    createVariable(
            const XPath&                xpath,
            XalanNode*                  contextNode,
            const PrefixResolver&       resolver);

#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
    virtual const XObjectPtr
    createVariable(
            const ElemTemplateElement&  templateChild,
            XalanNode*                  sourceNode);
#endif

    virtual void
    pushVariable(
            const XalanQName&           name,
            const ElemTemplateElement*  element,
            const XalanDOMString&       str,
            XalanNode*                  contextNode,
            const PrefixResolver&       resolver);

    virtual void
    pushVariable(
            const XalanQName&           name,
            const XObjectPtr            val,
            const ElemTemplateElement*  element);

    virtual void
    pushVariable(
            const XalanQName&           name,
            const ElemVariable*         var,
            const ElemTemplateElement*  element);

    virtual void
    pushVariable(
            const XalanQName&           name,
            const ElemTemplateElement*  element,
            const XPath&                xpath,
            XalanNode*                  contextNode,
            const PrefixResolver&       resolver);

#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
    virtual void
    pushVariable(
            const XalanQName&           name,
            const ElemTemplateElement*  element,
            const ElemTemplateElement&  templateChild,
            XalanNode*                  sourceNode);
#endif


    virtual void
    pushContextMarker();

    virtual void
    popContextMarker();

    virtual void
    resolveTopLevelParams();

    virtual void
    clearTopLevelParams();

#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
    virtual void beginParams();

    virtual void endParams();

    virtual void pushParam(const XalanQName& qName,const XObjectPtr& theValue);
#else
    virtual void
    pushParams(const ElemTemplateElement&   xslCallTemplateElement);
#endif

    virtual const XObjectPtr
    getParamVariable(const XalanQName&  theName);

    virtual void
    pushElementFrame(const ElemTemplateElement*     elem);

    virtual void
    popElementFrame();

    virtual int
    getGlobalStackFrameIndex() const;

    virtual int
    getCurrentStackFrameIndex() const;

    virtual void
    pushCurrentStackFrameIndex(int currentStackFrameIndex = -1);

    virtual void
    popCurrentStackFrameIndex();

    virtual void
    startDocument();

    virtual void
    endDocument();

    virtual void
    startElement(const XalanDOMChar*    name);

    virtual void
    endElement(const XalanDOMChar*  name);

    virtual void
    characters(
            const XalanDOMChar*     ch,
            fl_size_type            start,
            fl_size_type            length);

    virtual void
    charactersRaw(
            const XalanDOMChar*     ch,
            fl_size_type            start,
            fl_size_type            length);

    virtual void
    comment(const XalanDOMChar*     data);

    virtual void
    processingInstruction(
            const XalanDOMChar*     target,
            const XalanDOMChar*     data);

    virtual void
    flushPending();

    virtual void
    cloneToResultTree(
            const XalanNode&    node,
            const Locator*      locator);

    virtual void
    cloneToResultTree(
            const XalanNode&        node,
            XalanNode::NodeType     nodeType,
            bool                    overrideStrip,
            bool                    shouldCloneAttributes,
            const Locator*          locator);

#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
    virtual void
    beginCreateXResultTreeFrag(XalanNode*   sourceNode);

    virtual const XObjectPtr
    endCreateXResultTreeFrag();

    virtual void
    beginFormatToText(XalanDOMString&   theResult);

    virtual void
    endFormatToText();
#endif


#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
    virtual const XObjectPtr
    createXResultTreeFrag(
            const ElemTemplateElement&  templateChild,
            XalanNode*                  sourceNode);
#endif

    virtual void
    outputToResultTree(
            const XObject&      xobj,
            const Locator*      locator);

    virtual void
    outputResultTreeFragment(
            const XObject&      theTree,
            const Locator*      locator);

    virtual const XalanDOMString&
    getXSLNameSpaceURL() const;

    virtual const XalanDOMString&
    getXalanXSLNameSpaceURL() const;

    virtual bool
    findOnElementRecursionStack(const ElemTemplateElement*  theElement) const;

    virtual void
    pushOnElementRecursionStack(const ElemTemplateElement*  theElement);

    virtual const ElemTemplateElement*
    popElementRecursionStack();

    virtual bool
    returnXResultTreeFrag(XResultTreeFrag*  theXResultTreeFrag);

    virtual eEscapeURLs
    getEscapeURLs() const;

    virtual void
    setEscapeURLs(eEscapeURLs   value);

    virtual eOmitMETATag
    getOmitMETATag() const;

    void
    setOmitMETATag(eOmitMETATag     value);

    virtual FormatterListener*
    createFormatterToXML(
            Writer&                 writer,
            const XalanDOMString&   version = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
            bool                    doIndent = false,
            int                     indent = eDefaultXMLIndentAmount,
            const XalanDOMString&   encoding = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
            const XalanDOMString&   mediaType = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
            const XalanDOMString&   doctypeSystem = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
            const XalanDOMString&   doctypePublic = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
            bool                    xmlDecl = true,
            const XalanDOMString&   standalone = XalanDOMString(XalanMemMgrs::getDummyMemMgr()));

    virtual FormatterListener*
    createFormatterToHTML(
            Writer&                 writer,
            const XalanDOMString&   encoding = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
            const XalanDOMString&   mediaType = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
            const XalanDOMString&   doctypeSystem = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
            const XalanDOMString&   doctypePublic = XalanDOMString(XalanMemMgrs::getDummyMemMgr()),
            bool                    doIndent = true,
            int                     indent = eDefaultHTMLIndentAmount,
            bool                    escapeURLs = true,
            bool                    omitMetaTag = false);

    virtual FormatterListener*
    createFormatterToText(
            Writer&                 writer,
            const XalanDOMString&   encoding);

#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
    virtual NodeSorter*
    getNodeSorter();
#else
    virtual NodeSorter*
    borrowNodeSorter();

    virtual bool
    returnNodeSorter(NodeSorter*    theSorter);
#endif

    virtual XalanNumberFormatAutoPtr
    createXalanNumberFormat();

    // A basic class to create XalanNumberFormat instances...
    class XALAN_XSLT_EXPORT XalanNumberFormatFactory
    {
    public:

        explicit
        XalanNumberFormatFactory();

        virtual
        ~XalanNumberFormatFactory();

        virtual XalanNumberFormat*
        create(MemoryManager& theManager);
    };

    static XalanNumberFormatFactory&
    getDefaultXalanNumberFormatFactory()
    {
        return s_defaultXalanNumberFormatFactory;
    }

    /**
     * Static function to install a new XalanNumberFormatFactory.
     * The caller owns the XalanNumberFormatFactory instance.
     *
     * @param a pointer to the new factory instance to use.
     * @return a pointer to the old factory instance.
     */
    static XalanNumberFormatFactory*
    installXalanNumberFormatFactory(XalanNumberFormatFactory*   theFactory);


    virtual tl_size_type
    getTraceListeners() const;

    virtual void
    fireGenerateEvent(const GenerateEvent&  ge);

    virtual void
    fireTraceEvent(const TracerEvent&   te);

    virtual void
    fireSelectEvent(const SelectionEvent&   se);

    virtual bool
    getTraceSelects() const;

    virtual void
    traceSelect(
            const ElemTemplateElement&  theStylesheetElement,
            const NodeRefListBase&      nl,
            const XPath*                xpath);

    virtual int
    collationCompare(
            const XalanDOMString&               theLHS,
            const XalanDOMString&               theRHS,
            XalanCollationServices::eCaseOrder  theCaseOrder = XalanCollationServices::eDefault);

    virtual int
    collationCompare(
            const XalanDOMString&               theLHS,
            const XalanDOMString&               theRHS,
            const XalanDOMString&               theLocale,
            XalanCollationServices::eCaseOrder  theCaseOrder = XalanCollationServices::eDefault);

    virtual int
    collationCompare(
            const XalanDOMChar*                 theLHS,
            const XalanDOMChar*                 theRHS,
            XalanCollationServices::eCaseOrder  theCaseOrder = XalanCollationServices::eDefault);

    virtual int
    collationCompare(
            const XalanDOMChar*                 theLHS,
            const XalanDOMChar*                 theRHS,
            const XalanDOMChar*                 theLocale,
            XalanCollationServices::eCaseOrder  theCaseOrder = XalanCollationServices::eDefault);

    typedef XalanCollationServices::CollationCompareFunctor     CollationCompareFunctor;

    class XALAN_XSLT_EXPORT DefaultCollationCompareFunctor : public CollationCompareFunctor
    {
    public:

        DefaultCollationCompareFunctor();

        virtual
        ~DefaultCollationCompareFunctor();

        virtual int
        operator()(
            const XalanDOMChar*                 theLHS,
            const XalanDOMChar*                 theRHS,
            XalanCollationServices::eCaseOrder  theCaseOrder = XalanCollationServices::eDefault) const;

        virtual int
        operator()(
            const XalanDOMChar*                 theLHS,
            const XalanDOMChar*                 theRHS,
            const XalanDOMChar*                 theLocale,
            XalanCollationServices::eCaseOrder  theCaseOrder = XalanCollationServices::eDefault) const;
    };


    const CollationCompareFunctor*
    installCollationCompareFunctor(CollationCompareFunctor*     theFunctor);

    CollationCompareFunctor*
    uninstallCollationCompareFunctor();


    class XALAN_XSLT_EXPORT FormatNumberFunctor
    {
    public:

        FormatNumberFunctor() {};

        virtual
        ~FormatNumberFunctor() {};

        virtual void
        operator() (
            XPathExecutionContext&              executionContext,
            double                              theNumber,
            const XalanDOMString&               thePattern,
            const XalanDecimalFormatSymbols*    theDFS,
            XalanDOMString&                     theResult,
            const XalanNode*                    context = 0,
            const Locator*                      locator = 0) const = 0;
    };

    virtual void
    formatNumber(
            double                  number,
            const XalanDOMString&   pattern,
            XalanDOMString&         theResult,
            const XalanNode*        context = 0,
            const Locator*          locator = 0);

    virtual void
    formatNumber(
            double                  number,
            const XalanDOMString&   pattern,
            const XalanDOMString&   dfsName,
            XalanDOMString&         theResult,
            const XalanNode*        context = 0,
            const Locator*          locator = 0);


    const FormatNumberFunctor* 
    installFormatNumberFunctor(FormatNumberFunctor*     formatNumberFunctor);
    
    FormatNumberFunctor*
    uninstallFormatNumberFunctor();

    virtual PrintWriter*
    createPrintWriter(XalanOutputStream*        theTextOutputStream);

    virtual PrintWriter*
    createPrintWriter(
            const XalanDOMString&       theFileName,
            const XalanDOMString&       theEncoding);

    virtual PrintWriter*
    createPrintWriter(StreamType&   theStream);

    virtual PrintWriter*
    createPrintWriter(FILE*     theStream);

    virtual CountersTable&
    getCountersTable();

    virtual void
    characters(const XalanNode&     node);

    virtual void
    characters(const XObjectPtr&    xobject);

    virtual void
    charactersRaw(const XalanNode&  node);

    virtual void
    charactersRaw(const XObjectPtr&     xobject);


    // These interfaces are inherited from XPathExecutionContext...

    virtual void
    reset();

    virtual XalanNode*
    getCurrentNode() const;

    virtual void
    pushCurrentNode(XalanNode*  theCurrentNode);

    virtual void
    popCurrentNode();

    virtual bool
    isNodeAfter(
            const XalanNode&    node1,
            const XalanNode&    node2) const;

    virtual void
    pushContextNodeList(const NodeRefListBase&  theList);

    virtual void    
    popContextNodeList();

    virtual const NodeRefListBase&
    getContextNodeList() const;

    virtual size_type
    getContextNodeListLength() const;

    virtual size_type
    getContextNodeListPosition(const XalanNode&     contextNode) const;

    virtual bool
    elementAvailable(const XalanQName&  theQName) const;

    virtual bool
    elementAvailable(
            const XalanDOMString&   theName,
            const Locator*          locator) const;

    virtual bool
    functionAvailable(const XalanQName&     theQName) const;

    virtual bool
    functionAvailable(
            const XalanDOMString&   theName,
            const Locator*          locator) const;

    virtual const XObjectPtr
    extFunction(
            const XalanDOMString&           theNamespace,
            const XalanDOMString&           functionName,
            XalanNode*                      context,
            const XObjectArgVectorType&     argVec,
            const Locator*                  locator);

    virtual XalanDocument*
    parseXML(
            MemoryManager&      theManager,
            const XalanDOMString&   urlString,
            const XalanDOMString&   base,
            ErrorHandler*           theErrorHandler = 0) const;

    virtual MutableNodeRefList*
    borrowMutableNodeRefList();

    virtual bool
    returnMutableNodeRefList(MutableNodeRefList*    theList);

    virtual MutableNodeRefList*
    createMutableNodeRefList(MemoryManager& theManager) const;

#if !defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
    virtual void
    createUseAttributeSetIndexesOnStack();

    virtual UseAttributeSetIndexes&
    getUseAttributeSetIndexes();

    virtual void
    popUseAttributeSetIndexesFromStack();
    
    virtual void
    pushInvoker(const ElemTemplateElement * invoker);

    virtual void
    popInvoker();

    virtual const ElemTemplateElement*
    getInvoker() const;

    virtual MutableNodeRefList& 
    createAndPushMutableNodeRefList();

    virtual void 
    releaseAndPopMutableNodeRefList();

    virtual void
    pushXObjectPtr(const XObjectPtr& xobjectPtr);

    virtual void 
    popXObjectPtr();

    virtual void
    createAndPushNodesToTransformList(const NodeRefListBase* nodeList);

    virtual XalanNode* 
    getNextNodeToTransform();

    virtual void 
    popNodesToTransformList();

    virtual XalanDOMString&
    getAndPushCachedString();

    virtual XalanDOMString&
    getLastCachedString();

    virtual XalanDOMString&
    getAndPopCachedString();
#endif

    virtual XalanDOMString&
    getCachedString();

    virtual bool
    releaseCachedString(XalanDOMString&     theString);


    virtual void
    getNodeSetByKey(
            XalanNode*              context,
            const XalanQName&       qname,
            const XalanDOMString&   ref,
            const Locator*          locator,
            MutableNodeRefList&     nodelist);

    virtual void
    getNodeSetByKey(            
            XalanNode*              context,
            const XalanDOMString&   name,
            const XalanDOMString&   ref,
            const Locator*          locator,
            MutableNodeRefList&     nodelist);

    virtual const XObjectPtr
    getVariable(
            const XalanQName&   name,
            const Locator*      locator = 0);

    virtual const PrefixResolver*
    getPrefixResolver() const;

    virtual void
    setPrefixResolver(const PrefixResolver*     thePrefixResolver);

    virtual const XalanDOMString*
    getNamespaceForPrefix(const XalanDOMString&     prefix) const;

    virtual const XalanDOMString&
    findURIFromDoc(const XalanDocument*     owner) const;

    virtual const XalanDOMString&
    getUnparsedEntityURI(
            const XalanDOMString&   theName,
            const XalanDocument&    theDocument) const;

    virtual bool
    shouldStripSourceNode(const XalanText&  node);

    virtual XalanDocument*
    getSourceDocument(const XalanDOMString&     theURI) const;

    virtual void
    setSourceDocument(
            const XalanDOMString&   theURI,
            XalanDocument*          theDocument);

    // These interfaces are inherited from ExecutionContext...
    virtual void
    problem(
            eSource                 source,
            eClassification         classification,
            const XalanDOMString&   msg,
            const Locator*          locator,
            const XalanNode*        sourceNode);

    virtual void
    problem(
            eSource                 source,
            eClassification         classification,
            const XalanDOMString&   msg,
            const XalanNode*        sourceNode);

    class XPathCacheReturnFunctor
    {
    public:

        XPathCacheReturnFunctor(XSLTEngineImpl&     xsltProcessor) :
            m_xsltProcessor(xsltProcessor)
        {
        }

        void
        operator()(const XPathCacheMapType::value_type&     theCacheEntry);

    private:

        XSLTEngineImpl&     m_xsltProcessor;
    };

    /**
     * Get a XalanSourceTreeDocument, primarily for creating result 
     * tree fragments.
     */
    XalanSourceTreeDocument*
    getSourceTreeFactory(MemoryManager& theManager) const;

#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
protected:

    virtual FormatterToText*
    borrowFormatterToText();

    virtual bool
    returnFormatterToText(FormatterToText*  theFormatter);
#endif

private:

    const XalanDecimalFormatSymbols*
    getDecimalFormatSymbols(const XalanQName&   qname);

#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
    /**
     * Given a context, create the params for a template
     * call.
     *
     * @param xslCallTemplateElement "call-template" element
     * @param params The params
     */
    void
    getParams(
            const ElemTemplateElement&  xslCallTemplateElement,
            ParamsVectorType&           params);
#endif

    /**
     * Determine if the XPath is one that we have cached.
     *
     * @param theXPath the XPath instance to check
     * @return true if the instance has been cached, false if not.
     */
    bool
    isCached(const XPath*   theXPath);

    /**
     * Clear out the cache of XPath instances.
     */
    void
    clearXPathCache();

    /**
     * Add an XPath instance to the cache, clearing out an old entry
     * if the cache is full.
     *
     * @param pattern the key for looking up the XPath instance in the cache.
     * @param theXPath the XPath instance to cache
     */
    void
    addToXPathCache(
            const XalanDOMString&   pattern,
            const XPath*            theXPath);


    /**
     * Clean up anything that was created for use only during the transformation.
     */
    void
    cleanUpTransients();

    XPathExecutionContextDefault    m_xpathExecutionContextDefault;

    XSLTEngineImpl*                 m_xsltProcessor;

    XalanNode*                      m_rootDocument;

    enum { eXPathCacheMax = 50,
           eDefaultParamsVectorSize = 10,
           eXResultTreeFragAllocatorBlockSize = 10,
           eDocumentAllocatorBlockSize = 10,
           eDocumentFragmentAllocatorBlockSize = 10,
           eDefaultAttributeAllocatorBlockSize = 10,
           eDefaultAttributeNSAllocatorBlockSize = 10,
           eDefaultCommentAllocatorBlockSize = 10,
           eDefaultElementAllocatorBlockSize = 10,
           eDefaultElementNSAllocatorBlockSize = 10,
           eDefaultPIAllocatorBlockSize = 10,
           eDefaultTextAllocatorBlockSize = 20,
           eDefaultTextIWSAllocatorBlockSize = 20 };

    ElementTemplateElementStackType     m_elementRecursionStack;

    const StylesheetRoot*               m_stylesheetRoot;

    FormatterListenerVectorType         m_formatterListeners;

    PrintWriterVectorType               m_printWriters;

    OutputStreamVectorType              m_outputStreams;

    CollationCompareFunctor*            m_collationCompareFunctor;

    FormatNumberFunctor *               m_formatNumberFunctor;

    /**
     * Holds all information about variables during execution.
     */
    VariablesStack                      m_variablesStack;

    ParamsVectorType                    m_paramsVector;

    XPathCacheMapType                   m_matchPatternCache;

    KeyTablesTableType                  m_keyTables;

    CountersTable                       m_countersTable;

    /**
     * The factory that will be used to create result tree fragments based on our
     * internal source tree.
     */
    mutable XalanMemMgrAutoPtr<XalanSourceTreeDocument>     m_sourceTreeResultTreeFactory;

    // Holds the current mode.
    const XalanQName*                   m_mode;

    CurrentTemplateStackType            m_currentTemplateStack;

    int                                 m_indentAmount;

    XResultTreeFragAllocator            m_xresultTreeFragAllocator;

    XalanSourceTreeDocumentFragmentAllocator    m_documentFragmentAllocator;

    XalanSourceTreeDocumentAllocator    m_documentAllocator;

    typedef XalanVector<bool>       BooleanStackType;
    typedef XalanVector<const XalanQName*>  ModeStackType;
    typedef XalanVector<int>            IntStackType;

    BooleanStackType                    m_copyTextNodesOnlyStack;
    ModeStackType                       m_modeStack;
    IntStackType                        m_currentIndexStack;

#if defined(XALAN_RECURSIVE_STYLESHEET_EXECUTION)
    typedef XalanMemoryManagerObjectCacheDefault<FormatterToText>            FormatterToTextCacheType;
    typedef XalanMemoryManagerObjectCacheDefault<FormatterToSourceTree>     FormatterToSourceTreeCacheType;
    typedef XalanMemoryManagerObjectCacheDefault<NodeSorter>                NodeSorterCacheType;
    
    FormatterToTextCacheType            m_formatterToTextCache;

    FormatterToSourceTreeCacheType      m_formatterToSourceTreeCache;

    NodeSorterCacheType                 m_nodeSorterCache;
#else

    class FormatterToTextDOMString : public FormatterToText
    {
    public:

        FormatterToTextDOMString(MemoryManager& theManager);

        virtual
        ~FormatterToTextDOMString();

        void
        setDOMString(XalanDOMString&    theString)
        {
            m_printWriter.setString(theString);
        }

    private:

        // These are not defined...
        FormatterToTextDOMString(const FormatterToTextDOMString&);

        FormatterToTextDOMString&
        operator=(const FormatterToTextDOMString&);

        bool
        operator==(const FormatterToTextDOMString&) const;


        // Data members...
        DOMStringPrintWriter    m_printWriter;

        static XalanDOMString   s_dummyString;
    };

    typedef XalanVector<XObjectPtr>                             XObjectPtrStackType;
    typedef XalanVector<ParamsVectorType>                       ParamsVectorStackType;
    typedef XalanVector<UseAttributeSetIndexes>                 UseAttributeSetIndexesStackType;
    typedef XalanObjectStackCache<MutableNodeRefList,DefaultCacheCreateFunctorMemMgr<MutableNodeRefList> >          
                                                                MutableNodeRefListStackType;

    typedef XalanObjectStackCache<XalanDOMString,DefaultCacheCreateFunctorMemMgr<XalanDOMString> >              
                                                                StringStackType;

    typedef XalanObjectStackCache<FormatterToTextDOMString,DefaultCacheCreateFunctorMemMgr<FormatterToTextDOMString> >
                                                                FormatterToTextStackType;
    typedef XalanObjectStackCache<FormatterToSourceTree,DefaultCacheCreateFunctorMemMgr<FormatterToSourceTree> >
                                                                FormatterToSourceTreeStackType;

    /*
     * class to maintain the list of nodes to be transformed by an element
     */
    class NodesToTransform
    {
    public:
        NodesToTransform(const NodeRefListBase* nodeList) : 
            m_nodeList(nodeList), m_index(0)
        {
            assert(m_nodeList != 0);
        }

        const NodeRefListBase* operator() () 
        {
            return m_nodeList;
        }

        NodeRefListBase::size_type& index()
        {
            return m_index;
        }

        XalanNode* next()
        {
            if (m_index < m_nodeList->getLength())
            {
                return m_nodeList->item(m_index++);
            }
            return 0;
        }

    private:
        const NodeRefListBase*  m_nodeList;
        NodeRefListBase::size_type  m_index;
    };

    typedef XalanVector<NodesToTransform>           NodesToTransformStackType;

    XObjectPtrStackType                 m_xobjectPtrStack;
    MutableNodeRefListStackType         m_mutableNodeRefListStack;
    NodesToTransformStackType           m_nodesToTransformStack;
    BooleanStackType                    m_processCurrentAttributeStack;
    BooleanStackType                    m_executeIfStack;
    StringStackType                     m_stringStack;
    FormatterToTextStackType            m_formatterToTextStack;
    BooleanStackType                    m_skipElementAttributesStack;
    FormatterToSourceTreeStackType      m_formatterToSourceTreeStack;
    ParamsVectorStackType               m_paramsVectorStack;
    ElementTemplateElementStackType     m_elementInvokerStack;
    UseAttributeSetIndexesStackType     m_useAttributeSetIndexesStack;

    NodeSorter                          m_nodeSorter;
#endif

    // If true, we will use a separate document factory for
    // result tree fragments.
    bool                                m_usePerInstanceDocumentFactory;

    // Determines whether or not to override the property in the stylesheet.
    eEscapeURLs                         m_escapeURLs;

    // Determines whether or not to override the property in the stylesheet.
    eOmitMETATag                        m_omitMETATag;

    static XalanNumberFormatFactory     s_defaultXalanNumberFormatFactory;

    static XalanNumberFormatFactory*    s_xalanNumberFormatFactory;

    static const DefaultCollationCompareFunctor     s_defaultCollationFunctor;
};



XALAN_CPP_NAMESPACE_END



#endif  // STYLESHEETEXECUTIONCONTEXTDEFAULT_HEADER_GUARD_1357924680
