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

import java.io.IOException;
import java.io.StringWriter;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.SourceLocator;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.xalan.extensions.ExtensionsTable;
import org.apache.xalan.res.XSLMessages;
import org.apache.xalan.res.XSLTErrorResources;
import org.apache.xml.serializer.Method;
import org.apache.xml.serializer.Serializer;
import org.apache.xml.serializer.SerializerFactory;
import org.apache.xalan.templates.AVT;
import org.apache.xalan.templates.Constants;
import org.apache.xalan.templates.ElemAttributeSet;
import org.apache.xalan.templates.ElemForEach;
import org.apache.xalan.templates.ElemSort;
import org.apache.xalan.templates.ElemTemplate;
import org.apache.xalan.templates.ElemTemplateElement;
import org.apache.xalan.templates.ElemTextLiteral;
import org.apache.xalan.templates.ElemVariable;
import org.apache.xalan.templates.OutputProperties;
import org.apache.xalan.templates.Stylesheet;
import org.apache.xalan.templates.StylesheetComposed;
import org.apache.xalan.templates.StylesheetRoot;
import org.apache.xalan.templates.XUnresolvedVariable;
import org.apache.xalan.trace.GenerateEvent;
import org.apache.xalan.trace.TraceManager;
import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMIterator;
import org.apache.xml.dtm.DTMManager;
import org.apache.xml.dtm.DTMWSFilter;
import org.apache.xml.serializer.ToSAXHandler;
import org.apache.xml.serializer.ToTextStream;
import org.apache.xml.serializer.ToXMLSAXHandler;
import org.apache.xml.serializer.SerializationHandler;
import org.apache.xml.utils.BoolStack;
import org.apache.xml.utils.DOMBuilder;
import org.apache.xml.utils.NodeVector;
import org.apache.xml.utils.ObjectPool;
import org.apache.xml.utils.ObjectStack;
import org.apache.xml.utils.QName;
import org.apache.xml.utils.SAXSourceLocator;
import org.apache.xml.utils.ThreadControllerWrapper;
import org.apache.xpath.Arg;
import org.apache.xpath.ExtensionsProvider;
import org.apache.xpath.VariableStack;
import org.apache.xpath.XPathContext;
import org.apache.xpath.functions.FuncExtFunction;
import org.apache.xpath.objects.XObject;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.ext.DeclHandler;
import org.xml.sax.ext.LexicalHandler;

/**
 * This class implements the
 * {@link javax.xml.transform.Transformer} interface, and is the core
 * representation of the transformation execution.</p>
 * @xsl.usage advanced
 */
