/*
 * 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(XALAN_XSLTENGINEIMPL_HEADER_GUARD)
#define XALAN_XSLTENGINEIMPL_HEADER_GUARD



// Base include file.  Must be first.
#include "XSLTDefinitions.hpp"



// Base class
#include "XSLTProcessor.hpp"




// Standard library headers
#include <cassert>



#include <xalanc/XalanDOM/XalanDOMString.hpp>



#if defined(XALAN_AUTO_PTR_REQUIRES_DEFINITION)
#include <xalanc/XPath/XPathProcessor.hpp>
#endif



#include <xalanc/Include/XalanMemMgrAutoPtr.hpp>
#include <xalanc/Include/XalanMap.hpp>



#include <xalanc/PlatformSupport/AttributeListImpl.hpp>
#include <xalanc/PlatformSupport/DOMStringHelper.hpp>
#include <xalanc/PlatformSupport/PrefixResolver.hpp>



#include <xalanc/DOMSupport/XalanNamespacesStack.hpp>



#include <xalanc/XPath/Function.hpp>



#include <xalanc/XPath/XPathConstructionContextDefault.hpp>



#include "OutputContextStack.hpp"
#include "ProblemListenerDefault.hpp"
#include "ResultNamespacesStack.hpp"
#include "StylesheetExecutionContext.hpp"
#include "XSLTProcessorException.hpp"
#include "XalanParamHolder.hpp"



namespace XERCES_CPP_NAMESPACE
{
    class InputSource;
    class DocumentHandler;
}



namespace XALAN_CPP_NAMESPACE {



typedef xercesc::InputSource      InputSourceType;
typedef xercesc::DocumentHandler  DocumentHandlerType;

using xercesc::InputSource;
using xercesc::DocumentHandler;



// Forward declarations...
class DOMSupport;
class GenerateEvent;
class PrintWriter;
class StylesheetConstructionContext;
class StylesheetRoot;
class XalanAttr;
class XalanSourceTreeDocument;
class XalanText;
class XMLParserLiaison;
class XObject;
class XPathEnvSupport;
class XPathFactory;
class XPathProcessor;
class XSLTResultTarget;



/**
 * It's the responsibility of the XSLTEngineImpl class, collaborating with the
 * XML parser liaison, the DOM, and the XPath engine, to transform a source
 * tree of nodes into a result tree according to instructions and templates
 * specified by a stylesheet tree.  The process method is the primary
 * public entry points.
 * 
 * 
 * If you reuse the processor instance, you should call reset() between calls.
 *
 */

class XALAN_XSLT_EXPORT XSLTEngineImpl : public XSLTProcessor, public PrefixResolver
{
public:

    struct LessXalanDOMStringPointers
    {
        bool
        operator()(
                const XalanDOMString*   theLHS,
                const XalanDOMString*   theRHS) const
        {
            if (theLHS == 0 && theRHS != 0)
            {
                return true;
            }
            else if (theRHS == 0)
            {
                return false;
            }
            else
            {
                return theLHS->compare(*theRHS) < 0 ? true : false;
            }
        }
    };

    typedef XalanVector<const Locator*>         LocatorStack;
    typedef XalanVector<TraceListener*>         TraceListenerVectorType;
    typedef XalanVector<const XalanDOMString*>  XalanDOMStringPointerVectorType;

    typedef XalanVector<bool>                           BoolVectorType;

    struct FindStringPointerFunctor
    {
        FindStringPointerFunctor(const XalanDOMString&  theString) :
            m_string(theString)
        {
        }

        bool
        operator()(const XalanDOMString*    theString) const
        {
            assert(theString != 0);

            return *theString == m_string;
        }

    private:

        const XalanDOMString&   m_string;
    };

    typedef XalanMemMgrAutoPtr<XPathProcessor>              XPathProcessorPtrType;
    typedef Function::XObjectArgVectorType                  XObjectArgVectorType;
    typedef StylesheetExecutionContext::ParamVectorType     ParamVectorType;
    typedef XPathConstructionContext::GetCachedString       CCGetCachedString;
    typedef XPathExecutionContext::GetCachedString          ECGetCachedString;

    typedef XalanMap<XalanDOMString, XalanParamHolder>      ParamMapType;

    // Public members
    //---------------------------------------------------------------------

    /**
     * Construct an XSL processor that can call back to a XML processor, so it
     * can handle included files, and the like. You must create a new instance
     * of the XSLTEngineImpl class each time you run a transformation.
     *
     * @param XMLParserLiaison liaison to an object that can help with a
     *                         specific parser implementation
     * @param xpathEnvSupport  An XPathEnvSupport instance
     * @param domSupport       A DOMSupport instance for the DOM being used
     * @param xobjectFactory   object responsible for XObject objects
     * @param xpathFactory     object responsible for XPath objects
     */
    XSLTEngineImpl(
            MemoryManager&  theManager,
            XMLParserLiaison&   parserLiaison,
            XPathEnvSupport&    xpathEnvSupport,
            DOMSupport&         domSupport,
            XObjectFactory&     xobjectFactory,
            XPathFactory&       xpathFactory);

    virtual
    ~XSLTEngineImpl();

    MemoryManager&
    getMemoryManager() const
    {
        return m_xpathConstructionContext.getMemoryManager();
    }

    MemoryManager&
    getMemoryManager()
    {
        return m_xpathConstructionContext.getMemoryManager();
    }

    /**
     * Perform initialization of statics -- must be called before any
     * processing occurs.  See class XSLTInit.
     */
    static void
    initialize(MemoryManager&   theManager);

    /**
     * Perform termination of statics.  See class XSLTInit.
     */
    static void
    terminate();

    // These methods are inherited from XSLTProcessor ...

    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);

    virtual void
    process(
            const XSLTInputSource&          inputSource, 
            const XSLTInputSource&          stylesheetSource,
            XSLTResultTarget&               outputTarget,
            StylesheetConstructionContext&  constructionContext,
            StylesheetExecutionContext&     executionContext);

    virtual void
    process(
            const XSLTInputSource&          inputSource,
            XSLTResultTarget&               outputTarget,
            StylesheetExecutionContext&     executionContext);

    virtual StylesheetRoot*
    processStylesheet(
            const XSLTInputSource&          stylesheetSource,
            StylesheetConstructionContext&  constructionContext);

    virtual StylesheetRoot*
    processStylesheet(
            const XalanDOMString&           xsldocURLString,
            StylesheetConstructionContext&  constructionContext);

    virtual XalanNode*
    getSourceTreeFromInput(const XSLTInputSource&   inputSource);

    virtual void
    resolveTopLevelParams(StylesheetExecutionContext&   executionContext);

    virtual XMLParserLiaison&
    getXMLParserLiaison() const;

    virtual void
    getUniqueNamespaceValue(XalanDOMString&     theValue);

    virtual void
    setStylesheetParam( 
                    const XalanDOMString&   key,
                    const XalanDOMString&   expression);

    virtual void
    setStylesheetParam(
            const XalanDOMString&   key,
            XObjectPtr              value);

    virtual void
    clearStylesheetParams();

    virtual FormatterListener*
    getFormatterListener() const;

    virtual void
    setFormatterListener(FormatterListener* flistener);

    // Trace-related functions...

    virtual size_type
    getTraceListeners() const;

    virtual void
    addTraceListener(TraceListener*     tl);

    virtual void
    removeTraceListener(TraceListener*  tl);

    virtual void
    fireGenerateEvent(const GenerateEvent&  ge);
      
    virtual void
    fireTraceEvent(const TracerEvent&   te);

    virtual void
    fireSelectEvent(const SelectionEvent&   se);

    virtual bool
    getTraceSelects() const;

    virtual void
    setTraceSelects(bool    b);

    void
    traceSelect(
            StylesheetExecutionContext&     executionContext,
            const ElemTemplateElement&      theTemplate,
            const NodeRefListBase&          nl,
            const XPath*                    xpath) const;

    virtual void
    setQuietConflictWarnings(bool   b);

    virtual void
    setDiagnosticsOutput(PrintWriter*   pw);


    // Inherited from PrefixResolver...

    /**
     * Retrieve a namespace corresponding to a prefix.  This assumes that 
     * the PrevixResolver hold's its own namespace context, or is a namespace
     * context itself.
     *
     * @param prefix Prefix to resolve
     * @return namespace that prefix resolves to, or null if prefix is not found
     */
    virtual const XalanDOMString*
    getNamespaceForPrefix(const XalanDOMString&     prefix) const;

    /**
     * Retrieve the base URI for the resolver.
     * 
     * @return URI string
     */
    virtual const XalanDOMString&
    getURI() const;

    /**
     * Read in the XML file, either producing a Document or calling SAX events,
     * and register the document in a table.  If the document has already been
     * read in, it will not be reparsed.
     *
     * @param urlString location of the XML
     * @param docHandler pointer to SAX event handler
     * @param docToRegister if using a SAX event handler, the object to register in the source docs table. 
     * @return document object, which represents the parsed XML
     * @exception SAXException
     */
    XalanDocument*
    parseXML(
            const XalanDOMString&   urlString,
            DocumentHandler*        docHandler,
            XalanDocument*          docToRegister,
            ErrorHandler*           theErrorHandler = 0);

    /**
     * Read in the XML file, either producing a Document or calling SAX events,
     * and register the document in a table.  If the document has already been
     * read in, it will not be reparsed.
     *
     * @param inputSource location of the XML
     * @param docHandler pointer to SAX event handler
     * @param docToRegister if using a SAX event handler, the object to register in the source docs table. 
     * @return document object, which represents the parsed XML
     * @exception SAXException
     */
    XalanDocument*
    parseXML(
            const InputSource&  inputSource,
            DocumentHandler*    docHandler,
            XalanDocument*      docToRegister,
            ErrorHandler*       theErrorHandler = 0);

    /**
     * Reset the state of the XSL processor by reading in a new XSL stylesheet
     * from a processing instruction.
     *
     * @param xslURLString        valid URI to an XSL stylesheet
     * @param fragBase            base of tree if URI represents document
     *                            fragment
     * @param xmlBaseIdent        base identifier for stylesheet URI
     * @param isRoot              true if stylesheet is root of tree
     * @param constructionContext context for construction of object
     * @return pointer to stylesheet
     */
    Stylesheet*
    getStylesheetFromPIURL(
            const XalanDOMString&           xslURLString,
            XalanNode&                      fragBase,
            const XalanDOMString&           xmlBaseIdent,
            bool                            isRoot,
            StylesheetConstructionContext&  constructionContext);

    /**
     * Flush the pending element.
     */
    void
    flushPending();

    /**
     * Add a namespace declaration to the namespace stack
     *
     * @param prefix       namespace prefix
     * @param namespaceVal value of namespace
     */
    void
    addResultNamespaceDecl(
            const XalanDOMString&   prefix, 
            const XalanDOMString&   namespaceVal)
    {
        addResultNamespaceDecl(
            prefix,
            namespaceVal.c_str(),
            namespaceVal.length());
    }

    /**
     * Add a namespace declaration to the namespace stack
     *
     * @param prefix namespace prefix
     * @param namespaceVal value of namespace
     * @param len length of namespace
     */
    void
    addResultNamespaceDecl(
            const XalanDOMString&   prefix, 
            const XalanDOMChar*     namespaceVal,
            size_type               len)
    {
        m_resultNamespacesStack.addDeclaration(
            prefix,
            namespaceVal,
            len);
    }

    /**
     * Add attribute to attribute list, and if it is a namespace, add it to the
     * namespaces stack.
     *
     * @param attList attribute list added to
     * @param aname   name of attribute
     * @param value   value of attribute
     * @param fromCopy true if the attribute is being copied from the source tree
     * @param locator The Locator for reporting errors.
     */
    void
    addResultAttribute(
            AttributeListImpl&      attList,
            const XalanDOMString&   aname,
            const XalanDOMString&   value,
            bool                    fromCopy = false,
            const Locator*          locator = 0)
    {
        addResultAttribute(
            attList,
            aname,
            value.c_str(),
            fromCopy,
            locator);
    }

    /**
     * Add attribute to attribute list, and if it is a namespace, add it to the
     * namespaces stack.
     *
     * @param attList attribute list added to
     * @param aname name of attribute
     * @param value value of attribute
     * @param fromCopy true if the attribute is being copied from the source tree
     * @param locator The Locator for reporting errors.
     */
    void
    addResultAttribute(
            AttributeListImpl&      attList,
            const XalanDOMString&   aname,
            const XalanDOMChar*     value,
            bool                    fromCopy = false,
            const Locator*          locator = 0)
    {
        addResultAttribute(
            attList,
            aname,
            value,
            length(value),
            fromCopy,
            locator);
    }

    /**
     * Add attribute to attribute list, and if it is a namespace, add it to the
     * namespaces stack.
     *
     * @param attList attribute list added to
     * @param aname name of attribute
     * @param value value of attribute
     * @param theLength The length of the value
     * @param fromCopy true if the attribute is being copied from the source tree
     * @param locator The Locator for reporting errors.
     */
    void
    addResultAttribute(
            AttributeListImpl&      attList,
            const XalanDOMString&   aname,
            const XalanDOMChar*     value,
            size_type               theLength,
            bool                    fromCopy = false,
            const Locator*          locator = 0);

    /**
     * Add attribute to pending attributes list, and if it is a namespace, add
     * it to the namespaces stack.
     *
     * @param aname name of attribute
     * @param value value of attribute
     * @param fromCopy true if the attribute is being copied from the source tree
     * @param locator The Locator for reporting errors.
     */
    void
    addResultAttribute(
            const XalanDOMString&       aname,
            const XalanDOMChar*         value,
            bool                        fromCopy = false,
            const Locator*              locator = 0)
    {
        assert(m_outputContextStack.empty() == false);

        addResultAttribute(
                getPendingAttributesImpl(),
                aname,
                value,
                fromCopy,
                locator);
    }

    /**
     * Add attribute to pending attributes list, and if it is a namespace, add
     * it to the namespaces stack.
     *
     * @param aname   name of attribute
     * @param value   value of attribute
     * @param fromCopy true if the attribute is being copied from the source tree
     * @param locator The Locator for reporting errors.
     */
    void
    addResultAttribute(
            const XalanDOMString&   aname,
            const XalanDOMString&   value,
            bool                    fromCopy = false,
            const Locator*          locator = 0)
    {
        assert(m_outputContextStack.empty() == false);

        addResultAttribute(
                getPendingAttributesImpl(),
                aname,
                value,
                fromCopy,
                locator);
    }

    /**
     * Report an error copying a duplicate namespace node.
     *
     * @param theName The name of the node.
     */
    void
    reportDuplicateNamespaceNodeError(
            const XalanDOMString&   theName,
            const Locator*          locator);

    void
    setDocumentLocator(const Locator*   locator);

    void
    startDocument();

    void
    endDocument();
    
    void
    startElement(
            const XalanDOMChar*     name,
            AttributeListType&      atts);

    void
    endElement(const XalanDOMChar*  name);

    void
    characters (
            const XalanDOMChar*     ch,
            size_type               length);

    void
    ignorableWhitespace(
            const XalanDOMChar*     ch,
            size_type               length);

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

    void
    resetDocument();

    /**
     * Receive notification of character data.
     *
     * @param ch     pointer to characters from the XML document
     * @param start  startng offset in 'ch' array
     * @param length number of characters to read from the array 
     */
    void
    characters(
            const XalanDOMChar*     ch,
            size_type               start,
            size_type               length);

    /**
     * Send character data from the node to the result tree.
     *
     * @param node The node to send.
     */
    void
    characters(const XalanNode&     node);

    /**
     * Send character data from an XObject to the result tree.
     *
     * @param node The xobject to send.
     */
    void
    characters(const XObjectPtr&    xobject);

    /**
     * Receive notification of the beginning of an element with an empty
     * attribute list
     *
     * @param name element type name
     */
    void
    startElement(const XalanDOMChar*    name);

    /**
     * Receive notification of character data. If available, when the
     * disable-output-escaping attribute is used, output raw text without
     * escaping.
     *
     * @param ch pointer to characters from the XML document
     * @param start start position in the array
     * @param length number of characters to read from the array
     */
    void
    charactersRaw(
            const XalanDOMChar*     ch,
            size_type               start,
            size_type               length);

    /**
     * Send raw character data from the node to the result tree.
     *
     * @param node The node to send.
     */
    void
    charactersRaw(const XalanNode&  node);

    /**
     * Send raw character data from an XObject to the result tree.
     *
     * @param node The xobject to send.
     */
    void
    charactersRaw(const XObjectPtr&     xobject);

    /**
     * Called when a Comment is to be constructed.
     *
     * @param   data    pointer to comment data
     */
    void
    comment(const XalanDOMChar*     data);

    /**
     * Receive notification of a entityReference.
     *
     * @param data pointer to characters from the XML document
     * @exception SAXException
     */
    void
    entityReference(const XalanDOMChar*     data);

    /**
     * Receive notification of cdata.
     *
     * @param ch     pointer to characters from the XML document
     * @param start  start position in the array
     * @param length number of characters to read from the array
     */
    void
    cdata(
            const XalanDOMChar*     ch,
            size_type               start,
            size_type               length);

    /**
     * Clone a node to the result tree
     *
     * @param node      node to clone
     * @param cloneTextNodesOnly    if true, only text nodes will be cloned
     * @param locator   the Locator for the event, if any.
     */
    void
    cloneToResultTree(
            const XalanNode&    node,
            bool                cloneTextNodesOnly,
            const Locator*      locator);

    /**
     * Clone a node to the result tree
     *
     * @param node                  node to clone
     * @param nodeType              the type of the node
     * @param overrideStrip         false if white space stripping should be done
     * @param shouldCloneAttributes true if attributes should be cloned
     * @param cloneTextNodesOnly    if true, only text nodes will be cloned
     * @param locator               the Locator for the event, if any.
     */
    void
    cloneToResultTree(
            const XalanNode&        node,
            XalanNode::NodeType     nodeType,
            bool                    overrideStrip,
            bool                    shouldCloneAttributes,
            bool                    cloneTextNodesOnly,
            const Locator*          locator);

   /**
    * Output an object to the result tree by doing the right conversions.
    *
    * @param value the XObject to output
    * @param outputTextNodesOnly if true, only text nodes will be copied
    * @param locator                the Locator for the event, if any.
    */
    void
    outputToResultTree(
            const XObject&      value,
            bool                outputTextNodesOnly,
            const Locator*      locator);

    /**
     * Given a result tree fragment, walk the tree and output it to the result
     * stream.
     *
     * @param theTree result tree fragment
     * @param outputTextNodesOnly if true, only text nodes will be copied
     * @param locator the Locator for the event, if any.
     */
    void
    outputResultTreeFragment(
            const XObject&      theTree,
            bool                outputTextNodesOnly,
            const Locator*      locator)
    {
        outputResultTreeFragment(
            theTree.rtree(),
            outputTextNodesOnly,
            locator);
    }

    /**
     * Given a result tree fragment, walk the tree and output it to the result
     * stream.
     *
     * @param theTree result tree fragment
     * @param outputTextNodesOnly if true, only text nodes will be copied
     * @param locator the Locator for the event, if any.
     */
    void
    outputResultTreeFragment(
            const XalanDocumentFragment&    theTree,
            bool                            outputTextNodesOnly,
            const Locator*                  locator);

    /**
     * Retrieve the root stylesheet.
     * 
     * @return pointer to root stylesheet
     */
    virtual const StylesheetRoot*
    getStylesheetRoot() const;

    /**
     * Set the root stylesheet.
     * 
     * @param theStylesheet pointer to new root stylesheet
     */
    virtual void
    setStylesheetRoot(const StylesheetRoot*     theStylesheet);

    /**
     * Set the execution context.
     * 
     * @param theExecutionContext pointer to new execution context.
     */
    virtual void
    setExecutionContext(StylesheetExecutionContext*     theExecutionContext);

    /**
     * Retrieve the URI for the current XSL namespace, for example,
     * "http://www.w3.org/1999/XSL/Transform"
     * 
     * @return URI string
     */
    static const XalanDOMString&
    getXSLNameSpaceURL()
    {
        return s_XSLNameSpaceURL;
    }

    /**
     * Special Xalan namespace for built-in extensions.
     *
     * @return Xalan namespace for extensions
     */
    static const XalanDOMString&
    getXalanXSLNameSpaceURL()
    {
        return s_XalanNamespaceURL;
    }

    /**
     * Whether to warn about pattern match conflicts.
     *
     * @return true to not warn about pattern match conflicts
     */
    bool
    getQuietConflictWarnings() const
    {
        return m_quietConflictWarnings;
    }

    /**
     * Retrieve the result namespace corresponding to a prefix.
     * 
     * @param prefix prefix for namespace
     * @return string for namespace URI
     */
    const XalanDOMString*
    getResultNamespaceForPrefix(const XalanDOMString&   prefix) const;

    /**
     * Retrieve the result prefix corresponding to a namespace.
     * 
     * @param theNamespace namespace for prefix
     * @return string for namespace prefix
     */
    const XalanDOMString*
    getResultPrefixForNamespace(const XalanDOMString&   theNamespace) const;

    /**
     * Determine whether or not a prefix is in use on the pending element or
     * the pending attributes.
     * 
     * @param thePrefix prefix for namespace
     *
     * @return true if the prefix is in use, false if not.
     */
    bool
    isPendingResultPrefix(const XalanDOMString&     thePrefix) const;

    /**
     * Evaluate an xpath string and return the result as a numberic score.
     *
     * @param str              string to evaluate
     * @param context          context node
     * @param executionContext current execution context
     * @return score number, higher representing better match
     */
    double
    evalMatchPatternStr(
            const XalanDOMString&   str,
            XalanNode*              context,
            XPathExecutionContext&  executionContext);

    /**
     * Create and initialize an xpath and return it.
     *
     * @param str      string for XPath
     * @param resolver resolver for namespace resolution
     * @return pointer to XPath created
     */
    const XPath*
    createMatchPattern(
            const XalanDOMString&   str,
            const PrefixResolver&   resolver);

    /**
     * Return the xpath created by createXPath() or
     * createMatchPattern().
     *
     * @param xpath    The XPath to return.
     */
    void
    returnXPath(const XPath*    xpath);

    /**
     * Copy XMLNS: attributes in if not already in scope.
     *
     * @param src                 source node
     */
    void
    copyNamespaceAttributes(const XalanNode&    src);

    /**
     * Evaluate an xpath string and return the result.
     *
     * @param str              string to evaluate
     * @param executionContext current execution context
     * @return pointer to XObject result
     */
    const XObjectPtr
    evalXPathStr(
            const XalanDOMString&   str,
            XPathExecutionContext&  executionContext);

    /**
     * Evaluate an xpath string and return the result.
     * 
     * @param str              string to evaluate
     * @param contextNode      context node
     * @param prefixResolver prefix resolver to use
     * @param executionContext current execution context
     * @return pointer to XObject result
     */
    const XObjectPtr
    evalXPathStr(
            const XalanDOMString&   str,
            XalanNode*              contextNode,
            const PrefixResolver&   prefixResolver,
            XPathExecutionContext&  executionContext);

    /**
     * Evaluate an xpath string and return the result.
     * 
     * @param str              string to evaluate
     * @param contextNode      context node
     * @param prefixResolver prefix resolver to use
     * @param executionContext current execution context
     * @return pointer to XObject result
     */
    const XObjectPtr
    evalXPathStr(
            const XalanDOMString&   str,
            XalanNode*              contextNode,
            const XalanElement&     prefixResolver,
            XPathExecutionContext&  executionContext);

    /**
     * Copy an attribute to an AttributeListImpl.
     *
     * @param attrName The name of the attribute
     * @param attrValue The value of the attribute
     * @param attrList The attribute list added to
     */
    void
    copyAttributeToTarget(
            const XalanDOMString&   attrName,
            const XalanDOMString&   attrValue,
            AttributeListImpl&      attrList);

    /**
     * Get the factory for making xpaths.
     *
     * @return XPath factory object
     */
    XPathFactory&
    getXPathFactory()
    {
        return m_xpathFactory;
    }

    /**
     * Get the XPath processor object.
     *
     * @return XPathProcessor interface being used
     */
    XPathProcessor&
    getXPathProcessor()
    {
        return *m_xpathProcessor.get();
    }

    /**
     * Reset the state.  This needs to be called after a process() call 
     * is invoked, if the processor is to be used again.
     */
    virtual void
    reset();

    /**
     * Retrieve the XPath environment support object
     *
     * @return XPath environment support object
     */
    XPathEnvSupport&
    getXPathEnvSupport()
    {
        return m_xpathEnvSupport;
    }

    /**
     * Set the problem listener property. The XSL class can have a single
     * listener that can be informed of errors and warnings, and can normally
     * control if an exception is thrown or not (or the problem listeners can
     * throw their own RuntimeExceptions).
     *
     * @param l pointer to ProblemListener interface
     */
    void
    setProblemListener(ProblemListener*     l)
    {
        m_problemListener = l;
    }

    /**
     * Get the problem listener property. The XSL class can have a single
     * listener that can be informed of errors and warnings, and can normally
     * control if an exception is thrown or not (or the problem listeners can
     * throw their own RuntimeExceptions).
     *
     * @return pointer to ProblemListener interface
     */
    ProblemListener*
    getProblemListener() const
    {
        return m_problemListener;
    }

    /*
     * Push a new output context using the provided FormatterListener.
     *
     * @param A pointer to the FormatterListener instance for the new context.
     */
    void
    pushOutputContext(FormatterListener*    theListener)
    {
        m_outputContextStack.pushContext(theListener);
    }

    /*
     * Pop the current output context.
     */
    void
    popOutputContext()
    {
        m_outputContextStack.popContext();
    }

    /*
     * See if there is a pending start document event waiting.
     * @return true if there is a start document event waiting.
     */
    bool
    getHasPendingStartDocument() const
    {
        return getHasPendingStartDocumentImpl();
    }

    /*
     * Set the pending start document event state.
     * @param the new value
     */
    void
    setHasPendingStartDocument(bool b)
    {
        setHasPendingStartDocumentImpl(b);
    }

    /*
     * See if a pending start document event must be flushed.
     * @return true if the event must be flushed.
     */
    bool
    getMustFlushPendingStartDocument() const
    {
        return getMustFlushPendingStartDocumentImpl();
    }

    /*
     * Set the pending start document event flush state.
     * @param the new value
     */
    void
    setMustFlushPendingStartDocument(bool   b)
    {
        setMustFlushPendingStartDocumentImpl(b);
    }

    /**
     * Get the list of attributes yet to be processed
     * 
     * @return attribute list
     */
    const AttributeListType&
    getPendingAttributes() const
    {
        return getPendingAttributesImpl();
    }

    /**
     * Set the list of attributes yet to be processed
     * 
     * @param pendingAttributes The attribute list
     */
    void
    setPendingAttributes(const AttributeListType&   pendingAttributes)
    {
        getPendingAttributesImpl() = pendingAttributes;
    }

    /**
     * Replace the contents of a pending attribute.
     * 
     * @param theName           name of attribute
     * @param theNewType        type of attribute
     * @param theNewValue       new value of attribute
     */
    void
    replacePendingAttribute(
            const XalanDOMChar*     theName,
            const XalanDOMChar*     theNewType,
            const XalanDOMChar*     theNewValue)
    {
        // Remove the old attribute, then add the new one.  AttributeListImpl::addAttribute()
        // does this for us.
        getPendingAttributesImpl().addAttribute(theName, theNewType, theNewValue);
    }

    bool
    isElementPending() const
    {
        return !getPendingElementNameImpl().empty();
    }

    /**
     * Retrieve name of the pending element currently being processed.
     * 
     * @return element name
     */
    const XalanDOMString&
    getPendingElementName() const
    {
        return getPendingElementNameImpl();
    }

    /**
     * Changes the currently pending element name.
     * 
     * @param elementName new name of element
     */
    void
    setPendingElementName(const XalanDOMString&     elementName)
    {
        setPendingElementNameImpl(elementName);
    }

    void
    setPendingElementName(const XalanDOMChar*   elementName)
    {
        setPendingElementNameImpl(elementName);
    }

    /**
     * Get the locator from the top of the locator stack.
     *
     * @return A pointer to the Locator, or 0 if there is nothing on the stack.
     */
    const Locator*
    getLocatorFromStack() const
    {
        return m_stylesheetLocatorStack.empty() == true ? 0 : m_stylesheetLocatorStack.back();
    }

    /**
     * Push a locator on to the locator stack.
     *
     * @param A pointer to the Locator to push.
     */
    void
    pushLocatorOnStack(const Locator*   locator)
    {
        m_stylesheetLocatorStack.push_back(locator);
    }

    /**
     * Pop the locator from the top of the locator stack.
     */
    void
    popLocatorStack()
    {
        if (m_stylesheetLocatorStack.empty() == false)
        {
            m_stylesheetLocatorStack.pop_back();
        }
    }