public class TransformerImpl extends Transformer
        implements Runnable, DTMWSFilter, ExtensionsProvider, org.apache.xml.serializer.SerializerTrace
{

  // Synch object to gaurd against setting values from the TrAX interface 
  // or reentry while the transform is going on.

  /** NEEDSDOC Field m_reentryGuard          */
  private Boolean m_reentryGuard = new Boolean(true);

  /**
   * This is null unless we own the stream.
   */
  private java.io.FileOutputStream m_outputStream = null;

  /**
   * True if the parser events should be on the main thread,
   * false if not.  Experemental.  Can not be set right now.
   */
  private boolean m_parserEventsOnMain = true;

  /** The thread that the transformer is running on. */
  private Thread m_transformThread;

  /** The base URL of the source tree. */
  private String m_urlOfSource = null;

  /** The Result object at the start of the transform, if any. */
  private Result m_outputTarget = null;

  /**
   * The output format object set by the user.  May be null.
   */
  private OutputProperties m_outputFormat;


  /**
   * The content handler for the source input tree.
   */
  ContentHandler m_inputContentHandler;

  /**
   * The content handler for the result tree.
   */
  private ContentHandler m_outputContentHandler = null;

  //  /*
  //   * Use member variable to store param variables as they're
  //   * being created, use member variable so we don't
  //   * have to create a new vector every time.
  //   */
  //  private Vector m_newVars = new Vector();

  /** The JAXP Document Builder, mainly to create Result Tree Fragments. */
  DocumentBuilder m_docBuilder = null;

  /**
   * A pool of ResultTreeHandlers, for serialization of a subtree to text.
   *  Please note that each of these also holds onto a Text Serializer.  
   */
  private ObjectPool m_textResultHandlerObjectPool =
    new ObjectPool(ToTextStream.class);

  /**
   * Related to m_textResultHandlerObjectPool, this is a pool of
   * StringWriters, which are passed to the Text Serializers.
   * (I'm not sure if this is really needed any more.  -sb)      
   */
  private ObjectPool m_stringWriterObjectPool =
    new ObjectPool(StringWriter.class);

  /**
   * A static text format object, which can be used over and
   * over to create the text serializers.    
   */
  private OutputProperties m_textformat = new OutputProperties(Method.TEXT);

  // Commenteded out in response to problem reported by 
  // Nicola Brown <Nicola.Brown@jacobsrimell.com>
  //  /**
  //   * Flag to let us know if an exception should be reported inside the 
  //   * postExceptionFromThread method.  This is needed if the transform is 
  //   * being generated from SAX events, and thus there is no central place 
  //   * to report the exception from.  (An exception is usually picked up in 
  //   * the main thread from the transform thread in {@link #transform(Source source)} 
  //   * from {@link #getExceptionThrown()}. )
  //   */
  //  private boolean m_reportInPostExceptionFromThread = false;

  /**
   * A node vector used as a stack to track the current
   * ElemTemplateElement.  Needed for the
   * org.apache.xalan.transformer.TransformState interface,
   * so a tool can discover the calling template. Note the use of an array 
   * for this limits the recursion depth to 4K.
   */
  ObjectStack m_currentTemplateElements 
      = new ObjectStack(XPathContext.RECURSIONLIMIT);
  
  /** The top of the currentTemplateElements stack. */
  //int m_currentTemplateElementsTop = 0;

  /**
   * A node vector used as a stack to track the current
   * ElemTemplate that was matched.
   * Needed for the
   * org.apache.xalan.transformer.TransformState interface,
   * so a tool can discover the matched template
   */
  Stack m_currentMatchTemplates = new Stack();

  /**
   * A node vector used as a stack to track the current
   * node that was matched.
   * Needed for the
   * org.apache.xalan.transformer.TransformState interface,
   * so a tool can discover the matched
   * node. 
   */
  NodeVector m_currentMatchedNodes = new NodeVector();

  /**
   * The root of a linked set of stylesheets.
   */
  private StylesheetRoot m_stylesheetRoot = null;

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

  /**
   * The liason to the XML parser, so the XSL processor
   * can handle included files, and the like, and do the
   * initial parse of the XSL document.
   */
  private XPathContext m_xcontext;

  /**
   * Object to guard agains infinite recursion when
   * doing queries.
   */
  private StackGuard m_stackGuard;

  /**
   * Output handler to bottleneck SAX events.
   */
  private SerializationHandler m_serializationHandler;  

  /** The key manager, which manages xsl:keys. */
  private KeyManager m_keyManager = new KeyManager();

  /**
   * Stack for the purposes of flagging infinite recursion with
   * attribute sets.
   */
  Stack m_attrSetStack = null;

  /**
   * The table of counters for xsl:number support.
   * @see ElemNumber
   */
  CountersTable m_countersTable = null;

  /**
   * Is > 0 when we're processing a for-each.
   */
  BoolStack m_currentTemplateRuleIsNull = new BoolStack();

  /**
   * Keeps track of the result delivered by any EXSLT <code>func:result</code>
   * instruction that has been executed for the currently active EXSLT
   * <code>func:function</code>
   */
  ObjectStack m_currentFuncResult = new ObjectStack();
  
  /**
   * The message manager, which manages error messages, warning
   * messages, and other types of message events.   
   */
  private MsgMgr m_msgMgr;

  /**
   * The flag for the setting of the optimize feature;
   * This flag should have the same value as the FEATURE_OPTIMIZE feature
   * which is set by the TransformerFactory.setAttribut() method before a
   * Transformer is created
   */    
  private boolean m_optimizer = true;

  /**
   * The flag for the setting of the incremental feature;
   * This flag should have the same value as the FEATURE_INCREMENTAL feature
   * which is set by the TransformerFactory.setAttribut() method before a
   * Transformer is created
   */    
  private boolean m_incremental = false;

  /**
   * The flag for the setting of the source_location feature;
   * This flag should have the same value as the FEATURE_SOURCE_LOCATION feature
   * which is set by the TransformerFactory.setAttribut() method before a
   * Transformer is created
   */  
  private boolean m_source_location = false;
    
  /**
   * This is a compile-time flag to turn off calling
   * of trace listeners. Set this to false for optimization purposes.
   */
  private boolean m_debug = false;

  /**
   * The SAX error handler, where errors and warnings are sent.
   */
  private ErrorListener m_errorHandler =
    new org.apache.xml.utils.DefaultErrorHandler(false);

  /**
   * The trace manager.
   */
  private TraceManager m_traceManager = new TraceManager(this);

  /**
   * If the transform thread throws an exception, the exception needs to
   * be stashed away so that the main thread can pass it on to the
   * client. 
   */
  private Exception m_exceptionThrown = null;

  /**
   * The InputSource for the source tree, which is needed if the
   * parse thread is not the main thread, in order for the parse
   * thread's run method to get to the input source.
   * (Delete this if reversing threads is outlawed. -sb)    
   */
  private Source m_xmlSource;

  /**
   * This is needed for support of setSourceTreeDocForThread(Node doc),
   * which must be called in order for the transform thread's run
   * method to obtain the root of the source tree to be transformed.     
   */
  private int m_doc;

  /**
   * If the the transform is on the secondary thread, we
   * need to know when it is done, so we can return.
   */
  private boolean m_isTransformDone = false;

  /** Flag to to tell if the tranformer needs to be reset. */
  private boolean m_hasBeenReset = false;

  /** NEEDSDOC Field m_shouldReset          */
  private boolean m_shouldReset = true;

  /**
   * NEEDSDOC Method setShouldReset 
   *
   *
   * NEEDSDOC @param shouldReset
   */
  public void setShouldReset(boolean shouldReset)
  {
    m_shouldReset = shouldReset;
  }

  /**
   * A stack of current template modes.
   */
  private Stack m_modes = new Stack();

  //==========================================================
  // SECTION: Constructor
  //==========================================================

  /**
   * Construct a TransformerImpl.
   *
   * @param stylesheet The root of the stylesheet tree.
   */
  public TransformerImpl(StylesheetRoot stylesheet)
   // throws javax.xml.transform.TransformerException    
  {
    m_optimizer = stylesheet.getOptimizer();
    m_incremental = stylesheet.getIncremental();
    m_source_location = stylesheet.getSource_location();  	
    setStylesheet(stylesheet);
    XPathContext xPath = new XPathContext(this);
    xPath.setIncremental(m_incremental);
    xPath.getDTMManager().setIncremental(m_incremental);
    xPath.setSource_location(m_source_location);
    xPath.getDTMManager().setSource_location(m_source_location);
    
    if (stylesheet.isSecureProcessing())
      xPath.setSecureProcessing(true);
    
    setXPathContext(xPath);
    getXPathContext().setNamespaceContext(stylesheet);
    m_stackGuard = new StackGuard(this);    
  }
  
  // ================ ExtensionsTable ===================

  /**
   * The table of ExtensionHandlers.
   */
  private ExtensionsTable m_extensionsTable = null;

  /**
   * Get the extensions table object. 
   *
   * @return The extensions table.
   */
  public ExtensionsTable getExtensionsTable()
  {
    return m_extensionsTable;
  }

  /**
   * If the stylesheet contains extensions, set the extensions table object.
   *
   *
   * @param sroot The stylesheet.
   * @throws javax.xml.transform.TransformerException
   */
  void setExtensionsTable(StylesheetRoot sroot)
       throws javax.xml.transform.TransformerException
  {
    try
    {
      if (sroot.getExtensions() != null)
        //only load extensions if secureProcessing is disabled
        if(!sroot.isSecureProcessing())
            m_extensionsTable = new ExtensionsTable(sroot);
    }
    catch (javax.xml.transform.TransformerException te)
    {te.printStackTrace();}
  }
  
  //== Implementation of the XPath ExtensionsProvider interface.
  
  public boolean functionAvailable(String ns, String funcName)
          throws javax.xml.transform.TransformerException
  {
    return getExtensionsTable().functionAvailable(ns, funcName);
  }
  
  public boolean elementAvailable(String ns, String elemName)
          throws javax.xml.transform.TransformerException
  {
    return getExtensionsTable().elementAvailable(ns, elemName);   
  }
   
  public Object extFunction(String ns, String funcName, 
                            Vector argVec, Object methodKey)
            throws javax.xml.transform.TransformerException
  {//System.out.println("TransImpl.extFunction() " + ns + " " + funcName +" " + getExtensionsTable());
    return getExtensionsTable().extFunction(ns, funcName, 
                                        argVec, methodKey,
                                        getXPathContext().getExpressionContext());   
  }

  public Object extFunction(FuncExtFunction extFunction, Vector argVec)
            throws javax.xml.transform.TransformerException
  {
    return getExtensionsTable().extFunction(extFunction, argVec,
                                            getXPathContext().getExpressionContext());   
  }
  
  //=========================

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

    if (!m_hasBeenReset && m_shouldReset)
    {
      m_hasBeenReset = true;

      if (this.m_outputStream != null)
      {
        try
        {
          m_outputStream.close();
        }
        catch (java.io.IOException ioe){}
      }

      m_outputStream = null;

      // I need to look more carefully at which of these really
      // needs to be reset.
      m_countersTable = null;

      m_xcontext.reset();
      
      m_xcontext.getVarStack().reset();
      resetUserParameters();
      

      m_currentTemplateElements.removeAllElements();     
      m_currentMatchTemplates.removeAllElements();
      m_currentMatchedNodes.removeAllElements();
      
      m_serializationHandler = null;      
      m_outputTarget = null;
      m_keyManager = new KeyManager();
      m_attrSetStack = null;
      m_countersTable = null;
      m_currentTemplateRuleIsNull = new BoolStack();
      m_xmlSource = null;
      m_doc = DTM.NULL;
      m_isTransformDone = false;
      m_transformThread = null;

      // m_inputContentHandler = null;
      // For now, reset the document cache each time.
      m_xcontext.getSourceTreeManager().reset();
    }

    //    m_reportInPostExceptionFromThread = false;
  }

  /**
   * <code>getProperty</code> returns the current setting of the
   * property described by the <code>property</code> argument.
   *
   * %REVIEW% Obsolete now that source_location is handled in the TransformerFactory?
   *
   * @param property a <code>String</code> value
   * @return a <code>boolean</code> value
   */
  public boolean getProperty(String property)
  {
    return false;
  }

  /**
   * Set a runtime property for this <code>TransformerImpl</code>.
   *
   * %REVIEW% Obsolete now that source_location is handled in the TransformerFactory?
   *
   * @param property a <code>String</code> value
   * @param value an <code>Object</code> value
   */
  public void setProperty(String property, Object value)
  {
  }

  // ========= Transformer Interface Implementation ==========

  /**
   * Get true if the parser events should be on the main thread,
   * false if not.  Experimental.  Can not be set right now.
   *
   * @return true if the parser events should be on the main thread,
   * false if not.
   * @xsl.usage experimental
   */
  public boolean isParserEventsOnMain()
  {
    return m_parserEventsOnMain;
  }

  /**
   * Get the thread that the transform process is on.
   *
   * @return The thread that the transform process is on, or null.
   * @xsl.usage internal
   */
  public Thread getTransformThread()
  {
    return m_transformThread;
  }

  /**
   * Get the thread that the transform process is on.
   *
   * @param t The transform thread, may be null.
   * @xsl.usage internal
   */
  public void setTransformThread(Thread t)
  {
    m_transformThread = t;
  }

  /** NEEDSDOC Field m_hasTransformThreadErrorCatcher          */
  private boolean m_hasTransformThreadErrorCatcher = false;

  /**
   * Return true if the transform was initiated from the transform method,
   * otherwise it was probably done from a pure parse events.
   *
   * NEEDSDOC ($objectName$) @return
   */
  public boolean hasTransformThreadErrorCatcher()
  {
    return m_hasTransformThreadErrorCatcher;
  }
        
        /**
   * Process the source tree to SAX parse events.
   * @param source  The input for the source tree.
   *
   * @throws TransformerException
   */
  public void transform(Source source) throws TransformerException
  {
                transform(source, true); 
        }

  /**
   * Process the source tree to SAX parse events.
   * @param source  The input for the source tree.
   * @param shouldRelease  Flag indicating whether to release DTMManager.
   *
   * @throws TransformerException
   */
  public void transform(Source source, boolean shouldRelease) throws TransformerException
  {

    try
    {
        
      // Patch for bugzilla #13863.  If we don't reset the namespaceContext
      // then we will get a NullPointerException if transformer is reused 
      // (for stylesheets that use xsl:key).  Not sure if this should go 
      // here or in reset(). -is  
      if(getXPathContext().getNamespaceContext() == null){
         getXPathContext().setNamespaceContext(getStylesheet());
      }
      String base = source.getSystemId();
      
      // If no systemID of the source, use the base of the stylesheet.
      if(null == base)
      {
        base = m_stylesheetRoot.getBaseIdentifier();
      }

      // As a last resort, use the current user dir.
      if(null == base)
      {
        String currentDir = "";
        try {
          currentDir = System.getProperty("user.dir");
        }
        catch (SecurityException se) {}// user.dir not accessible from applet
              
        if (currentDir.startsWith(java.io.File.separator))
          base = "file://" + currentDir;
        else
          base = "file:///" + currentDir;
        
        base = base + java.io.File.separatorChar
               + source.getClass().getName();
      }
      setBaseURLOfSource(base);
      DTMManager mgr = m_xcontext.getDTMManager();
      /*
       * According to JAXP1.2, new SAXSource()/StreamSource()
       * should create an empty input tree, with a default root node. 
       * new DOMSource()creates an empty document using DocumentBuilder.
       * newDocument(); Use DocumentBuilder.newDocument() for all 3 situations,
       * since there is no clear spec. how to create an empty tree when
       * both SAXSource() and StreamSource() are used.
       */
      if ((source instanceof StreamSource && source.getSystemId()==null &&
         ((StreamSource)source).getInputStream()==null &&
         ((StreamSource)source).getReader()==null)||
         (source instanceof SAXSource &&
         ((SAXSource)source).getInputSource()==null &&
         ((SAXSource)source).getXMLReader()==null )||
         (source instanceof DOMSource && ((DOMSource)source).getNode()==null)){
        try {
          DocumentBuilderFactory builderF = 
                   DocumentBuilderFactory.newInstance();
          DocumentBuilder builder = builderF.newDocumentBuilder();
          String systemID = source.getSystemId();
          source = new DOMSource(builder.newDocument());

          // Copy system ID from original, empty Source to new Source
          if (systemID != null) {
            source.setSystemId(systemID);
          }
        } catch (ParserConfigurationException e) {
          fatalError(e);
        }           
      }
      DTM dtm = mgr.getDTM(source, false, this, true, true);
      dtm.setDocumentBaseURI(base);
      
      boolean hardDelete = true;  // %REVIEW% I have to think about this. -sb

      try
      {
      	// NOTE: This will work because this is _NOT_ a shared DTM, and thus has
      	// only a single Document node. If it could ever be an RTF or other
      	// shared DTM, look at dtm.getDocumentRoot(nodeHandle).
        this.transformNode(dtm.getDocument());
      }
      finally
      {
        if (shouldRelease)
          mgr.release(dtm, hardDelete);
      }

      // Kick off the parse.  When the ContentHandler gets 
      // the startDocument event, it will call transformNode( node ).
      // reader.parse( xmlSource );
      // This has to be done to catch exceptions thrown from 
      // the transform thread spawned by the STree handler.
      Exception e = getExceptionThrown();

      if (null != e)
      {
        if (e instanceof javax.xml.transform.TransformerException)
        {
          throw (javax.xml.transform.TransformerException) e;
        }
        else if (e instanceof org.apache.xml.utils.WrappedRuntimeException)
        {
          fatalError(
              ((org.apache.xml.utils.WrappedRuntimeException) e).getException());
        }
        else
        {
          throw new javax.xml.transform.TransformerException(e);
        }
      }
      else if (null != m_serializationHandler)
      {
        m_serializationHandler.endDocument();
      }
    }
    catch (org.apache.xml.utils.WrappedRuntimeException wre)
    {
      Throwable throwable = wre.getException();

      while (throwable
             instanceof org.apache.xml.utils.WrappedRuntimeException)
      {
        throwable =
          ((org.apache.xml.utils.WrappedRuntimeException) throwable).getException();
      }

      fatalError(throwable);
    }

    // Patch attributed to David Eisenberg <david@catcode.com>
    catch (org.xml.sax.SAXParseException spe)
    {
      fatalError(spe);
    }
    catch (org.xml.sax.SAXException se)
    {
      m_errorHandler.fatalError(new TransformerException(se));
    }
    finally
    {
      m_hasTransformThreadErrorCatcher = false;

      // This looks to be redundent to the one done in TransformNode.
      reset();
    }
  }
  
  private void fatalError(Throwable throwable) throws TransformerException
  {
    if (throwable instanceof org.xml.sax.SAXParseException)
      m_errorHandler.fatalError(new TransformerException(throwable.getMessage(),new SAXSourceLocator((org.xml.sax.SAXParseException)throwable)));
    else
      m_errorHandler.fatalError(new TransformerException(throwable));
    
  }

  /**
   * Get the base URL of the source.
   *
   * @return The base URL of the source tree, or null.
   */
  public String getBaseURLOfSource()
  {
    return m_urlOfSource;
  }

  /**
   * Get the base URL of the source.
   *
   *
   * NEEDSDOC @param base
   * @return The base URL of the source tree, or null.
   */
  public void setBaseURLOfSource(String base)
  {
    m_urlOfSource = base;
  }

  /**
   * Get the original output target.
   *
   * @return The Result object used to kick of the transform or null.
   */
  public Result getOutputTarget()
  {
    return m_outputTarget;
  }

  /**
   * Set the original output target.  This is useful when using a SAX transform and
   * supplying a ContentHandler or when the URI of the output target should
   * not be the same as the systemID of the original output target.
   *
   *
   * NEEDSDOC @param outputTarget
   */
  public void setOutputTarget(Result outputTarget)
  {
    m_outputTarget = outputTarget;
  }

  /**
   * Get an output property that is in effect for the
   * transformation.  The property specified may be a property
   * that was set with setOutputProperty, or it may be a
   * property specified in the stylesheet.
   *
   * NEEDSDOC @param qnameString
   *
   * @return The string value of the output property, or null
   * if no property was found.
   *
   * @throws IllegalArgumentException If the property is not supported.
   *
   * @see javax.xml.transform.OutputKeys
   */
  public String getOutputProperty(String qnameString)
          throws IllegalArgumentException
  {

    String value = null;
    OutputProperties props = getOutputFormat();

    value = props.getProperty(qnameString);

    if (null == value)
    {
      if (!OutputProperties.isLegalPropertyKey(qnameString))
        throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_OUTPUT_PROPERTY_NOT_RECOGNIZED, new Object[]{qnameString})); //"output property not recognized: "
                                           //+ qnameString);
    }

    return value;
  }

  /**
   * Get the value of a property, without using the default properties.  This
   * can be used to test if a property has been explicitly set by the stylesheet
   * or user.
   *
   * NEEDSDOC @param qnameString
   *
   * @return The value of the property, or null if not found.
   *
   * @throws IllegalArgumentException If the property is not supported,
   * and is not namespaced.
   */
  public String getOutputPropertyNoDefault(String qnameString)
          throws IllegalArgumentException
  {

    String value = null;
    OutputProperties props = getOutputFormat();

    value = (String) props.getProperties().get(qnameString);

    if (null == value)
    {
      if (!OutputProperties.isLegalPropertyKey(qnameString))
        throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_OUTPUT_PROPERTY_NOT_RECOGNIZED, new Object[]{qnameString})); //"output property not recognized: "
                                          // + qnameString);
    }

    return value;
  }

  /**
   * This method is used to set or override the value
   * of the effective xsl:output attribute values
   * specified in the stylesheet.
   * <p>
   * The recognized standard output properties are:
   * <ul>
   * <li>cdata-section-elements
   * <li>doctype-system
   * <li>doctype-public
   * <li>indent
   * <li>media-type
   * <li>method
   * <li>omit-xml-declaration
   * <li>standalone
   * <li>version
   * </ul>
   * <p>
   * For example:
   * <pre>
   *   tran.setOutputProperty("standalone", "yes");
   * </pre>
   * <p>
   * In the case of the cdata-section-elements property,
   * the value should be a whitespace separated list of
   * element names.  The element name is the local name
   * of the element, if it is in no namespace, or, the URI
   * in braces followed immediately by the local name
   * if the element is in that namespace. For example: 
   * <pre>
   * tran.setOutputProperty(
   *   "cdata-section-elements", 
   *   "elem1 {http://example.uri}elem2 elem3");
   * </pre>
   * <p>
   * The recognized Xalan extension elements are: 
   * <ul>
   * <li>content-handler
   * <li>entities
   * <li>indent-amount
   * <li>line-separator
   * <li>omit-meta-tag
   * <li>use-url-escaping
   * </ul>
   * <p>
   * These must be in the extension namespace of
   * "http://xml.apache.org/xalan".  This is accomplished
   * by putting the namespace URI in braces before the 
   * property name, for example:
   * <pre>
   *   tran.setOutputProperty(
   *     "{http://xml.apache.org/xalan}line-separator" ,
   *     "\n");
   * </pre> 
   *
   * @param name The property name.
   * @param value The requested value for the property.
   * @throws IllegalArgumentException if the property name is not legal.
   */
  public void setOutputProperty(String name, String value)
          throws IllegalArgumentException
  {

    synchronized (m_reentryGuard)
    {

      // Get the output format that was set by the user, otherwise get the 
      // output format from the stylesheet.
      if (null == m_outputFormat)
      {
        m_outputFormat =
          (OutputProperties) getStylesheet().getOutputComposed().clone();
      }

      if (!OutputProperties.isLegalPropertyKey(name))
        throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_OUTPUT_PROPERTY_NOT_RECOGNIZED, new Object[]{name})); //"output property not recognized: "
                                           //+ name);

      m_outputFormat.setProperty(name, value);
    }
  }

  /**
   * Set the output properties for the transformation.  These
   * properties will override properties set in the templates
   * with xsl:output.
   *
   * <p>If argument to this function is null, any properties
   * previously set will be removed.</p>
   *
   * @param oformat A set of output properties that will be
   * used to override any of the same properties in effect
   * for the transformation.
   *
   * @see javax.xml.transform.OutputKeys
   * @see java.util.Properties
   *
   * @throws IllegalArgumentException if any of the argument keys are not
   * recognized and are not namespace qualified.   
   */
  public void setOutputProperties(Properties oformat)
  		throws IllegalArgumentException
  {

    synchronized (m_reentryGuard)
    {
      if (null != oformat)
      {

        // See if an *explicit* method was set.
        String method = (String) oformat.get(OutputKeys.METHOD);

        if (null != method)
          m_outputFormat = new OutputProperties(method);
        else if(m_outputFormat==null)
          m_outputFormat = new OutputProperties();

        m_outputFormat.copyFrom(oformat);
        // copyFrom does not set properties that have been already set, so 
        // this must be called after, which is a bit in the reverse from 
        // what one might think.
        m_outputFormat.copyFrom(m_stylesheetRoot.getOutputProperties());
      }
      else {
        // if oformat is null JAXP says that any props previously set are removed
        // and we are to revert back to those in the templates object (i.e. Stylesheet).
        m_outputFormat = null;
      }
    }
  }

  /**
   * Get a copy of the output properties for the transformation.  These
   * properties will override properties set in the templates
   * with xsl:output.
   *
   * <p>Note that mutation of the Properties object returned will not
   * effect the properties that the transformation contains.</p>
   *
   * @return  A copy of the set of output properties in effect
   * for the next transformation.
   *
   * NEEDSDOC ($objectName$) @return
   */
  public Properties getOutputProperties()
  {
    return (Properties) getOutputFormat().getProperties().clone();
  }

    /**
     * Create a result ContentHandler from a Result object, based
     * on the current OutputProperties.
     *
     * @param outputTarget Where the transform result should go,
     * should not be null.
     *
     * @return A valid ContentHandler that will create the
     * result tree when it is fed SAX events.
     *
     * @throws TransformerException
     */
    public SerializationHandler createSerializationHandler(Result outputTarget)
            throws TransformerException
    {
       SerializationHandler xoh =
        createSerializationHandler(outputTarget, getOutputFormat());
       return xoh;
    }

    /**
     * Create a ContentHandler from a Result object and an OutputProperties.
     *
     * @param outputTarget Where the transform result should go,
     * should not be null.
     * @param format The OutputProperties object that will contain
     * instructions on how to serialize the output.
     *
     * @return A valid ContentHandler that will create the
     * result tree when it is fed SAX events.
     *
     * @throws TransformerException
     */
    public SerializationHandler createSerializationHandler(
            Result outputTarget, OutputProperties format)
              throws TransformerException
    {

      SerializationHandler xoh;

      // If the Result object contains a Node, then create
      // a ContentHandler that will add nodes to the input node.
      org.w3c.dom.Node outputNode = null;

      if (outputTarget instanceof DOMResult)
      {
        outputNode = ((DOMResult) outputTarget).getNode();
        org.w3c.dom.Node nextSibling = ((DOMResult)outputTarget).getNextSibling();

        org.w3c.dom.Document doc;
        short type;

        if (null != outputNode)
        {
          type = outputNode.getNodeType();
          doc = (org.w3c.dom.Node.DOCUMENT_NODE == type)
                ? (org.w3c.dom.Document) outputNode
                : outputNode.getOwnerDocument();
        }
        else
        {
          boolean isSecureProcessing = m_stylesheetRoot.isSecureProcessing();
          doc = org.apache.xml.utils.DOMHelper.createDocument(isSecureProcessing);
          outputNode = doc;
          type = outputNode.getNodeType();

          ((DOMResult) outputTarget).setNode(outputNode);
        }

        DOMBuilder handler =
          (org.w3c.dom.Node.DOCUMENT_FRAGMENT_NODE == type)
          ? new DOMBuilder(doc, (org.w3c.dom.DocumentFragment) outputNode)
          : new DOMBuilder(doc, outputNode);
        
        if (nextSibling != null)
          handler.setNextSibling(nextSibling);
        
          String encoding = format.getProperty(OutputKeys.ENCODING);          
          xoh = new ToXMLSAXHandler(handler, (LexicalHandler)handler, encoding);
      }
      else if (outputTarget instanceof SAXResult)
      {
        ContentHandler handler = ((SAXResult) outputTarget).getHandler();
        
        if (null == handler)
           throw new IllegalArgumentException(
             "handler can not be null for a SAXResult"); 
             
        LexicalHandler lexHandler;
        if (handler instanceof LexicalHandler)     
            lexHandler = (LexicalHandler)  handler;
        else
            lexHandler = null;
            
        String encoding = format.getProperty(OutputKeys.ENCODING); 
        String method = format.getProperty(OutputKeys.METHOD);

        ToXMLSAXHandler toXMLSAXHandler = new ToXMLSAXHandler(handler, lexHandler, encoding);
        toXMLSAXHandler.setShouldOutputNSAttr(false);
        xoh = toXMLSAXHandler;   


        String publicID = format.getProperty(OutputKeys.DOCTYPE_PUBLIC); 
        String systemID = format.getProperty(OutputKeys.DOCTYPE_SYSTEM); 
        if (systemID != null)
            xoh.setDoctypeSystem(systemID);
        if (publicID != null)
            xoh.setDoctypePublic(publicID);
        
        if (handler instanceof TransformerClient) {
            XalanTransformState state = new XalanTransformState();
            ((TransformerClient)handler).setTransformState(state);
            ((ToSAXHandler)xoh).setTransformState(state);
        }

 
      }

      // Otherwise, create a ContentHandler that will serialize the
      // result tree to either a stream or a writer.
      else if (outputTarget instanceof StreamResult)
      {
        StreamResult sresult = (StreamResult) outputTarget;

        try
        {
          SerializationHandler serializer =
            (SerializationHandler) SerializerFactory.getSerializer(format.getProperties());

          if (null != sresult.getWriter())
            serializer.setWriter(sresult.getWriter());
          else if (null != sresult.getOutputStream())
            serializer.setOutputStream(sresult.getOutputStream());
          else if (null != sresult.getSystemId())
          {
            String fileURL = sresult.getSystemId();

            if (fileURL.startsWith("file:///"))
            {
              if (fileURL.substring(8).indexOf(":") >0)
                fileURL = fileURL.substring(8);
              else
                fileURL = fileURL.substring(7);
            }
            else if (fileURL.startsWith("file:/"))
            {
                if (fileURL.substring(6).indexOf(":") >0)
                    fileURL = fileURL.substring(6);
                  else
                    fileURL = fileURL.substring(5);            	
            }

            m_outputStream = new java.io.FileOutputStream(fileURL);

            serializer.setOutputStream(m_outputStream);
            
            xoh = serializer;
          }
          else
            throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_OUTPUT_SPECIFIED, null)); //"No output specified!");

          // handler = serializer.asContentHandler();

        //  this.setSerializer(serializer);

          xoh = serializer;  
        }