protected:

    /**
     * Get the list of attributes yet to be processed
     * 
     * @return attribute list
     */
    const AttributeListImpl&
    getPendingAttributesImpl() const
    {
        return m_outputContextStack.getPendingAttributes();
    }

    /**
     * Get the list of attributes yet to be processed
     * 
     * @return attribute list
     */
    AttributeListImpl&
    getPendingAttributesImpl()
    {
        return m_outputContextStack.getPendingAttributes();
    }

    /**
     * Set the list of attributes yet to be processed
     * 
     * @param pendingAttributes The attribute list
     */
    void
    setPendingAttributesImpl(const AttributeListType&   pendingAttributes)
    {
        getPendingAttributesImpl() = pendingAttributes;
    }

    /**
     * Retrieve name of the pending element currently being processed.
     * 
     * @return element name
     */
    const XalanDOMString&
    getPendingElementNameImpl() const
    {
        return m_outputContextStack.getPendingElementName();
    }

    /**
     * Retrieve name of the pending element currently being processed.
     * 
     * @return element name
     */
    XalanDOMString&
    getPendingElementNameImpl()
    {
        return m_outputContextStack.getPendingElementName();
    }

    /**
     * Changes the currently pending element name.
     * 
     * @param elementName new name of element
     */
    void
    setPendingElementNameImpl(const XalanDOMString&     elementName)
    {
        m_outputContextStack.getPendingElementName() = elementName;
    }

    /**
     * Changes the currently pending element name.
     * 
     * @param elementName new name of element
     */
    void
    setPendingElementNameImpl(const XalanDOMChar*   elementName)
    {
        assert(elementName != 0);

        m_outputContextStack.getPendingElementName() = elementName;
    }

    /*
     * See if there is a pending start document event waiting.
     * @return true if there is a start document event waiting.
     */
    bool
    getHasPendingStartDocumentImpl() const
    {
        return m_outputContextStack.getHasPendingStartDocument();
    }

    /*
     * Set the pending start document event state.
     * @param the new value
     */
    void
    setHasPendingStartDocumentImpl(bool     b)
    {
        m_outputContextStack.getHasPendingStartDocument() = b;
    }

    /*
     * See if a pending start document event must be flushed.
     * @return true if the event must be flushed.
     */
    bool
    getMustFlushPendingStartDocumentImpl() const
    {
        return m_outputContextStack.getMustFlushPendingStartDocument();
    }

    /*
     * Set the pending start document event flush state.
     * @param the new value
     */
    void
    setMustFlushPendingStartDocumentImpl(bool   b)
    {
        m_outputContextStack.getMustFlushPendingStartDocument() = b;
    }

    FormatterListener*
    getFormatterListenerImpl() const
    {
        return m_outputContextStack.getFormatterListener();
    }

    void
    setFormatterListenerImpl(FormatterListener*     flistener)
    {
        m_outputContextStack.getFormatterListener() = flistener;
    }

    /**
     * The namespace that the result tree conforms to.  A null value 
     * indicates that result-ns is not used and there is no checking. 
     * A empty string indicates that the result tree conforms to the 
     * default namespace.
     */
    XalanDOMString  m_resultNameSpacePrefix;

    /**
     * The URL that belongs to the result namespace.
     */
    XalanDOMString  m_resultNameSpaceURL;


    /**
     * Copy the attributes from the XSL element to the created 
     * output element.
     */
    void
    copyAttributesToAttList(
            const XalanNode&    node,
            AttributeListImpl&  attList);

    // Factory for creating xpaths.
    XPathFactory&           m_xpathFactory;

    // Factory for creating xobjects
    XObjectFactory&         m_xobjectFactory;

    // The query/pattern-matcher object.
    const XPathProcessorPtrType     m_xpathProcessor;

    /**
     * Stack of Booleans to keep track of if we should be outputting 
     * cdata instead of escaped text.
     */
    BoolVectorType  m_cdataStack;

private:

    /**
     * Issue a warning that only text nodes can be copied.
     *
     * @param sourceNode node in source where error occurred
     * @param locator The Locator to use, if any.
     */
    void
    warnCopyTextNodesOnly(
            const XalanNode*    sourceNode,
            const Locator*      locator);

    /**
     * Clone a text node to the result tree
     *
     * @param node                  node to clone
     * @param overrideStrip         false if white space stripping should be done
     */
    void
    cloneToResultTree(
            const XalanText&    node,
            bool                overrideStrip);

    /**
     * Determine if any pending attributes is a default
     * namespace.
     */
    bool
    pendingAttributesHasDefaultNS() const; 

    void
    addResultNamespace(
            const XalanDOMString&   thePrefix,
            const XalanDOMString&   theName,
            const XalanNode&        theNode,
            AttributeListImpl&      thePendingAttributes,
            bool                    fOnlyIfPrefixNotPresent);

    void
    addResultNamespace(
            const XalanNode&    theNode,
            AttributeListImpl&  thePendingAttributes,
            bool                fOnlyIfPrefixNotPresent = false);

  /**
   * The top of this stack should contain the currently processed
   * stylesheet SAX locator object.
   */
    LocatorStack  m_stylesheetLocatorStack;

    /**
     * The XSL class can have a single listener that can be informed 
     * of errors and warnings, and can normally control if an exception
     * is thrown or not (or the problem listeners can throw their 
     * own RuntimeExceptions).
     */
    ProblemListenerDefault  m_defaultProblemListener;

    ProblemListener*    m_problemListener;

    /**
     * The root of a linked set of stylesheets.
     */
    const StylesheetRoot*               m_stylesheetRoot;

    /**
     * The namespace that we must match as a minimum for XSLT.
     */
    static const XalanDOMString&        s_XSLNameSpaceURL;  //"http://www.w3.org/1999/XSL/Transform"

    /**
     * Special Xalan namespace for built-in extensions.
     */
    static const XalanDOMString&        s_XalanNamespaceURL; // "http://xml.apache.org/xalan"

    /**
     * Prefix to use when generating unique namespaces.
     */
    static const XalanDOMString&        s_uniqueNamespacePrefix;

    /**
     * If this is set to true, selects will be traced
     */
    bool    m_traceSelects;

    /**
     * If this is set to true, do not warn about pattern 
     * match conflicts.
     */
    bool    m_quietConflictWarnings;

    /*
     * A stream to print diagnostics to.
     */
    PrintWriter*    m_diagnosticsPrintWriter;

    /**
     * List of listeners who are interested in tracing what's 
     * being generated.
     */
    TraceListenerVectorType     m_traceListeners;
    
    void
    problem(
            const XalanDOMString&               msg, 
            ProblemListener::eClassification    classification,
            const XalanNode*                    sourceNode,
            const ElemTemplateElement*          styleNode) const;

    void
    problem(
            const XalanDOMString&               msg, 
            ProblemListener::eClassification    classification,
            const Locator&                      locator,
            const XalanNode*                    sourceNode) const;

    void
    problem(
            const XalanDOMString&               msg, 
            ProblemListener::eClassification    classification) const;

  //==========================================================
  // SECTION: Function to do with attribute handling
  //==========================================================

    /**
     * This is used whenever a unique namespace is needed.
     */
    unsigned long       m_uniqueNSValue;

    ParamVectorType     m_topLevelParams;