//        catch (UnsupportedEncodingException uee)
//        {
//          throw new TransformerException(uee);
//        }
        catch (IOException ioe)
        {
          throw new TransformerException(ioe);
        }
      }
      else
      {
        throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_CANNOT_TRANSFORM_TO_RESULT_TYPE, new Object[]{outputTarget.getClass().getName()})); //"Can't transform to a Result of type "
                                       //+ outputTarget.getClass().getName()
                                       //+ "!");
      }
      
      // before we forget, lets make the created handler hold a reference
      // to the current TransformImpl object
      xoh.setTransformer(this);

      SourceLocator srcLocator = getStylesheet();
      xoh.setSourceLocator(srcLocator);
      
      
      return xoh;

   
    }
        
        /**
   * Process the source tree to the output result.
   * @param xmlSource  The input for the source tree.
   * @param outputTarget The output source target.
   *
   * @throws TransformerException
   */
  public void transform(Source xmlSource, Result outputTarget)
          throws TransformerException
  {
                transform(xmlSource, outputTarget, true);
        }

  /**
   * Process the source tree to the output result.
   * @param xmlSource  The input for the source tree.
   * @param outputTarget The output source target.
   * @param shouldRelease  Flag indicating whether to release DTMManager. 
   *
   * @throws TransformerException
   */
  public void transform(Source xmlSource, Result outputTarget, boolean shouldRelease)
          throws TransformerException
  {

    synchronized (m_reentryGuard)
    {
      SerializationHandler xoh = createSerializationHandler(outputTarget);
      this.setSerializationHandler(xoh);        

      m_outputTarget = outputTarget;

      transform(xmlSource, shouldRelease);
    }
  }

  /**
   * Process the source node to the output result, if the
   * processor supports the "http://xml.org/trax/features/dom/input"
   * feature.
   * %REVIEW% Do we need a Node version of this?
   * @param node  The input source node, which can be any valid DTM node.
   * @param outputTarget The output source target.
   *
   * @throws TransformerException
   */
  public void transformNode(int node, Result outputTarget)
          throws TransformerException
  {
    

    SerializationHandler xoh = createSerializationHandler(outputTarget);
    this.setSerializationHandler(xoh);

    m_outputTarget = outputTarget;

    transformNode(node);
  }

  /**
   * Process the source node to the output result, if the
   * processor supports the "http://xml.org/trax/features/dom/input"
   * feature.
   * %REVIEW% Do we need a Node version of this?
   * @param node  The input source node, which can be any valid DTM node.
   *
   * @throws TransformerException
   */
  public void transformNode(int node) throws TransformerException
  {
    //dml
    setExtensionsTable(getStylesheet());
    // Make sure we're not writing to the same output content handler.
    synchronized (m_serializationHandler)
    {
      m_hasBeenReset = false;
      
      XPathContext xctxt = getXPathContext();
      DTM dtm = xctxt.getDTM(node);

      try
      {
        pushGlobalVars(node);

        // ==========
        // Give the top-level templates a chance to pass information into 
        // the context (this is mainly for setting up tables for extensions).
        StylesheetRoot stylesheet = this.getStylesheet();
        int n = stylesheet.getGlobalImportCount();

        for (int i = 0; i < n; i++)
        {
          StylesheetComposed imported = stylesheet.getGlobalImport(i);
          int includedCount = imported.getIncludeCountComposed();

          for (int j = -1; j < includedCount; j++)
          {
            Stylesheet included = imported.getIncludeComposed(j);

            included.runtimeInit(this);

            for (ElemTemplateElement child = included.getFirstChildElem();
                    child != null; child = child.getNextSiblingElem())
            {
              child.runtimeInit(this);
            }
          }
        }
        // ===========        
        // System.out.println("Calling applyTemplateToNode - "+Thread.currentThread().getName());
        DTMIterator dtmIter = new org.apache.xpath.axes.SelfIteratorNoPredicate();
        dtmIter.setRoot(node, xctxt);
        xctxt.pushContextNodeList(dtmIter);
        try
        {
          this.applyTemplateToNode(null, null, node);
        }
        finally
        {
          xctxt.popContextNodeList();
        }
        // m_stylesheetRoot.getStartRule().execute(this);

        // System.out.println("Done with applyTemplateToNode - "+Thread.currentThread().getName());
        if (null != m_serializationHandler)
        {
          m_serializationHandler.endDocument();
        }
      }
      catch (Exception se)
      {

        // System.out.println(Thread.currentThread().getName()+" threw an exception! "
        //                   +se.getMessage());
        // If an exception was thrown, we need to make sure that any waiting 
        // handlers can terminate, which I guess is best done by sending 
        // an endDocument.
        
        // SAXSourceLocator
        while(se instanceof org.apache.xml.utils.WrappedRuntimeException)
        {
          Exception e = ((org.apache.xml.utils.WrappedRuntimeException)se).getException();
          if(null != e)
            se = e;
        }
        
        if (null != m_serializationHandler)
        {
          try
          {
            if(se instanceof org.xml.sax.SAXParseException)
              m_serializationHandler.fatalError((org.xml.sax.SAXParseException)se);
            else if(se instanceof TransformerException)
            {
              TransformerException te = ((TransformerException)se);
              SAXSourceLocator sl = new SAXSourceLocator( te.getLocator() );
              m_serializationHandler.fatalError(new org.xml.sax.SAXParseException(te.getMessage(), sl, te)); 
            }
            else
            {
              m_serializationHandler.fatalError(new org.xml.sax.SAXParseException(se.getMessage(), new SAXSourceLocator(), se)); 
            }             
          }
          catch (Exception e){}
        }        
        
        if(se instanceof TransformerException)
        {
          m_errorHandler.fatalError((TransformerException)se);
        }
        else if(se instanceof org.xml.sax.SAXParseException)
        {
          m_errorHandler.fatalError(new TransformerException(se.getMessage(), 
                      new SAXSourceLocator((org.xml.sax.SAXParseException)se), 
                      se));
        }
        else
        {
          m_errorHandler.fatalError(new TransformerException(se));
        }
        
      }
      finally
      {
        this.reset();
      }
    }
  }

  /**
   * Get a SAX2 ContentHandler for the input.
   *
   * @return A valid ContentHandler, which should never be null, as
   * long as getFeature("http://xml.org/trax/features/sax/input")
   * returns true.
   */
  public ContentHandler getInputContentHandler()
  {
    return getInputContentHandler(false);
  }

  /**
   * Get a SAX2 ContentHandler for the input.
   *
   * @param doDocFrag true if a DocumentFragment should be created as
   * the root, rather than a Document.
   *
   * @return A valid ContentHandler, which should never be null, as
   * long as getFeature("http://xml.org/trax/features/sax/input")
   * returns true.
   */
  public ContentHandler getInputContentHandler(boolean doDocFrag)
  {

    if (null == m_inputContentHandler)
    {

      //      if(null == m_urlOfSource && null != m_stylesheetRoot)
      //        m_urlOfSource = m_stylesheetRoot.getBaseIdentifier();
      m_inputContentHandler = new TransformerHandlerImpl(this, doDocFrag,
              m_urlOfSource);
    }

    return m_inputContentHandler;
  }

  /**
   * Get a SAX2 DeclHandler for the input.
   * @return A valid DeclHandler, which should never be null, as
   * long as getFeature("http://xml.org/trax/features/sax/input")
   * returns true.
   */
  public DeclHandler getInputDeclHandler()
  {

    if (m_inputContentHandler instanceof DeclHandler)
      return (DeclHandler) m_inputContentHandler;
    else
      return null;
  }

  /**
   * Get a SAX2 LexicalHandler for the input.
   * @return A valid LexicalHandler, which should never be null, as
   * long as getFeature("http://xml.org/trax/features/sax/input")
   * returns true.
   */
  public LexicalHandler getInputLexicalHandler()
  {

    if (m_inputContentHandler instanceof LexicalHandler)
      return (LexicalHandler) m_inputContentHandler;
    else
      return null;
  }

  /**
   * Set the output properties for the transformation.  These
   * properties will override properties set in the templates
   * with xsl:output.
   *
   * @param oformat A valid OutputProperties object (which will
   * not be mutated), or null.
   */
  public void setOutputFormat(OutputProperties oformat)
  {
    m_outputFormat = oformat;
  }

  /**
   * Get the output properties used for the transformation.
   *
   * @return the output format that was set by the user,
   * otherwise the output format from the stylesheet.
   */
  public OutputProperties getOutputFormat()
  {

    // Get the output format that was set by the user, otherwise get the 
    // output format from the stylesheet.
    OutputProperties format = (null == m_outputFormat)
                              ? getStylesheet().getOutputComposed()
                              : m_outputFormat;

    return format;
  }

  /**
   * Set a parameter for the templates.
   * 
   * @param name The name of the parameter.
   * @param namespace The namespace of the parameter.
   * @param value The value object.  This can be any valid Java object
   * -- it's up to the processor to provide the proper
   * coersion to the object, or simply pass it on for use
   * in extensions.
   */
  public void setParameter(String name, String namespace, Object value)
  {

    VariableStack varstack = getXPathContext().getVarStack();
    QName qname = new QName(namespace, name);
    XObject xobject = XObject.create(value, getXPathContext());
    
    StylesheetRoot sroot = m_stylesheetRoot;
    Vector vars = sroot.getVariablesAndParamsComposed();
    int i = vars.size();
    while (--i >= 0)
    {
      ElemVariable variable = (ElemVariable)vars.elementAt(i);
      if(variable.getXSLToken() == Constants.ELEMNAME_PARAMVARIABLE && 
         variable.getName().equals(qname))
      {
          varstack.setGlobalVariable(i, xobject);
      }
    }
  }

  /** NEEDSDOC Field m_userParams          */
  Vector m_userParams;

  /**
   * Set a parameter for the transformation.
   *
   * @param name The name of the parameter,
   *             which may have a namespace URI.
   * @param value The value object.  This can be any valid Java object
   * -- it's up to the processor to provide the proper
   * coersion to the object, or simply pass it on for use
   * in extensions.
   */
  public void setParameter(String name, Object value)
  {
    
    if (value == null) {
      throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_INVALID_SET_PARAM_VALUE, new Object[]{name}));
    }    

    StringTokenizer tokenizer = new StringTokenizer(name, "{}", false);

    try
    {

      // The first string might be the namespace, or it might be 
      // the local name, if the namespace is null.
      String s1 = tokenizer.nextToken();
      String s2 = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null;

      if (null == m_userParams)
        m_userParams = new Vector();

      if (null == s2)
      {
        replaceOrPushUserParam(new QName(s1), XObject.create(value, getXPathContext()));
        setParameter(s1, null, value);
      }
      else
      {
        replaceOrPushUserParam(new QName(s1, s2), XObject.create(value, getXPathContext()));
        setParameter(s2, s1, value);
      }
    }
    catch (java.util.NoSuchElementException nsee)
    {

      // Should throw some sort of an error.
    }
  }

  /**
   * NEEDSDOC Method replaceOrPushUserParam 
   *
   *
   * NEEDSDOC @param qname
   * NEEDSDOC @param xval
   */
  private void replaceOrPushUserParam(QName qname, XObject xval)
  {

    int n = m_userParams.size();

    for (int i = n - 1; i >= 0; i--)
    {
      Arg arg = (Arg) m_userParams.elementAt(i);

      if (arg.getQName().equals(qname))
      {
        m_userParams.setElementAt(new Arg(qname, xval, true), i);

        return;
      }
    }

    m_userParams.addElement(new Arg(qname, xval, true));
  }

  /**
   * Get a parameter that was explicitly set with setParameter
   * or setParameters.
   *
   *
   * NEEDSDOC @param name
   * @return A parameter that has been set with setParameter
   * or setParameters,
   * *not* all the xsl:params on the stylesheet (which require
   * a transformation Source to be evaluated).
   */
  public Object getParameter(String name)
  {

    try
    {

      // VariableStack varstack = getXPathContext().getVarStack();
      // The first string might be the namespace, or it might be 
      // the local name, if the namespace is null.
      QName qname = QName.getQNameFromString(name);

      if (null == m_userParams)
        return null;

      int n = m_userParams.size();

      for (int i = n - 1; i >= 0; i--)
      {
        Arg arg = (Arg) m_userParams.elementAt(i);

        if (arg.getQName().equals(qname))
        {
          return arg.getVal().object();
        }
      }

      return null;
    }
    catch (java.util.NoSuchElementException nsee)
    {

      // Should throw some sort of an error.
      return null;
    }
  }
  
  /**
   * Reset parameters that the user specified for the transformation.
   * Called during transformer.reset() after we have cleared the 
   * variable stack. We need to make sure that user params are
   * reset so that the transformer object can be reused. 
   */
  private void resetUserParameters()
  {

    try
    {
      
      if (null == m_userParams)
        return;

      int n = m_userParams.size();
      for (int i = n - 1; i >= 0; i--)
      {
        Arg arg = (Arg) m_userParams.elementAt(i);
        QName name = arg.getQName();
        // The first string might be the namespace, or it might be 
        // the local name, if the namespace is null.
        String s1 = name.getNamespace();
        String s2 = name.getLocalPart();

        setParameter(s2, s1, arg.getVal().object());
        
      }
      
    }
    catch (java.util.NoSuchElementException nsee)
    {
      // Should throw some sort of an error.
      
    }
  }

  /**
   * Set a bag of parameters for the transformation. Note that
   * these will not be additive, they will replace the existing
   * set of parameters.
   *
   * NEEDSDOC @param params
   */
  public void setParameters(Properties params)
  {

    clearParameters();

    Enumeration names = params.propertyNames();

    while (names.hasMoreElements())
    {
      String name = params.getProperty((String) names.nextElement());
      StringTokenizer tokenizer = new StringTokenizer(name, "{}", false);

      try
      {

        // The first string might be the namespace, or it might be 
        // the local name, if the namespace is null.
        String s1 = tokenizer.nextToken();
        String s2 = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null;

        if (null == s2)
          setParameter(s1, null, params.getProperty(name));
        else
          setParameter(s2, s1, params.getProperty(name));
      }
      catch (java.util.NoSuchElementException nsee)
      {

        // Should throw some sort of an error.
      }
    }
  }

  /**
   * Reset the parameters to a null list.
   */
  public void clearParameters()
  {

    synchronized (m_reentryGuard)
    {
      VariableStack varstack = new VariableStack();

      m_xcontext.setVarStack(varstack);

      m_userParams = null;
    }
  }


  /**
   * Internal -- push the global variables from the Stylesheet onto
   * the context's runtime variable stack.
   * <p>If we encounter a variable
   * that is already defined in the variable stack, we ignore it.  This
   * is because the second variable definition will be at a lower import
   * precedence.  Presumably, global"variables at the same import precedence
   * with the same name will have been caught during the recompose process.
   * <p>However, if we encounter a parameter that is already defined in the
   * variable stack, we need to see if this is a parameter whose value was
   * supplied by a setParameter call.  If so, we need to "receive" the one
   * already in the stack, ignoring this one.  If it is just an earlier
   * xsl:param or xsl:variable definition, we ignore it using the same
   * reasoning as explained above for the variable.
   *
   * @param contextNode The root of the source tree, can't be null.
   *
   * @throws TransformerException
   */
  protected void pushGlobalVars(int contextNode) throws TransformerException
  {

    XPathContext xctxt = m_xcontext;
    VariableStack vs = xctxt.getVarStack();
    StylesheetRoot sr = getStylesheet();
    Vector vars = sr.getVariablesAndParamsComposed();
    
    int i = vars.size();
    vs.link(i);

    while (--i >= 0)
    {
      ElemVariable v = (ElemVariable) vars.elementAt(i);

      // XObject xobj = v.getValue(this, contextNode);
      XObject xobj = new XUnresolvedVariable(v, contextNode, this,
                                     vs.getStackFrame(), 0, true);
      
      if(null == vs.elementAt(i))                               
        vs.setGlobalVariable(i, xobj);
    }

  }

  /**
   * Set an object that will be used to resolve URIs used in
   * document(), etc.
   * @param resolver An object that implements the URIResolver interface,
   * or null.
   */
  public void setURIResolver(URIResolver resolver)
  {

    synchronized (m_reentryGuard)
    {
      m_xcontext.getSourceTreeManager().setURIResolver(resolver);
    }
  }

  /**
   * Get an object that will be used to resolve URIs used in
   * document(), etc.
   *
   * @return An object that implements the URIResolver interface,
   * or null.
   */
  public URIResolver getURIResolver()
  {
    return m_xcontext.getSourceTreeManager().getURIResolver();
  }

  // ======== End Transformer Implementation ========  

  /**
   * Set the content event handler.
   *
   * NEEDSDOC @param handler
   * @throws java.lang.NullPointerException If the handler
   *            is null.
   * @see org.xml.sax.XMLReader#setContentHandler
   */
  public void setContentHandler(ContentHandler handler)
  {

    if (handler == null)
    {
      throw new NullPointerException(XSLMessages.createMessage(XSLTErrorResources.ER_NULL_CONTENT_HANDLER, null)); //"Null content handler");
    }
    else
    {
      m_outputContentHandler = handler;

      if (null == m_serializationHandler)
      {
        ToXMLSAXHandler h = new ToXMLSAXHandler();
        h.setContentHandler(handler);
        h.setTransformer(this);
        
        m_serializationHandler = h;
      }
      else
        m_serializationHandler.setContentHandler(handler);
    }
  }

  /**
   * Get the content event handler.
   *
   * @return The current content handler, or null if none was set.
   * @see org.xml.sax.XMLReader#getContentHandler
   */
  public ContentHandler getContentHandler()
  {
    return m_outputContentHandler;
  }

  /**
   * Given a stylesheet element, create a result tree fragment from it's
   * contents. The fragment will be built within the shared RTF DTM system
   * used as a variable stack.
   * @param templateParent The template element that holds the fragment.
   * @return the NodeHandle for the root node of the resulting RTF.
   *
   * @throws TransformerException
   * @xsl.usage advanced
   */
  public int transformToRTF(ElemTemplateElement templateParent)
          throws TransformerException
  {
    // Retrieve a DTM to contain the RTF. At this writing, this may be a
    // multi-document DTM (SAX2RTFDTM).
    DTM dtmFrag = m_xcontext.getRTFDTM();
    return transformToRTF(templateParent,dtmFrag);
  }
  
  /**
   * Given a stylesheet element, create a result tree fragment from it's
   * contents. The fragment will also use the shared DTM system, but will
   * obtain its space from the global variable pool rather than the dynamic
   * variable stack. This allows late binding of XUnresolvedVariables without
   * the risk that their content will be discarded when the variable stack
   * is popped.
   * 
   * @param templateParent The template element that holds the fragment.
   * @return the NodeHandle for the root node of the resulting RTF.
   *
   * @throws TransformerException
   * @xsl.usage advanced
   */
  public int transformToGlobalRTF(ElemTemplateElement templateParent)
          throws TransformerException
  {
    // Retrieve a DTM to contain the RTF. At this writing, this may be a
    // multi-document DTM (SAX2RTFDTM).
    DTM dtmFrag = m_xcontext.getGlobalRTFDTM();
    return transformToRTF(templateParent,dtmFrag);
  }
  
  /**
   * Given a stylesheet element, create a result tree fragment from it's
   * contents.
   * @param templateParent The template element that holds the fragment.
   * @param dtmFrag The DTM to write the RTF into
   * @return the NodeHandle for the root node of the resulting RTF.
   *
   * @throws TransformerException
   * @xsl.usage advanced
   */
  private int transformToRTF(ElemTemplateElement templateParent,DTM dtmFrag)
          throws TransformerException
  {

    XPathContext xctxt = m_xcontext;
    
    ContentHandler rtfHandler = dtmFrag.getContentHandler();

    // Obtain the ResultTreeFrag's root node.
    // NOTE: In SAX2RTFDTM, this value isn't available until after
    // the startDocument has been issued, so assignment has been moved
    // down a bit in the code.
    int resultFragment; // not yet reliably = dtmFrag.getDocument();

    // Save the current result tree handler.
    SerializationHandler savedRTreeHandler = this.m_serializationHandler;
 

    // And make a new handler for the RTF.
    ToSAXHandler h = new ToXMLSAXHandler();
    h.setContentHandler(rtfHandler);
    h.setTransformer(this);
    
    // Replace the old handler (which was already saved)
    m_serializationHandler = h;
 
    // use local variable for the current handler
    SerializationHandler rth = m_serializationHandler;

    try
    {
      rth.startDocument();
      
      // startDocument is "bottlenecked" in RTH. We need it acted upon immediately,
      // to set the DTM's state as in-progress, so that if the xsl:variable's body causes
      // further RTF activity we can keep that from bashing this DTM.
      rth.flushPending(); 
 
      try
      {

        // Do the transformation of the child elements.
        executeChildTemplates(templateParent, true);

        // Make sure everything is flushed!
        rth.flushPending();
        
        // Get the document ID. May not exist until the RTH has not only
        // received, but flushed, the startDocument, and may be invalid
        // again after the document has been closed (still debating that)
        // ... so waiting until just before the end seems simplest/safest. 
	resultFragment = dtmFrag.getDocument();      
      }
      finally
      {
        rth.endDocument();
      }
    }
    catch (org.xml.sax.SAXException se)
    {
      throw new TransformerException(se);
    }
    finally
    {

      // Restore the previous result tree handler.
      this.m_serializationHandler = savedRTreeHandler;
    }

    return resultFragment;
  }

  /**
   * Get the StringWriter pool, so that StringWriter
   * objects may be reused.
   *
   * @return The string writer pool, not null.
   * @xsl.usage internal
   */
  public ObjectPool getStringWriterPool()
  {
    return m_stringWriterObjectPool;
  }

  /**
   * Take the contents of a template element, process it, and
   * convert it to a string.
   *
   * @param elem The parent element whose children will be output
   * as a string.
   *
   * @return The stringized result of executing the elements children.
   *
   * @throws TransformerException
   * @xsl.usage advanced
   */
  public String transformToString(ElemTemplateElement elem)
          throws TransformerException
  {
    ElemTemplateElement firstChild = elem.getFirstChildElem();
    if(null == firstChild)
      return "";
    if(elem.hasTextLitOnly() && m_optimizer)
    {
      return ((ElemTextLiteral)firstChild).getNodeValue();
    }

    // Save the current result tree handler.
    SerializationHandler savedRTreeHandler = this.m_serializationHandler;

    // Create a Serializer object that will handle the SAX events 
    // and build the ResultTreeFrag nodes.
    StringWriter sw = (StringWriter) m_stringWriterObjectPool.getInstance();

    m_serializationHandler =
        (ToTextStream) m_textResultHandlerObjectPool.getInstance();

      if (null == m_serializationHandler)
      {
        // if we didn't get one from the pool, go make a new one

        
        Serializer serializer = org.apache.xml.serializer.SerializerFactory.getSerializer(
            m_textformat.getProperties());
        m_serializationHandler = (SerializationHandler) serializer;
      } 

        m_serializationHandler.setTransformer(this);
        m_serializationHandler.setWriter(sw);
 
 
    String result;

    try
    {
        /* Don't call startDocument, the SerializationHandler  will
         * generate its own internal startDocument call anyways
         */
      // this.m_serializationHandler.startDocument();

      // Do the transformation of the child elements.
      executeChildTemplates(elem, true);
        this.m_serializationHandler.endDocument();

      result = sw.toString();
    }
    catch (org.xml.sax.SAXException se)
    {
      throw new TransformerException(se);
    }
    finally
    {
      sw.getBuffer().setLength(0);

      try
      {
        sw.close();
      }
      catch (Exception ioe){}

      m_stringWriterObjectPool.freeInstance(sw);
      m_serializationHandler.reset();
      m_textResultHandlerObjectPool.freeInstance(m_serializationHandler);

      // Restore the previous result tree handler.
      m_serializationHandler = savedRTreeHandler;
    }

    return result;
  }

  /**
   * Given an element and mode, find the corresponding
   * template and process the contents.
   *
   * @param xslInstruction The calling element.
   * @param template The template to use if xsl:for-each, current template for apply-imports, or null.
   * @param child The source context node.
   * @throws TransformerException
   * @return true if applied a template, false if not.
   * @xsl.usage advanced
   */
  public boolean applyTemplateToNode(ElemTemplateElement xslInstruction,  // xsl:apply-templates or xsl:for-each
                                     ElemTemplate template, int child)
                                             throws TransformerException
  {

    DTM dtm = m_xcontext.getDTM(child);
    short nodeType = dtm.getNodeType(child);
    boolean isDefaultTextRule = false;
    boolean isApplyImports = false;
    
    isApplyImports = ((xslInstruction == null)
                                ? false
                                : xslInstruction.getXSLToken()
                                  == Constants.ELEMNAME_APPLY_IMPORTS);        

    if (null == template || isApplyImports)
    {
      int maxImportLevel, endImportLevel=0;

      if (isApplyImports)
      {
        maxImportLevel =
          template.getStylesheetComposed().getImportCountComposed() - 1;
        endImportLevel =
          template.getStylesheetComposed().getEndImportCountComposed();
      }
      else
      {
        maxImportLevel = -1;
      }

      // If we're trying an xsl:apply-imports at the top level (ie there are no
      // imported stylesheets), we need to indicate that there is no matching template.
      // The above logic will calculate a maxImportLevel of -1 which indicates
      // that we should find any template.  This is because a value of -1 for
      // maxImportLevel has a special meaning.  But we don't want that.
      // We want to match -no- templates. See bugzilla bug 1170.
      if (isApplyImports && (maxImportLevel == -1))
      {
        template = null;
      }
      else
      {

        // Find the XSL template that is the best match for the 
        // element.        
        XPathContext xctxt = m_xcontext;

        try
        {
          xctxt.pushNamespaceContext(xslInstruction);

          QName mode = this.getMode();
          
          if (isApplyImports)
            template = m_stylesheetRoot.getTemplateComposed(xctxt, child, mode,
                  maxImportLevel, endImportLevel, m_quietConflictWarnings, dtm);
          else
            template = m_stylesheetRoot.getTemplateComposed(xctxt, child, mode,
                  m_quietConflictWarnings, dtm);
          
        }
        finally
        {
          xctxt.popNamespaceContext();
        }
      }

      // If that didn't locate a node, fall back to a default template rule.
      // See http://www.w3.org/TR/xslt#built-in-rule.
      if (null == template)
      {
        switch (nodeType)
        {
        case DTM.DOCUMENT_FRAGMENT_NODE :
        case DTM.ELEMENT_NODE :
          template = m_stylesheetRoot.getDefaultRule();
          break;
        case DTM.CDATA_SECTION_NODE :
        case DTM.TEXT_NODE :
        case DTM.ATTRIBUTE_NODE :
          template = m_stylesheetRoot.getDefaultTextRule();
          isDefaultTextRule = true;
          break;
        case DTM.DOCUMENT_NODE :
          template = m_stylesheetRoot.getDefaultRootRule();
          break;
        default :

          // No default rules for processing instructions and the like.
          return false;
        }
      }
    }

    // If we are processing the default text rule, then just clone 
    // the value directly to the result tree.
    try
    {
      pushElemTemplateElement(template);
      m_xcontext.pushCurrentNode(child);
      pushPairCurrentMatched(template, child);
      
      // Fix copy copy29 test.
      if (!isApplyImports) {
          DTMIterator cnl = new org.apache.xpath.NodeSetDTM(child, m_xcontext.getDTMManager());
          m_xcontext.pushContextNodeList(cnl);
      }

      if (isDefaultTextRule)
      {
        switch (nodeType)
        {
        case DTM.CDATA_SECTION_NODE :
        case DTM.TEXT_NODE :
          ClonerToResultTree.cloneToResultTree(child, nodeType, 
                                        dtm, getResultTreeHandler(), false);
          break;
        case DTM.ATTRIBUTE_NODE :
          dtm.dispatchCharactersEvents(child, getResultTreeHandler(), false);
          break;
        }
      }
      else
      {

        // Fire a trace event for the template.
         
        if (m_debug)
          getTraceManager().fireTraceEvent(template);
        // And execute the child templates.
        // 9/11/00: If template has been compiled, hand off to it
        // since much (most? all?) of the processing has been inlined.
        // (It would be nice if there was a single entry point that
        // worked for both... but the interpretive system works by
        // having the Tranformer execute the children, while the
        // compiled obviously has to run its own code. It's
        // also unclear that "execute" is really the right name for
        // that entry point.)
        m_xcontext.setSAXLocator(template);
        // m_xcontext.getVarStack().link();
        m_xcontext.getVarStack().link(template.m_frameSize);
        executeChildTemplates(template, true);
        
        if (m_debug)
          getTraceManager().fireTraceEndEvent(template);
      }
    }
    catch (org.xml.sax.SAXException se)
    {
      throw new TransformerException(se);
    }
    finally
    {
      if (!isDefaultTextRule)
        m_xcontext.getVarStack().unlink();
      m_xcontext.popCurrentNode();
      if (!isApplyImports) {
          m_xcontext.popContextNodeList();
      }
      popCurrentMatched();
      
      popElemTemplateElement();
    }

    return true;
  }
  
  
  /**
   * Execute each of the children of a template element.  This method
   * is only for extension use.
   *
   * @param elem The ElemTemplateElement that contains the children
   * that should execute.
   * NEEDSDOC @param context
   * @param mode The current mode.
   * @param handler The ContentHandler to where the result events
   * should be fed.
   *
   * @throws TransformerException
   * @xsl.usage advanced
   */
  public void executeChildTemplates(
          ElemTemplateElement elem, org.w3c.dom.Node context, QName mode, ContentHandler handler)
            throws TransformerException
  {

    XPathContext xctxt = m_xcontext;

    try
    {
      if(null != mode)
        pushMode(mode);
      xctxt.pushCurrentNode(xctxt.getDTMHandleFromNode(context));
      executeChildTemplates(elem, handler);
    }
    finally
    {
      xctxt.popCurrentNode();
      
      // I'm not sure where or why this was here.  It is clearly in 
      // error though, without a corresponding pushMode().
      if (null != mode)
        popMode();
    }
  }

  /**
   * Execute each of the children of a template element.
   *
   * @param elem The ElemTemplateElement that contains the children
   * that should execute.
   * @param shouldAddAttrs true if xsl:attributes should be executed.
   *
   * @throws TransformerException
   * @xsl.usage advanced
   */
  public void executeChildTemplates(
          ElemTemplateElement elem, boolean shouldAddAttrs)
            throws TransformerException
  {

    // Does this element have any children?
    ElemTemplateElement t = elem.getFirstChildElem();

    if (null == t)
      return;      
    
    if(elem.hasTextLitOnly() && m_optimizer)
    {      
      char[] chars = ((ElemTextLiteral)t).getChars();
      try
      {
        // Have to push stuff on for tooling...
        this.pushElemTemplateElement(t);
        m_serializationHandler.characters(chars, 0, chars.length);
      }
      catch(SAXException se)
      {
        throw new TransformerException(se);
      }
      finally
      {
        this.popElemTemplateElement();
      }
      return;
    }

//    // Check for infinite loops if we have to.
//    boolean check = (m_stackGuard.m_recursionLimit > -1);
//
//    if (check)
//      getStackGuard().push(elem, xctxt.getCurrentNode());

    XPathContext xctxt = m_xcontext;
    xctxt.pushSAXLocatorNull();
    int currentTemplateElementsTop = m_currentTemplateElements.size();
    m_currentTemplateElements.push(null);

    try
    {
      // Loop through the children of the template, calling execute on 
      // each of them.
      for (; t != null; t = t.getNextSiblingElem())
      {
        if (!shouldAddAttrs
                && t.getXSLToken() == Constants.ELEMNAME_ATTRIBUTE)
          continue;

        xctxt.setSAXLocator(t);
        m_currentTemplateElements.setElementAt(t,currentTemplateElementsTop);
        t.execute(this);
      }
    }
    catch(RuntimeException re)
    {
    	TransformerException te = new TransformerException(re);
    	te.setLocator(t);
    	throw te;
    }
    finally
    {
      m_currentTemplateElements.pop();
      xctxt.popSAXLocator();
    }

    // Check for infinite loops if we have to
//    if (check)
//      getStackGuard().pop();
  }
    /**
      * Execute each of the children of a template element.
      *
      * @param elem The ElemTemplateElement that contains the children
      * that should execute.
      * @param handler The ContentHandler to where the result events
      * should be fed.
      *
      * @throws TransformerException
      * @xsl.usage advanced
      */
     public void executeChildTemplates(
             ElemTemplateElement elem, ContentHandler handler)
               throws TransformerException
     {

       SerializationHandler xoh = this.getSerializationHandler();

       // These may well not be the same!  In this case when calling
       // the Redirect extension, it has already set the ContentHandler
       // in the Transformer.
       SerializationHandler savedHandler = xoh;

       try
       {
         xoh.flushPending();

         // %REVIEW% Make sure current node is being pushed.
         LexicalHandler lex = null;
         if (handler instanceof LexicalHandler) {
            lex = (LexicalHandler) handler;
         }
         m_serializationHandler = new ToXMLSAXHandler(handler, lex, savedHandler.getEncoding());
         m_serializationHandler.setTransformer(this);
         executeChildTemplates(elem, true);
       }
       catch (TransformerException e)
       {
         throw e;
       }
       catch (SAXException se) {
       	 throw new TransformerException(se);
       }
       finally
       {
         m_serializationHandler = savedHandler;
    }
  }

  /**
   * Get the keys for the xsl:sort elements.
   * Note: Should this go into ElemForEach?
   *
   * @param foreach Valid ElemForEach element, not null.
   * @param sourceNodeContext The current node context in the source tree,
   * needed to evaluate the Attribute Value Templates.
   *
   * @return A Vector of NodeSortKeys, or null.
   *
   * @throws TransformerException
   * @xsl.usage advanced
   */
  public Vector processSortKeys(ElemForEach foreach, int sourceNodeContext)
          throws TransformerException
  {

    Vector keys = null;
    XPathContext xctxt = m_xcontext;
    int nElems = foreach.getSortElemCount();

    if (nElems > 0)
      keys = new Vector();

    // March backwards, collecting the sort keys.
    for (int i = 0; i < nElems; i++)
    {
      ElemSort sort = foreach.getSortElem(i);
      
      if (m_debug)
        getTraceManager().fireTraceEvent(sort);
     
      String langString =
        (null != sort.getLang())
        ? sort.getLang().evaluate(xctxt, sourceNodeContext, foreach) : null;
      String dataTypeString = sort.getDataType().evaluate(xctxt,
                                sourceNodeContext, foreach);

      if (dataTypeString.indexOf(":") >= 0)
        System.out.println(
          "TODO: Need to write the hooks for QNAME sort data type");
      else if (!(dataTypeString.equalsIgnoreCase(Constants.ATTRVAL_DATATYPE_TEXT))
               &&!(dataTypeString.equalsIgnoreCase(
                 Constants.ATTRVAL_DATATYPE_NUMBER)))
        foreach.error(XSLTErrorResources.ER_ILLEGAL_ATTRIBUTE_VALUE,
                      new Object[]{ Constants.ATTRNAME_DATATYPE,
                                    dataTypeString });

      boolean treatAsNumbers =
        ((null != dataTypeString) && dataTypeString.equals(
        Constants.ATTRVAL_DATATYPE_NUMBER)) ? true : false;
      String orderString = sort.getOrder().evaluate(xctxt, sourceNodeContext,
                             foreach);

      if (!(orderString.equalsIgnoreCase(Constants.ATTRVAL_ORDER_ASCENDING))
              &&!(orderString.equalsIgnoreCase(
                Constants.ATTRVAL_ORDER_DESCENDING)))
        foreach.error(XSLTErrorResources.ER_ILLEGAL_ATTRIBUTE_VALUE,
                      new Object[]{ Constants.ATTRNAME_ORDER,
                                    orderString });

      boolean descending =
        ((null != orderString) && orderString.equals(
        Constants.ATTRVAL_ORDER_DESCENDING)) ? true : false;
      AVT caseOrder = sort.getCaseOrder();
      boolean caseOrderUpper;

      if (null != caseOrder)
      {
        String caseOrderString = caseOrder.evaluate(xctxt, sourceNodeContext,
                                                    foreach);

        if (!(caseOrderString.equalsIgnoreCase(Constants.ATTRVAL_CASEORDER_UPPER))
                &&!(caseOrderString.equalsIgnoreCase(
                  Constants.ATTRVAL_CASEORDER_LOWER)))
          foreach.error(XSLTErrorResources.ER_ILLEGAL_ATTRIBUTE_VALUE,
                        new Object[]{ Constants.ATTRNAME_CASEORDER,
                                      caseOrderString });

        caseOrderUpper =
          ((null != caseOrderString) && caseOrderString.equals(
          Constants.ATTRVAL_CASEORDER_UPPER)) ? true : false;
      }
      else
      {
        caseOrderUpper = false;
      }

      keys.addElement(new NodeSortKey(this, sort.getSelect(), treatAsNumbers,
                                      descending, langString, caseOrderUpper,
                                      foreach));
      if (m_debug)
        getTraceManager().fireTraceEndEvent(sort);
     }

    return keys;
  }

  //==========================================================
  // SECTION: TransformState implementation
  //==========================================================
  
  /**
   * Get the stack of ElemTemplateElements.
   * 
   * @return A copy of stack that contains the xsl element instructions, 
   * the earliest called in index zero, and the latest called in index size()-1.
   */
  public Vector getElementCallstack()
  {
  	Vector elems = new Vector();
  	int nStackSize = m_currentTemplateElements.size();
  	for(int i = 0; i < nStackSize; i++)
  	{
  		ElemTemplateElement elem = (ElemTemplateElement) m_currentTemplateElements.elementAt(i);
  		if(null != elem)
  		{
  			elems.addElement(elem);
  		}
  	}
  	return elems;
  }
  
  /**
   * Get the count of how many elements are 
   * active.
   * @return The number of active elements on 
   * the currentTemplateElements stack.
   */
  public int getCurrentTemplateElementsCount()
  {
  	return m_currentTemplateElements.size();
  }
  
  
  /**
   * Get the count of how many elements are 
   * active.
   * @return The number of active elements on 
   * the currentTemplateElements stack.
   */
  public ObjectStack getCurrentTemplateElements()
  {
  	return m_currentTemplateElements;
  }

  /**
   * Push the current template element.
   *
   * @param elem The current ElemTemplateElement (may be null, and then
   * set via setCurrentElement).
   */
  public void pushElemTemplateElement(ElemTemplateElement elem)
  {
    m_currentTemplateElements.push(elem);
  }

  /**
   * Pop the current template element.
   */
  public void popElemTemplateElement()
  {
    m_currentTemplateElements.pop();
  }

  /**
   * Set the top of the current template elements
   * stack.
   *
   * @param e The current ElemTemplateElement about to
   * be executed.
   */
  public void setCurrentElement(ElemTemplateElement e)
  {
    m_currentTemplateElements.setTop(e);
  }

  /**
   * Retrieves the current ElemTemplateElement that is
   * being executed.
   *
   * @return The current ElemTemplateElement that is executing,
   * should not normally be null.
   */
  public ElemTemplateElement getCurrentElement()
  {
    return (m_currentTemplateElements.size() > 0) ? 
        (ElemTemplateElement) m_currentTemplateElements.peek() : null;
  }

  /**
   * This method retrieves the current context node
   * in the source tree.
   *
   * @return The current context node (should never be null?).
   */
  public int getCurrentNode()
  {
    return m_xcontext.getCurrentNode();
  }
  
  /**
   * Get the call stack of xsl:template elements.
   * 
   * @return A copy of stack that contains the xsl:template 
   * (ElemTemplate) instructions, the earliest called in index 
   * zero, and the latest called in index size()-1.
   */
  public Vector getTemplateCallstack()
  {
  	Vector elems = new Vector();
  	int nStackSize = m_currentTemplateElements.size();
  	for(int i = 0; i < nStackSize; i++)
  	{
  		ElemTemplateElement elem = (ElemTemplateElement) m_currentTemplateElements.elementAt(i);
  		if(null != elem && (elem.getXSLToken() != Constants.ELEMNAME_TEMPLATE))
  		{
  			elems.addElement(elem);
  		}
  	}
  	return elems;
  }


  /**
   * This method retrieves the xsl:template
   * that is in effect, which may be a matched template
   * or a named template.
   *
   * <p>Please note that the ElemTemplate returned may
   * be a default template, and thus may not have a template
   * defined in the stylesheet.</p>
   *
   * @return The current xsl:template, should not be null.
   */
  public ElemTemplate getCurrentTemplate()
  {

    ElemTemplateElement elem = getCurrentElement();

    while ((null != elem)
           && (elem.getXSLToken() != Constants.ELEMNAME_TEMPLATE))
    {
      elem = elem.getParentElem();
    }

    return (ElemTemplate) elem;
  }

  /**
   * Push both the current xsl:template or xsl:for-each onto the
   * stack, along with the child node that was matched.
   * (Note: should this only be used for xsl:templates?? -sb)
   *
   * @param template xsl:template or xsl:for-each.
   * @param child The child that was matched.
   */
  public void pushPairCurrentMatched(ElemTemplateElement template, int child)
  {
    m_currentMatchTemplates.push(template);
    m_currentMatchedNodes.push(child);
  }

  /**
   * Pop the elements that were pushed via pushPairCurrentMatched.
   */
  public void popCurrentMatched()
  {
    m_currentMatchTemplates.pop();
    m_currentMatchedNodes.pop();
  }

  /**
   * This method retrieves the xsl:template
   * that was matched.  Note that this may not be
   * the same thing as the current template (which
   * may be from getCurrentElement()), since a named
   * template may be in effect.
   *
   * @return The pushed template that was pushed via pushPairCurrentMatched.
   */
  public ElemTemplate getMatchedTemplate()
  {
    return (ElemTemplate) m_currentMatchTemplates.peek();
  }

  /**
   * Retrieves the node in the source tree that matched
   * the template obtained via getMatchedTemplate().
   *
   * @return The matched node that corresponds to the
   * match attribute of the current xsl:template.
   */
  public int getMatchedNode()
  {
    return m_currentMatchedNodes.peepTail();
  }

  /**
   * Get the current context node list.
   *
   * @return A reset clone of the context node list.
   */
  public DTMIterator getContextNodeList()
  {

    try
    {
      DTMIterator cnl = m_xcontext.getContextNodeList();

      return (cnl == null) ? null : (DTMIterator) cnl.cloneWithReset();
    }
    catch (CloneNotSupportedException cnse)
    {

      // should never happen.
      return null;
    }
  }

  /**
   * Get the TrAX Transformer object in effect.
   *
   * @return This object.
   */
  public Transformer getTransformer()
  {
    return this;
  }

  //==========================================================
  // SECTION: Accessor Functions
  //==========================================================

  /**
   * Set the stylesheet for this processor.  If this is set, then the
   * process calls that take only the input .xml will use
   * this instead of looking for a stylesheet PI.  Also,
   * setting the stylesheet is needed if you are going
   * to use the processor as a SAX ContentHandler.
   *
   * @param stylesheetRoot A non-null StylesheetRoot object,
   * or null if you wish to clear the stylesheet reference.
   */
  public void setStylesheet(StylesheetRoot stylesheetRoot)
  {
    m_stylesheetRoot = stylesheetRoot;
  }

  /**
   * Get the current stylesheet for this processor.
   *
   * @return The stylesheet that is associated with this
   * transformer.
   */
  public final StylesheetRoot getStylesheet()
  {
    return m_stylesheetRoot;
  }

  /**
   * Get quietConflictWarnings property. If the quietConflictWarnings
   * property is set to true, warnings about pattern conflicts won't be
   * printed to the diagnostics stream.
   *
   * @return True if this transformer should not report
   * template match conflicts.
   */
  public boolean getQuietConflictWarnings()
  {
    return m_quietConflictWarnings;
  }

  /**
   * If the quietConflictWarnings property is set to
   * true, warnings about pattern conflicts won't be
   * printed to the diagnostics stream.
   * False by default.
   * (Currently setting this property will have no effect.)
   *
   * @param b true if conflict warnings should be suppressed.
   */
  public void setQuietConflictWarnings(boolean b)
  {
    m_quietConflictWarnings = b;
  }

  /**
   * Set the execution context for XPath.
   *
   * @param xcontext A non-null reference to the XPathContext
   * associated with this transformer.
   * @xsl.usage internal
   */
  public void setXPathContext(XPathContext xcontext)
  {
    m_xcontext = xcontext;
  }

  /**
   * Get the XPath context associated with this transformer.
   *
   * @return The XPathContext reference, never null.
   */
  public final XPathContext getXPathContext()
  {
    return m_xcontext;
  }

  /**
   * Get the object used to guard the stack from
   * recursion.
   *
   * @return The StackGuard object, which should never be null.
   * @xsl.usage internal
   */
  public StackGuard getStackGuard()
  {
    return m_stackGuard;
  }

  /**
   * Get the recursion limit.
   * Used for infinite loop check. If the value is -1, do not
   * check for infinite loops. Anyone who wants to enable that
   * check should change the value of this variable to be the
   * level of recursion that they want to check. Be careful setting
   * this variable, if the number is too low, it may report an
   * infinite loop situation, when there is none.
   * Post version 1.0.0, we'll make this a runtime feature.
   *
   * @return The limit on recursion, or -1 if no check is to be made.
   */
  public int getRecursionLimit()
  {
    return m_stackGuard.getRecursionLimit();
  }

  /**
   * Set the recursion limit.
   * Used for infinite loop check. If the value is -1, do not
   * check for infinite loops. Anyone who wants to enable that
   * check should change the value of this variable to be the
   * level of recursion that they want to check. Be careful setting
   * this variable, if the number is too low, it may report an
   * infinite loop situation, when there is none.
   * Post version 1.0.0, we'll make this a runtime feature.
   *
   * @param limit A number that represents the limit of recursion,
   * or -1 if no checking is to be done.
   */
  public void setRecursionLimit(int limit)
  {
    m_stackGuard.setRecursionLimit(limit);
  }

  /**
   * Get the SerializationHandler object.
   *
   * @return The current SerializationHandler, which may not
   * be the main result tree manager.
   */
  public SerializationHandler getResultTreeHandler()
  {
    return m_serializationHandler;
  }

  /**
   * Get the SerializationHandler object.
   *
   * @return The current SerializationHandler, which may not
   * be the main result tree manager.
   */
  public SerializationHandler getSerializationHandler()
  {
    return m_serializationHandler;
  }
  
  /**
   * Get the KeyManager object.
   *
   * @return A reference to the KeyManager object, which should
   * never be null.
   */
  public KeyManager getKeyManager()
  {
    return m_keyManager;
  }

  /**
   * Check to see if this is a recursive attribute definition.
   *
   * @param attrSet A non-null ElemAttributeSet reference.
   *
   * @return true if the attribute set is recursive.
   */
  public boolean isRecursiveAttrSet(ElemAttributeSet attrSet)
  {

    if (null == m_attrSetStack)
    {
      m_attrSetStack = new Stack();
    }

    if (!m_attrSetStack.empty())
    {
      int loc = m_attrSetStack.search(attrSet);

      if (loc > -1)
      {
        return true;
      }
    }

    return false;
  }

  /**
   * Push an executing attribute set, so we can check for
   * recursive attribute definitions.
   *
   * @param attrSet A non-null ElemAttributeSet reference.
   */
  public void pushElemAttributeSet(ElemAttributeSet attrSet)
  {
    m_attrSetStack.push(attrSet);
  }

  /**
   * Pop the current executing attribute set.
   */
  public void popElemAttributeSet()
  {
    m_attrSetStack.pop();
  }

  /**
   * Get the table of counters, for optimized xsl:number support.
   *
   * @return The CountersTable, never null.
   */
  public CountersTable getCountersTable()
  {

    if (null == m_countersTable)
      m_countersTable = new CountersTable();

    return m_countersTable;
  }

  /**
   * Tell if the current template rule is null, i.e. if we are
   * directly within an apply-templates.  Used for xsl:apply-imports.
   *
   * @return True if the current template rule is null.
   */
  public boolean currentTemplateRuleIsNull()
  {
    return ((!m_currentTemplateRuleIsNull.isEmpty())
            && (m_currentTemplateRuleIsNull.peek() == true));
  }

  /**
   * Push true if the current template rule is null, false
   * otherwise.
   *
   * @param b True if the we are executing an xsl:for-each
   * (or xsl:call-template?).
   */
  public void pushCurrentTemplateRuleIsNull(boolean b)
  {
    m_currentTemplateRuleIsNull.push(b);
  }

  /**
   * Push true if the current template rule is null, false
   * otherwise.
   */
  public void popCurrentTemplateRuleIsNull()
  {
    m_currentTemplateRuleIsNull.pop();
  }

  /**
   * Push a funcion result for the currently active EXSLT
   * <code>func:function</code>.
   * 
   * @param val the result of executing an EXSLT
   * <code>func:result</code> instruction for the current
   * <code>func:function</code>.
   */
  public void pushCurrentFuncResult(Object val) {
    m_currentFuncResult.push(val);
  }

  /**
   * Pops the result of the currently active EXSLT <code>func:function</code>.
   * 
   * @return the value of the <code>func:function</code>
   */
  public Object popCurrentFuncResult() {
    return m_currentFuncResult.pop();
  }

  /**
   * Determines whether an EXSLT <code>func:result</code> instruction has been
   * executed for the currently active EXSLT <code>func:function</code>.
   * 
   * @return <code>true</code> if and only if a <code>func:result</code>
   * instruction has been executed
   */
  public boolean currentFuncResultSeen() {
    return !m_currentFuncResult.empty()
               && m_currentFuncResult.peek() != null;
  }

  /**
   * Return the message manager.
   *
   * @return The message manager, never null.
   */
  public MsgMgr getMsgMgr()
  {

    if (null == m_msgMgr)
      m_msgMgr = new MsgMgr(this);

    return m_msgMgr;
  }

  /**
   * Set the error event listener.
   *
   * @param listener The new error listener.
   * @throws IllegalArgumentException if
   */
  public void setErrorListener(ErrorListener listener)
          throws IllegalArgumentException
  {

    synchronized (m_reentryGuard)
    {
      if (listener == null)
        throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_NULL_ERROR_HANDLER, null)); //"Null error handler");

      m_errorHandler = listener;
    }
  }

  /**
   * Get the current error event handler.
   *
   * @return The current error handler, which should never be null.
   */
  public ErrorListener getErrorListener()
  {
    return m_errorHandler;
  }

  /**
   * Get an instance of the trace manager for this transformation.
   * This object can be used to set trace listeners on various
   * events during the transformation.
   *
   * @return A reference to the TraceManager, never null.
   */
  public TraceManager getTraceManager()
  {
    return m_traceManager;
  }

  /**
   * Look up the value of a feature.
   *
   * <p>The feature name is any fully-qualified URI.  It is
   * possible for an TransformerFactory to recognize a feature name but
   * to be unable to return its value; this is especially true
   * in the case of an adapter for a SAX1 Parser, which has
   * no way of knowing whether the underlying parser is
   * validating, for example.</p>
   *
   * <h3>Open issues:</h3>
   * <dl>
   *    <dt><h4>Should getFeature be changed to hasFeature?</h4></dt>
   *    <dd>Keith Visco writes: Should getFeature be changed to hasFeature?
   *        It returns a boolean which indicated whether the "state"
   *        of feature is "true or false". I assume this means whether
   *        or not a feature is supported? I know SAX is using "getFeature",
   *        but to me "hasFeature" is cleaner.</dd>
   * </dl>
   *
   * @param name The feature name, which is a fully-qualified
   *        URI.
   * @return The current state of the feature (true or false).
   * @throws org.xml.sax.SAXNotRecognizedException When the
   *            TransformerFactory does not recognize the feature name.
   * @throws org.xml.sax.SAXNotSupportedException When the
   *            TransformerFactory recognizes the feature name but
   *            cannot determine its value at this time.
   *
   * @throws SAXNotRecognizedException
   * @throws SAXNotSupportedException
   */
  public boolean getFeature(String name)
          throws SAXNotRecognizedException, SAXNotSupportedException
  {

    if ("http://xml.org/trax/features/sax/input".equals(name))
      return true;
    else if ("http://xml.org/trax/features/dom/input".equals(name))
      return true;

    throw new SAXNotRecognizedException(name);
  }

  // %TODO% Doc

  /**
   * NEEDSDOC Method getMode 
   *
   *
   * NEEDSDOC (getMode) @return
   */
  public QName getMode()
  {
    return m_modes.isEmpty() ? null : (QName) m_modes.peek();
  }

  // %TODO% Doc

  /**
   * NEEDSDOC Method pushMode 
   *
   *
   * NEEDSDOC @param mode
   */
  public void pushMode(QName mode)
  {
    m_modes.push(mode);
  }

  // %TODO% Doc

  /**
   * NEEDSDOC Method popMode 
   *
   */
  public void popMode()
  {
    m_modes.pop();
  }

  /**
   * Called by SourceTreeHandler to start the transformation
   *  in a separate thread
   *
   * NEEDSDOC @param priority
   */
  public void runTransformThread(int priority)
  {

    // used in SourceTreeHandler
    Thread t = ThreadControllerWrapper.runThread(this, priority);
    this.setTransformThread(t);
  }

  /**
   * Called by this.transform() if isParserEventsOnMain()==false.
   *  Similar with runTransformThread(), but no priority is set
   *  and setTransformThread is not set.
   */
  public void runTransformThread()
  {
    ThreadControllerWrapper.runThread(this, -1);
  }
  
  /**
   * Called by CoRoutineSAXParser. Launches the CoroutineSAXParser
   * in a thread, and prepares it to invoke the parser from that thread
   * upon request. 
   *  
   */
  public static void runTransformThread(Runnable runnable)
  {
    ThreadControllerWrapper.runThread(runnable, -1);
  }

  /**
   * Used by SourceTreeHandler to wait until the transform
   *   completes
   *
   * @throws SAXException
   */
  public void waitTransformThread() throws SAXException
  {

    // This is called to make sure the task is done.
    // It is possible that the thread has been reused -
    // but for a different transformation. ( what if we 
    // recycle the transformer ? Not a problem since this is
    // still in use. )
    Thread transformThread = this.getTransformThread();

    if (null != transformThread)
    {
      try
      {
        ThreadControllerWrapper.waitThread(transformThread, this);

        if (!this.hasTransformThreadErrorCatcher())
        {
          Exception e = this.getExceptionThrown();

          if (null != e)
          {
            e.printStackTrace();
            throw new org.xml.sax.SAXException(e);
          }
        }

        this.setTransformThread(null);
      }
      catch (InterruptedException ie){}
    }
  }

  /**
   * Get the exception thrown by the secondary thread (normally
   * the transform thread).
   *
   * @return The thrown exception, or null if no exception was
   * thrown.
   */
  public Exception getExceptionThrown()
  {
    return m_exceptionThrown;
  }

  /**
   * Set the exception thrown by the secondary thread (normally
   * the transform thread).
   *
   * @param e The thrown exception, or null if no exception was
   * thrown.
   */
  public void setExceptionThrown(Exception e)
  {
    m_exceptionThrown = e;
  }

  /**
   * This is just a way to set the document for run().
   *
   * @param doc A non-null reference to the root of the
   * tree to be transformed.
   */
  public void setSourceTreeDocForThread(int doc)
  {
    m_doc = doc;
  }

  /**
   * Set the input source for the source tree, which is needed if the
   * parse thread is not the main thread, in order for the parse
   * thread's run method to get to the input source.
   *
   * @param source The input source for the source tree.
   */
  public void setXMLSource(Source source)
  {
    m_xmlSource = source;
  }

  /**
   * Tell if the transform method is completed.
   *
   * @return True if transformNode has completed, or
   * an exception was thrown.
   */
  public boolean isTransformDone()
  {

    synchronized (this)
    {
      return m_isTransformDone;
    }
  }

  /**
   * Set if the transform method is completed.
   *
   * @param done True if transformNode has completed, or
   * an exception was thrown.
   */
  public void setIsTransformDone(boolean done)
  {

    synchronized (this)
    {
      m_isTransformDone = done;
    }
  }

  /**
   * From a secondary thread, post the exception, so that
   * it can be picked up from the main thread.
   *
   * @param e The exception that was thrown.
   */
  void postExceptionFromThread(Exception e)
  {

    // Commented out in response to problem reported by Nicola Brown <Nicola.Brown@jacobsrimell.com>
    //    if(m_reportInPostExceptionFromThread)
    //    {
    //      // Consider re-throwing the exception if this flag is set.
    //      e.printStackTrace();
    //    }
    // %REVIEW Need DTM equivelent?    
    //    if (m_inputContentHandler instanceof SourceTreeHandler)
    //    {
    //      SourceTreeHandler sth = (SourceTreeHandler) m_inputContentHandler;
    //
    //      sth.setExceptionThrown(e);
    //    }
 //   ContentHandler ch = getContentHandler();

    //    if(ch instanceof SourceTreeHandler)
    //    {
    //      SourceTreeHandler sth = (SourceTreeHandler) ch;
    //      ((TransformerImpl)(sth.getTransformer())).postExceptionFromThread(e);
    //    }
    m_isTransformDone = true;
    m_exceptionThrown = e;
    ;  // should have already been reported via the error handler?

    synchronized (this)
    {

      // See message from me on 3/27/2001 to Patrick Moore.
      //      String msg = e.getMessage();
      // System.out.println(e.getMessage());
      // Is this really needed?  -sb
      notifyAll();

      //      if (null == msg)
      //      {
      //
      //        // m_throwNewError = false;
      //        e.printStackTrace();
      //      }
      // throw new org.apache.xml.utils.WrappedRuntimeException(e);
    }
  }

  /**
   * Run the transform thread.
   */
  public void run()
  {

    m_hasBeenReset = false;

    try
    {

      // int n = ((SourceTreeHandler)getInputContentHandler()).getDTMRoot();
      // transformNode(n);
      try
      {
        m_isTransformDone = false;
        
        // Should no longer be needed...
//          if(m_inputContentHandler instanceof TransformerHandlerImpl)
//          {
//            TransformerHandlerImpl thi = (TransformerHandlerImpl)m_inputContentHandler;
//            thi.waitForInitialEvents();
//          }

        transformNode(m_doc);
        
      }
      catch (Exception e)
      {
        // e.printStackTrace();

        // Strange that the other catch won't catch this...
        if (null != m_transformThread)
          postExceptionFromThread(e);   // Assume we're on the main thread
        else 
          throw new RuntimeException(e.getMessage());
      }
      finally
      {
        m_isTransformDone = true;

        if (m_inputContentHandler instanceof TransformerHandlerImpl)
        {
          ((TransformerHandlerImpl) m_inputContentHandler).clearCoRoutine();
        }

        //        synchronized (this)
        //        {
        //          notifyAll();
        //        }
      }
    }
    catch (Exception e)
    {

      // e.printStackTrace();
      if (null != m_transformThread)
        postExceptionFromThread(e);
      else 
        throw new RuntimeException(e.getMessage());         // Assume we're on the main thread.
    }
  }

  // Fragment re-execution interfaces for a tool.

  /**
   * This will get a snapshot of the current executing context 
   *
   *
   * @return TransformSnapshot object, snapshot of executing context
   * @deprecated This is an internal tooling API that nobody seems to be using
   */
  public TransformSnapshot getSnapshot()
  {
    return new TransformSnapshotImpl(this);
  }

  /**
   * This will execute the following XSLT instructions
   * from the snapshot point, after the stylesheet execution
   * context has been reset from the snapshot point. 
   *
   * @param ts The snapshot of where to start execution
   *
   * @throws TransformerException
   * @deprecated This is an internal tooling API that nobody seems to be using
   */
  public void executeFromSnapshot(TransformSnapshot ts)
          throws TransformerException
  {

    ElemTemplateElement template = getMatchedTemplate();
    int child = getMatchedNode();

    pushElemTemplateElement(template);  //needed??
    m_xcontext.pushCurrentNode(child);  //needed??
    this.executeChildTemplates(template, true);  // getResultTreeHandler());
  }

  /**
   * This will reset the stylesheet execution context
   * from the snapshot point.
   *
   * @param ts The snapshot of where to start execution
   * @deprecated This is an internal tooling API that nobody seems to be using
   */
  public void resetToStylesheet(TransformSnapshot ts)
  {
    ((TransformSnapshotImpl) ts).apply(this);
  }

  /**
   * NEEDSDOC Method stopTransformation 
   *
   */
  public void stopTransformation(){}

  /**
   * Test whether whitespace-only text nodes are visible in the logical
   * view of <code>DTM</code>. Normally, this function
   * will be called by the implementation of <code>DTM</code>;
   * it is not normally called directly from
   * user code.
   *
   * @param elementHandle int Handle of the element.
   * @return one of NOTSTRIP, STRIP, or INHERIT.
   */
  public short getShouldStripSpace(int elementHandle, DTM dtm)
  {

    try
    {
      org.apache.xalan.templates.WhiteSpaceInfo info =
        m_stylesheetRoot.getWhiteSpaceInfo(m_xcontext, elementHandle, dtm);

      if (null == info)
      {
        return DTMWSFilter.INHERIT;
      }
      else
      {

        // System.out.println("getShouldStripSpace: "+info.getShouldStripSpace());
        return info.getShouldStripSpace()
               ? DTMWSFilter.STRIP : DTMWSFilter.NOTSTRIP;
      }
    }
    catch (TransformerException se)
    {
      return DTMWSFilter.INHERIT;
    }
  }
  /**
   * Initializer method.
   *
   * @param transformer non-null transformer instance
   * @param realHandler Content Handler instance
   */
   public void init(ToXMLSAXHandler h,Transformer transformer, ContentHandler realHandler)
   {
      h.setTransformer(transformer);
      h.setContentHandler(realHandler);
   }
      
   public void setSerializationHandler(SerializationHandler xoh)
   {
      m_serializationHandler = xoh;
   }
   
   
     
	/**
	 * Fire off characters, cdate events.
	 * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int, char[], int, int)
	 */
	public void fireGenerateEvent(
		int eventType,
		char[] ch,
		int start,
		int length) {
			
		GenerateEvent ge = new GenerateEvent(this, eventType, ch, start, length);
		m_traceManager.fireGenerateEvent(ge);					
	}

	/**
	 * Fire off startElement, endElement events.
	 * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int, String, Attributes)
	 */
	public void fireGenerateEvent(
		int eventType,
		String name,
		Attributes atts) {
			
		GenerateEvent ge = new GenerateEvent(this, eventType, name, atts);
		m_traceManager.fireGenerateEvent(ge);					
	}

	/**
	 * Fire off processingInstruction events.
	 * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int, String, String)
	 */
	public void fireGenerateEvent(int eventType, String name, String data) {
		GenerateEvent ge = new GenerateEvent(this, eventType, name,data);
		m_traceManager.fireGenerateEvent(ge);				
	}

	/**
	 * Fire off comment and entity ref events.
	 * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int, String)
	 */
	public void fireGenerateEvent(int eventType, String data) {
		GenerateEvent ge = new GenerateEvent(this, eventType, data);
		m_traceManager.fireGenerateEvent(ge);		
	}

	/**
	 * Fire off startDocument, endDocument events.
	 * @see org.apache.xml.serializer.SerializerTrace#fireGenerateEvent(int)
	 */
	public void fireGenerateEvent(int eventType) {
		GenerateEvent ge = new GenerateEvent(this, eventType);
		m_traceManager.fireGenerateEvent(ge);
	}

    /**
     * @see org.apache.xml.serializer.SerializerTrace#hasTraceListeners()
     */
    public boolean hasTraceListeners() {
        return m_traceManager.hasTraceListeners();
    }

    public boolean getDebug() {
        return m_debug;
    }

    public void setDebug(boolean b) {
        m_debug = b;
    }

    /**
     * @return Incremental flag
     */
    public boolean getIncremental() {
        return m_incremental;
    }

    /**
     * @return Optimization flag
     */
    public boolean getOptimize() {
        return m_optimizer;
    }

    /**
     * @return Source location flag
     */
    public boolean getSource_location() {
        return m_source_location;
    }

}  // end TransformerImpl class