public:

    /**
     * Reset the vector of top level parameters
     */
    void
    clearTopLevelParams()
    {
        m_topLevelParams.clear();
    }

private:

    bool
    generateCDATASection() const
    {
        if (m_hasCDATASectionElements == false)
        {
            return false;
        }
        else
        {
            assert(m_cdataStack.empty() == false);

            return m_cdataStack.back();
        }
    }

    void
    doFlushPending()
    {
        setMustFlushPendingStartDocument(true);

        flushPending();
    }

    /**
     * Tell if a given element name should output its text 
     * as cdata.
     *
     * @param elementName name of element
     * @return true if it should output as cdata
     */
    bool
    isCDataResultElem(const XalanDOMString&     elementName);

    void
    fireCharacterGenerateEvent(
            const XalanNode&    theNode,
            bool                isCDATA);

    void
    fireCharacterGenerateEvent(
            const XObjectPtr&   theXObject,
            bool                isCDATA);

    void
    fireCharacterGenerateEvent(
            const XalanDOMString&   theString,
            bool                    isCDATA);

    void
    fireCharacterGenerateEvent(
            const XalanDOMChar*     ch,
            size_type               start,
            size_type               length,
            bool                    isCDATA);

    void
    checkDefaultNamespace(
            const XalanDOMString&   theElementName,
            const XalanDOMString&   theElementNamespaceURI);

    void
    error(
            const XalanDOMString&   theMessage,
            const Locator*          theLocator,
            const XalanNode*        theSourceNode);

    void
    warn(
            const XalanDOMString&   theMessage,
            const Locator*          theLocator,
            const XalanNode*        theSourceNode);

    void
    message(
            const XalanDOMString&   theMessage,
            const Locator*          theLocator,
            const XalanNode*        theSourceNode);

    // Data members...
    XMLParserLiaison&   m_parserLiaison;

    XPathEnvSupport&    m_xpathEnvSupport;

    DOMSupport&         m_domSupport;

    /**
     * Current execution context...
     */
    StylesheetExecutionContext*     m_executionContext;

    /*
     * Stack of current output contexts...
     */
    OutputContextStack              m_outputContextStack;

    /*
     * Stack of current result namespaces...
     */
    XalanNamespacesStack            m_resultNamespacesStack;

    /*
     * Dummy AttributeListImpl
     */
    AttributeListImpl                   m_dummyAttributesList;

    XalanDOMString                      m_scratchString;

    XalanDOMStringPointerVectorType     m_attributeNamesVisited;

    bool                                m_hasCDATASectionElements;

    XPathConstructionContextDefault     m_xpathConstructionContext;

    ParamMapType                        m_stylesheetParams;

    static void
    installFunctions(MemoryManager& theManager);

    static void
    uninstallFunctions();


    static const XalanDOMString     s_emptyString;

    static const XalanDOMString&    s_stylesheetNodeName;
    static const XalanDOMString&    s_typeString;
    static const XalanDOMString&    s_hrefString;
    static const XalanDOMString&    s_piTokenizerString;
    static const XalanDOMString&    s_typeValueString1;
    static const XalanDOMString&    s_typeValueString2;
    static const XalanDOMString&    s_typeValueString3;
    static const XalanDOMString&    s_typeValueString4;

    // Not implemented...
    XSLTEngineImpl(const XSLTEngineImpl&);

    XSLTEngineImpl&
    operator=(const XSLTEngineImpl&);

    bool
    operator==(const XSLTEngineImpl&) const;
};



}



#endif  // XALAN_XSLTENGINEIMPL_HEADER_GUARD
