/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:  
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, Lotus
 * Development Corporation., http://www.lotus.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
package org.apache.xalan.transformer;

import java.util.Enumeration;

import org.apache.xalan.templates.Stylesheet;
import org.apache.xalan.templates.StylesheetRoot;
import org.apache.xalan.templates.ElemTemplate;
import org.apache.xalan.templates.ElemTemplateElement;
import org.apache.xalan.trace.TraceManager;
import org.apache.xalan.trace.GenerateEvent;
import org.apache.xml.utils.MutableAttrListImpl;
import org.apache.xml.utils.QName;
import org.apache.xml.utils.TreeWalker;
import org.apache.xml.utils.ObjectPool;
import org.apache.xml.utils.XMLCharacterRecognizer;
import org.apache.xpath.objects.XObject;
import org.apache.xpath.XPathContext;
import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMIterator;
import org.apache.xml.dtm.DTMFilter;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.SAXParseException;
import org.xml.sax.SAXException;
import org.xml.sax.ErrorHandler;

import org.xml.sax.helpers.NamespaceSupport;
import org.apache.xml.utils.NamespaceSupport2;
import org.xml.sax.Locator;

import javax.xml.transform.TransformerException;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.Transformer;

/**
 * This class is a layer between the direct calls to the result
 * tree content handler, and the transformer.  For one thing,
 * we have to delay the call to
 * getContentHandler().startElement(name, atts) because of the
 * xsl:attribute and xsl:copy calls.  In other words,
 * the attributes have to be fully collected before you
 * can call startElement.
 */
public class ResultTreeHandler extends QueuedEvents
        implements ContentHandler, LexicalHandler, TransformState,
        org.apache.xml.dtm.ref.dom2dtm.DOM2DTM.CharacterNodeHandler,
        ErrorHandler
{

  /** Indicate whether running in Debug mode */
  private static final boolean DEBUG = false;

  /**
   * Null constructor for object pooling.
   */
  public ResultTreeHandler(){}

  /**
   * Create a new result tree handler.  The real content
   * handler will be the ContentHandler passed as an argument.
   *
   * @param transformer non-null transformer instance
   * @param realHandler Content Handler instance
   */
  public ResultTreeHandler(TransformerImpl transformer,
                           ContentHandler realHandler)
  {
    init(transformer, realHandler);
  }

  /**
   * Initializer method.
   *
   * @param transformer non-null transformer instance
   * @param realHandler Content Handler instance
   */
  public void init(TransformerImpl transformer, ContentHandler realHandler)
  {

    m_transformer = transformer;

    // m_startDoc.setTransformer(m_transformer);
    TraceManager tracer = transformer.getTraceManager();

    if ((null != tracer) && tracer.hasTraceListeners())
      m_tracer = tracer;
    else
      m_tracer = null;

    // m_startDoc.setTraceManager(m_tracer);
    m_contentHandler = realHandler;

    // m_startDoc.setContentHandler(m_contentHandler);
    if (m_contentHandler instanceof LexicalHandler)
      m_lexicalHandler = (LexicalHandler) m_contentHandler;
    else
      m_lexicalHandler = null;

    m_isTransformClient = (m_contentHandler instanceof TransformerClient);

    m_cloner = new ClonerToResultTree(transformer, this);

    // The stylesheet is set at a rather late stage, so I do 
    // this here, though it would probably be better done elsewhere.
    if (null != m_transformer)
      m_stylesheetRoot = m_transformer.getStylesheet();

    pushDocumentEvent();  // not pending yet.
  }

  /**
   * Bottleneck the startDocument event.
   *
   * @throws org.xml.sax.SAXException
   */
  public void startDocument() throws org.xml.sax.SAXException{}

  /**
   * Bottleneck the endDocument event.  This may be called
   * more than once in order to make sure the pending start
   * document is called.
   *
   * @throws org.xml.sax.SAXException
   */
  public void endDocument() throws org.xml.sax.SAXException
  {

    flushPending(true);

    if (!m_docEnded)
    {
      m_contentHandler.endDocument();

      if (null != m_tracer)
      {
        GenerateEvent ge =
          new GenerateEvent(m_transformer,
                            GenerateEvent.EVENTTYPE_ENDDOCUMENT, null);

        m_tracer.fireGenerateEvent(ge);
      }

      m_docEnded = true;
      m_docPending = false;
    }
  }

  /**
   * Bottleneck the startElement event.  This is used to "pend" an
   * element, so that attributes can still be added to it before
   * the real "startElement" is called on the result tree listener.
   *
   * @param ns Namespace URI of element
   * @param localName Local part of qname of element
   * @param name Name of element
   * @param atts List of attributes for the element
   *
   * @throws org.xml.sax.SAXException
   */
  public void startElement(
          String ns, String localName, String name, Attributes atts)
            throws org.xml.sax.SAXException
  {

    if (DEBUG)
    {
      if (m_elemIsPending)
        System.out.println("(ResultTreeHandler#startElement - pended: "
                           + m_url + "#" + m_localName);

      System.out.println("ResultTreeHandler#startElement: " + ns + "#"
                         + localName);

      //      if(null == ns)
      //      {
      //        (new RuntimeException(localName+" has a null namespace!")).printStackTrace();
      //      }
    }

    if(m_docPending)
      checkForSerializerSwitch(ns, localName);
      
    flushPending(true);

    if (!m_nsContextPushed)
    {
      if (DEBUG)
        System.out.println(
          "ResultTreeHandler#startElement - push(startElement)");

      m_nsSupport.pushContext();

      m_nsContextPushed = true;
    }
    
    if (ns != null)
      ensurePrefixIsDeclared(ns, name);

    m_name = name;
    m_url = ns;
    m_localName = localName;

    if (null != atts)
      m_attributes.addAttributes(atts);

    m_elemIsPending = true;
    m_elemIsEnded = false;
    
    if(m_isTransformClient && (null != m_transformer))
    {
      m_snapshot.m_currentElement = m_transformer.getCurrentElement();
      m_snapshot.m_currentTemplate = m_transformer.getCurrentTemplate();
      m_snapshot.m_matchedTemplate = m_transformer.getMatchedTemplate();
      int currentNodeHandle = m_transformer.getCurrentNode();
      DTM dtm = m_transformer.getXPathContext().getDTM(currentNodeHandle);
      m_snapshot.m_currentNode = dtm.getNode(currentNodeHandle);
      m_snapshot.m_matchedNode = m_transformer.getMatchedNode();
      m_snapshot.m_contextNodeList = m_transformer.getContextNodeList(); // TODO: Need to clone
    }
    // initQSE(m_startElement);

    m_eventCount++;
  }

  /**
   * Bottleneck the endElement event.
   *
   * @param ns Namespace URI of element
   * @param localName Local part of qname of element
   * @param name Name of element
   *
   * @throws org.xml.sax.SAXException
   */
  public void endElement(String ns, String localName, String name)
          throws org.xml.sax.SAXException
  {

    if (DEBUG)
    {
      if (m_elemIsPending)
        System.out.println("(ResultTreeHandler#endElement - pended: "
                           + m_url + "#" + m_localName);

      System.out.println("ResultTreeHandler#endElement: " + ns + "#"
                         + localName);
    }

    flushPending(true);
    m_contentHandler.endElement(ns, localName, name);

    if (null != m_tracer)
    {
      GenerateEvent ge = new GenerateEvent(m_transformer,
                                           GenerateEvent.EVENTTYPE_ENDELEMENT,
                                           name, (Attributes)null);

      m_tracer.fireGenerateEvent(ge);
    }

    sendEndPrefixMappings();
    popEvent();

    if (DEBUG)
      System.out.println("ResultTreeHandler#startElement pop: " + localName);

    m_nsSupport.popContext();
  }

  /** Indicate whether a namespace context was pushed */
  boolean m_nsContextPushed = false;

  /**
   * Begin the scope of a prefix-URI Namespace mapping.
   *
   * <p>The information from this event is not necessary for
   * normal Namespace processing: the SAX XML reader will
   * automatically replace prefixes for element and attribute
   * names when the http://xml.org/sax/features/namespaces
   * feature is true (the default).</p>
   *
   * <p>There are cases, however, when applications need to
   * use prefixes in character data or in attribute values,
   * where they cannot safely be expanded automatically; the
   * start/endPrefixMapping event supplies the information
   * to the application to expand prefixes in those contexts
   * itself, if necessary.</p>
   *
   * <p>Note that start/endPrefixMapping events are not
   * guaranteed to be properly nested relative to each-other:
   * all startPrefixMapping events will occur before the
   * corresponding startElement event, and all endPrefixMapping
   * events will occur after the corresponding endElement event,
   * but their order is not guaranteed.</p>
   *
   * @param prefix The Namespace prefix being declared.
   * @param uri The Namespace URI the prefix is mapped to.
   * @throws org.xml.sax.SAXException The client may throw
   *            an exception during processing.
   * @see #endPrefixMapping
   * @see #startElement
   */
  public void startPrefixMapping(String prefix, String uri)
          throws org.xml.sax.SAXException
  {
    startPrefixMapping(prefix, uri, true);
  }

  /**
   * Begin the scope of a prefix-URI Namespace mapping.
   *
   *
   * @param prefix The Namespace prefix being declared.
   * @param uri The Namespace URI the prefix is mapped to.
   * @param shouldFlush Indicate whether pending events needs
   * to be flushed first
   *
   * @throws org.xml.sax.SAXException The client may throw
   *            an exception during processing.
   */
  public void startPrefixMapping(
          String prefix, String uri, boolean shouldFlush)
            throws org.xml.sax.SAXException
  {

    if (shouldFlush)
      flushPending(false);

    if (!m_nsContextPushed)
    {
      if (DEBUG)
        System.out.println(
          "ResultTreeHandler#startPrefixMapping push(startPrefixMapping: "
          + prefix + ")");

      m_nsSupport.pushContext();

      m_nsContextPushed = true;
    }

    if (null == prefix)
      prefix = "";  // bit-o-hack, that that's OK

    String existingURI = m_nsSupport.getURI(prefix);

    if (null == existingURI)
      existingURI = "";

    if (null == uri)
      uri = "";

    if (!existingURI.equals(uri))
    {
      if (DEBUG)
      {
        System.out.println("ResultTreeHandler#startPrefixMapping Prefix: "
                           + prefix);
        System.out.println("ResultTreeHandler#startPrefixMapping uri: "
                           + uri);
      }

      m_nsSupport.declarePrefix(prefix, uri);
    }
  }

  /**
   * End the scope of a prefix-URI mapping.
   *
   * <p>See startPrefixMapping for details.  This event will
   * always occur after the corresponding endElement event,
   * but the order of endPrefixMapping events is not otherwise
   * guaranteed.</p>
   *
   * @param prefix The prefix that was being mapping.
   * @throws org.xml.sax.SAXException The client may throw
   *            an exception during processing.
   * @see #startPrefixMapping
   * @see #endElement
   */
  public void endPrefixMapping(String prefix)
          throws org.xml.sax.SAXException{}

  /**
   * Bottleneck the characters event.
   *
   * @param ch Array of characters to process
   * @param start start of characters in the array
   * @param length Number of characters in the array
   *
   * @throws org.xml.sax.SAXException
   */
  public void characters(char ch[], int start, int length)
          throws org.xml.sax.SAXException
  {

    // It would be nice to suppress all whitespace before the
    // first element, but this is going to cause potential problems with 
    // text serialization and with text entities (right term?).
    // So this really needs to be done at the serializer level.

    /*if (m_startDoc.isPending
    && XMLCharacterRecognizer.isWhiteSpace(ch, start, length))
    return;*/
    if (DEBUG)
    {
      System.out.print("ResultTreeHandler#characters: ");

      int n = start + length;

      for (int i = start; i < n; i++)
      {
        if (Character.isWhitespace(ch[i]))
          System.out.print("\\" + ((int) ch[i]));
        else
          System.out.print(ch[i]);
      }

      System.out.println("");
    }

    flushPending(true);
    m_contentHandler.characters(ch, start, length);

    if (null != m_tracer)
    {
      GenerateEvent ge = new GenerateEvent(m_transformer,
                                           GenerateEvent.EVENTTYPE_CHARACTERS,
                                           ch, start, length);

      m_tracer.fireGenerateEvent(ge);
    }
  }
  
  public void characters(org.w3c.dom.Node node)
          throws org.xml.sax.SAXException
  {

    flushPending(true);
    
    if(m_isTransformClient)
      m_snapshot.m_currentNode = node;

    String data = node.getNodeValue();
    char [] ch = null;
    int length = 0;
    if (data != null)
    {
    ch = data.toCharArray();
    length = data.length();
    m_contentHandler.characters(ch, 0, length);
    }
    
    if (null != m_tracer)
    {
      GenerateEvent ge = new GenerateEvent(m_transformer,
                                           GenerateEvent.EVENTTYPE_CHARACTERS,
                                           ch, 0, length);

      m_tracer.fireGenerateEvent(ge);
    }  
    if(m_isTransformClient)
      m_snapshot.m_currentNode = null;
  }

  /**
   * Bottleneck the ignorableWhitespace event.
   *
   * @param ch Array of characters to process
   * @param start start of characters in the array
   * @param length Number of characters in the array
   *
   * @throws org.xml.sax.SAXException
   */
  public void ignorableWhitespace(char ch[], int start, int length)
          throws org.xml.sax.SAXException
  {

    if (m_docPending
            && XMLCharacterRecognizer.isWhiteSpace(ch, start, length))
      return;

    flushPending(true);
    m_contentHandler.ignorableWhitespace(ch, start, length);

    if (null != m_tracer)
    {
      GenerateEvent ge =
        new GenerateEvent(m_transformer,
                          GenerateEvent.EVENTTYPE_IGNORABLEWHITESPACE, ch,
                          start, length);

      m_tracer.fireGenerateEvent(ge);
    }
  }

  /**
   * Bottleneck the processingInstruction event.
   *
   * @param target Processing instruction target name
   * @param data Processing instruction data
   *
   * @throws org.xml.sax.SAXException
   */
  public void processingInstruction(String target, String data)
          throws org.xml.sax.SAXException
  {

    flushPending(true);
    m_contentHandler.processingInstruction(target, data);

    if (null != m_tracer)
    {
      GenerateEvent ge = new GenerateEvent(m_transformer,
                                           GenerateEvent.EVENTTYPE_PI,
                                           target, data);

      m_tracer.fireGenerateEvent(ge);
    }
  }

  /**
   * Bottleneck the comment event.
   *
   * @param data Comment data
   *
   * @throws org.xml.sax.SAXException
   */
  public void comment(String data) throws org.xml.sax.SAXException
  {

    flushPending(true);

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.comment(data.toCharArray(), 0, data.length());
    }

    if (null != m_tracer)
    {
      GenerateEvent ge = new GenerateEvent(m_transformer,
                                           GenerateEvent.EVENTTYPE_COMMENT,
                                           data);

      m_tracer.fireGenerateEvent(ge);
    }
  }

  /**
   * Bottleneck the comment event.
   *
   * @param ch Character array with comment data
   * @param start start of characters in the array
   * @param length number of characters in the array
   *
   * @throws org.xml.sax.SAXException
   */
  public void comment(char ch[], int start, int length)
          throws org.xml.sax.SAXException
  {

    flushPending(true);

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.comment(ch, start, length);
    }

    if (null != m_tracer)
    {
      GenerateEvent ge = new GenerateEvent(m_transformer,
                                           GenerateEvent.EVENTTYPE_COMMENT,
                                           new String(ch, start, length));

      m_tracer.fireGenerateEvent(ge);
    }
  }

  /**
   * Entity reference event.
   *
   * @param name Name of entity
   *
   * @throws org.xml.sax.SAXException
   */
  public void entityReference(String name) throws org.xml.sax.SAXException
  {

    flushPending(true);

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.startEntity(name);
      m_lexicalHandler.endEntity(name);
    }

    if (null != m_tracer)
    {
      GenerateEvent ge = new GenerateEvent(m_transformer,
                                           GenerateEvent.EVENTTYPE_ENTITYREF,
                                           name);

      m_tracer.fireGenerateEvent(ge);
    }
  }

  /**
   * Start an entity.
   *
   * @param name Name of the entity
   *
   * @throws org.xml.sax.SAXException
   */
  public void startEntity(String name) throws org.xml.sax.SAXException
  {

    flushPending(true);

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.startEntity(name);
    }
  }

  /**
   * End an entity.
   *
   * @param name Name of the entity
   *
   * @throws org.xml.sax.SAXException
   */
  public void endEntity(String name) throws org.xml.sax.SAXException
  {

    flushPending(true);

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.endEntity(name);
    }

    if (null != m_tracer)
    {
      GenerateEvent ge = new GenerateEvent(m_transformer,
                                           GenerateEvent.EVENTTYPE_ENTITYREF,
                                           name);

      m_tracer.fireGenerateEvent(ge);
    }
  }

  /**
   * Start the DTD.
   *
   * @param s1 The document type name.
   * @param s2 The declared public identifier for the
   *        external DTD subset, or null if none was declared.
   * @param s3 The declared system identifier for the
   *        external DTD subset, or null if none was declared.
   *
   * @throws org.xml.sax.SAXException
   */
  public void startDTD(String s1, String s2, String s3)
          throws org.xml.sax.SAXException
  {

    flushPending(true);

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.startDTD(s1, s2, s3);
    }
  }

  /**
   * End the DTD.
   *
   * @throws org.xml.sax.SAXException
   */
  public void endDTD() throws org.xml.sax.SAXException
  {

    flushPending(true);

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.endDTD();
    }
  }

  /**
   * Start the CDATACharacters.
   *
   * @throws org.xml.sax.SAXException
   */
  public void startCDATA() throws org.xml.sax.SAXException
  {

    flushPending(true);

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.startCDATA();
    }
  }

  /**
   * End the CDATA characters.
   *
   * @throws org.xml.sax.SAXException
   */
  public void endCDATA() throws org.xml.sax.SAXException
  {

    flushPending(true);

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.endCDATA();
    }
  }

  /**
   * Receive notification of a skipped entity.
   *
   * <p>The Parser will invoke this method once for each entity
   * skipped.  Non-validating processors may skip entities if they
   * have not seen the declarations (because, for example, the
   * entity was declared in an external DTD subset).  All processors
   * may skip external entities, depending on the values of the
   * http://xml.org/sax/features/external-general-entities and the
   * http://xml.org/sax/features/external-parameter-entities
   * properties.</p>
   *
   * @param name The name of the skipped entity.  If it is a
   *        parameter entity, the name will begin with '%'.
   * @throws org.xml.sax.SAXException Any SAX exception, possibly
   *            wrapping another exception.
   */
  public void skippedEntity(String name) throws org.xml.sax.SAXException{}

  /**
   * Set whether Namespace declarations have been added to
   * this element
   *
   *
   * @param b Flag indicating whether Namespace declarations
   * have been added to this element
   */
  public void setNSDeclsHaveBeenAdded(boolean b)
  {

    m_nsDeclsHaveBeenAdded = b;
  }

  /**
   * Flush the event.
   *
   * @throws TransformerException
   *
   * @throws org.xml.sax.SAXException
   */
  void flushDocEvent() throws org.xml.sax.SAXException
  {

    if (m_docPending)
    {
      m_contentHandler.startDocument();

      if (null != m_tracer)
      {
        GenerateEvent ge =
          new GenerateEvent(m_transformer,
                            GenerateEvent.EVENTTYPE_STARTDOCUMENT);

        m_tracer.fireGenerateEvent(ge);
      }

      if (m_contentHandler instanceof TransformerClient)
      {
        ((TransformerClient) m_contentHandler).setTransformState(this);
      }

      m_docPending = false;
    }
  }
  
  /**
   * Flush the event.
   *
   * @throws SAXException
   */
  void flushElem() throws org.xml.sax.SAXException
  {

    if (m_elemIsPending)
    {
      if (null != m_name)
      {
        try
        {
          m_contentHandler.startElement(m_url, m_localName, m_name,
                                      m_attributes);
        }
        catch(Exception re)
        {
          // If we don't do this, and the exception is a RuntimeException, 
          // good line numbers of where the exception occured in the stylesheet
          // won't get reported.  I tried just catching RuntimeException, but 
          // for whatever reason it didn't seem to catch.
          // Fix for Christina's DOMException error problem.
          throw new SAXParseException(re.getMessage(), 
          m_transformer.getCurrentElement().getPublicId(), 
          m_transformer.getCurrentElement().getSystemId(), 
          m_transformer.getCurrentElement().getLineNumber(), 
          m_transformer.getCurrentElement().getColumnNumber(), 
          re);
        }
        
        if(null != m_tracer)
        {
          GenerateEvent ge =
            new GenerateEvent(m_transformer,
                              GenerateEvent.EVENTTYPE_STARTELEMENT, m_name,
                                      m_attributes);
  
          m_tracer.fireGenerateEvent(ge);
        }
        if(m_isTransformClient)
          m_snapshot.m_currentNode = null;
      }

      m_elemIsPending = false;
      m_attributes.clear();
  
      m_nsDeclsHaveBeenAdded = false;
      m_name = null;
      m_url = null;
      m_localName = null;
      m_namespaces = null;

      // super.flush();
    }
  }


  /**
   * Flush the pending element.
   *
   * @throws org.xml.sax.SAXException
   */
  public final void flushPending() throws org.xml.sax.SAXException
  {
    flushPending(true);
  }

  /**
   * Flush the pending element, and any attributes associated with it.
   *
   * NOTE: If there are attributes but _no_ pending element (which can
   * happen if the user's stylesheet is doing something inappropriate),
   * we still want to make sure they are flushed.
   *
   * @param type Event type
   *
   * NEEDSDOC @param flushPrefixes
   *
   * @throws org.xml.sax.SAXException
   */
  public final void flushPending(boolean flushPrefixes)
          throws org.xml.sax.SAXException
  {

    if (flushPrefixes && m_docPending)
    {
      flushDocEvent();
    }

    if (m_elemIsPending)
    {
      // Combined loop shoud be much more efficient.
      // %REVIEW% %OPT% Will the "else" case ever arise?
      if (!m_nsDeclsHaveBeenAdded)
//        addNSDeclsToAttrs();
          startAndAddPrefixMappings();  // new
      else                              // new
          sendStartPrefixMappings();


      if (DEBUG)
      {
        System.out.println("ResultTreeHandler#flushPending - start flush: "
                           + m_name);
      }

      flushElem();

      if (DEBUG)
      {
        System.out.println(
          "ResultTreeHandler#flushPending - after flush, isPending: "
          + m_elemIsPending);
      }

      m_nsContextPushed = false;
    }
  }

  /**
   * Given a result tree fragment, walk the tree and
   * output it to the result stream.
   *
   * @param obj Result tree fragment object
   * @param support XPath context for the result tree fragment
   *
   * @throws org.xml.sax.SAXException
   */
  public void outputResultTreeFragment(XObject obj, XPathContext support)
          throws org.xml.sax.SAXException
  {

    int doc = obj.rtf();
    DTM dtm = support.getDTM(doc);

    if(null != dtm)
    {
	    for (int n = dtm.getFirstChild(doc); DTM.NULL != n;
	            n = dtm.getNextSibling(n))
	    {
	      flushPending(true);  // I think.
	      dtm.dispatchToEvents(n, this);
	    }
    }
  }

  /**
   * To fullfill the FormatterListener interface... no action
   * for the moment.
   *
   * @param locator Document locator
   */
  public void setDocumentLocator(Locator locator){}

  /**
   * This function checks to make sure a given prefix is really
   * declared.  It might not be, because it may be an excluded prefix.
   * If it's not, it still needs to be declared at this point.
   * TODO: This needs to be done at an earlier stage in the game... -sb
   *
   * @param ns Namespace URI of the element
   * @param rawName Raw name of element (with prefix)
   *
   * @throws org.xml.sax.SAXException
   */
  public void ensurePrefixIsDeclared(String ns, String rawName)
          throws org.xml.sax.SAXException
  {

    if (ns != null && ns.length() > 0)
    {
      int index;
      String prefix = (index = rawName.indexOf(":")) < 0
                      ? "" : rawName.substring(0, index);

      if (null != prefix)
      {
        String foundURI = m_nsSupport.getURI(prefix);

        if ((null == foundURI) ||!foundURI.equals(ns))
        {
          startPrefixMapping(prefix, ns, false);
                                        
          // Bugzilla1133: Generate attribute as well as namespace event.
          // SAX does expect both.

          m_attributes.addAttribute("http://www.w3.org/2000/xmlns/", 
                                    prefix, 
                                    "xmlns"+(prefix.length()==0 ? "" : ":")+prefix, 
                                    "CDATA", ns);
        }
      }
    }
  }

  /**
   * This function checks to make sure a given prefix is really
   * declared.  It might not be, because it may be an excluded prefix.
   * If it's not, it still needs to be declared at this point.
   * TODO: This needs to be done at an earlier stage in the game... -sb
   *
   * @param ns Namespace URI of the element
   * @param rawName Raw name of element (with prefix)
   *
   * NEEDSDOC @param dtm
   * NEEDSDOC @param namespace
   *
   * @throws org.xml.sax.SAXException
   */
  public void ensureNamespaceDeclDeclared(DTM dtm, int namespace)
          throws org.xml.sax.SAXException
  {

    String uri = dtm.getNodeValue(namespace);
    String prefix = dtm.getNodeNameX(namespace);

    if ((uri != null && uri.length() > 0) && (null != prefix))
    {
      String foundURI = m_nsSupport.getURI(prefix);

      if ((null == foundURI) ||!foundURI.equals(uri))
      {
        startPrefixMapping(prefix, uri, false);
      }
    }
  }

  /**
   * Add the attributes that have been declared to the attribute list.
   * (Seems like I shouldn't have to do this...)
   * Internally deprecated in favor of combined startAndAddPrefixMappings();
   * 
   *
   * @throws org.xml.sax.SAXException
   */
  protected void sendStartPrefixMappings() throws org.xml.sax.SAXException
  {
    Enumeration prefixes = m_nsSupport.getDeclaredPrefixes();
    ContentHandler handler = m_contentHandler;
    while (prefixes.hasMoreElements())
    {
      String prefix = (String) prefixes.nextElement();
      handler.startPrefixMapping(prefix, m_nsSupport.getURI(prefix));
    }
  }

  /**
   * Combination of sendStartPrefixMappings and
   * addNSDeclsToAttrs() (which it mostly replaces).  Merging the two
   * loops is significantly more efficient.
   *
   * @throws org.xml.sax.SAXException */
  protected void startAndAddPrefixMappings() throws org.xml.sax.SAXException
  {

    Enumeration prefixes = m_nsSupport.getDeclaredPrefixes();
    ContentHandler handler = m_contentHandler;

    while (prefixes.hasMoreElements())
    {
      String prefix = (String) prefixes.nextElement();
      String uri=m_nsSupport.getURI(prefix);
      
      // Send event
      handler.startPrefixMapping(prefix, uri);

      // Set attribute
      boolean isDefault = (prefix.length() == 0);
      String name;

      if (isDefault)
      {
        //prefix = "xml";
        name = "xmlns";
      }
      else
        name = "xmlns:" + prefix;

      if (null == uri)
        uri = "";

      m_attributes.addAttribute("http://www.w3.org/2000/xmlns/", 
                                prefix, name, "CDATA", uri);
    }
    m_nsDeclsHaveBeenAdded=true;
  }

  /**
   * Add the attributes that have been declared to the attribute list.
   * (Seems like I shouldn't have to do this...)
   *
   * @throws org.xml.sax.SAXException
   */
  protected void sendEndPrefixMappings() throws org.xml.sax.SAXException
  {

    Enumeration prefixes = m_nsSupport.getDeclaredPrefixes();
    ContentHandler handler = m_contentHandler;

    while (prefixes.hasMoreElements())
    {
      String prefix = (String) prefixes.nextElement();

      handler.endPrefixMapping(prefix);
    }
  }

  /**
   * Check to see if we should switch serializers based on the
   * first output element being an HTML element.
   *
   * @param ns Namespace URI of the element
   * @param localName Local part of name of the element
   *
   * @throws org.xml.sax.SAXException
   */
  private void checkForSerializerSwitch(String ns, String localName)
          throws org.xml.sax.SAXException
  {

    try
    {
      if (m_docPending)
      {
        SerializerSwitcher.switchSerializerIfHTML(m_transformer, ns,
                                                  localName);
      }
    }
    catch (TransformerException te)
    {
      throw new org.xml.sax.SAXException(te);
    }
  }

  /**
   * Add the attributes that have been declared to the attribute list.
   *
   * %REVIEW% This should have been done automatically during
   * flushPending(boolean); is it ever explicitly reinvoked?
   */
  public void addNSDeclsToAttrs()
  {

    Enumeration prefixes = m_nsSupport.getDeclaredPrefixes();

    while (prefixes.hasMoreElements())
    {
      String prefix = (String) prefixes.nextElement();
      boolean isDefault = (prefix.length() == 0);
      String name;

      if (isDefault)
      {

        //prefix = "xml";
        name = "xmlns";
      }
      else
        name = "xmlns:" + prefix;

      String uri = m_nsSupport.getURI(prefix);

      if (null == uri)
        uri = "";

      m_attributes.addAttribute("http://www.w3.org/2000/xmlns/", 
                                prefix, name, "CDATA", uri);
    }

    m_nsDeclsHaveBeenAdded = true;
  }

  /**
   * Copy <KBD>xmlns:</KBD> attributes in if not already in scope.
   * 
   * As a quick hack to support ClonerToResultTree, this can also be used
   * to copy an individual namespace node.
   *
   * @param src Source Node
   * NEEDSDOC @param type
   * NEEDSDOC @param dtm
   *
   * @throws TransformerException
   */
  public void processNSDecls(int src, int type, DTM dtm)
          throws TransformerException
  {

    try
    {
      if (type == DTM.ELEMENT_NODE)
      {
        for (int namespace = dtm.getFirstNamespaceNode(src, true);
                DTM.NULL != namespace;
                namespace = dtm.getNextNamespaceNode(src, namespace, true))
        {

          // String prefix = dtm.getPrefix(namespace);
          String prefix = dtm.getNodeNameX(namespace);
          String desturi = getURI(prefix);
          String srcURI = dtm.getNodeValue(namespace);

          if (!srcURI.equalsIgnoreCase(desturi))
          {
            this.startPrefixMapping(prefix, srcURI, false);
          }
        }
      }
      else if (type == DTM.NAMESPACE_NODE)
			{
          String prefix = dtm.getNodeNameX(src);
          String desturi = getURI(prefix);
          String srcURI = dtm.getNodeValue(src);

          if (!srcURI.equalsIgnoreCase(desturi))
          {
            this.startPrefixMapping(prefix, srcURI, false);
          }
			}
    }
    catch (org.xml.sax.SAXException se)
    {
      throw new TransformerException(se);
    }
  }

  /**
   * Given a prefix, return the namespace,
   *
   * @param prefix Given prefix name
   *
   * @return Namespace associated with the given prefix, or null
   */
  public String getURI(String prefix)
  {
    return m_nsSupport.getURI(prefix);
  }

  /**
   * Given a namespace, try and find a prefix.
   *
   * @param namespace Given namespace URI
   *
   * @return Prefix name associated with namespace URI
   */
  public String getPrefix(String namespace)
  {

    // This Enumeration business may be too slow for our purposes...
    Enumeration enum = m_nsSupport.getPrefixes();

    while (enum.hasMoreElements())
    {
      String prefix = (String) enum.nextElement();

      if (m_nsSupport.getURI(prefix).equals(namespace))
        return prefix;
    }

    return null;
  }

  /**
   * Get the NamespaceSupport object.
   *
   * @return NamespaceSupport object.
   */
  public NamespaceSupport getNamespaceSupport()
  {
    return m_nsSupport;
  }

  //  /**
  //   * Override QueuedEvents#initQSE.
  //   *
  //   * @param qse Give queued Sax event
  //   */
  //  protected void initQSE(QueuedSAXEvent qse)
  //  {
  //
  //    // qse.setContentHandler(m_contentHandler);
  //    // qse.setTransformer(m_transformer);
  //    // qse.setTraceManager(m_tracer);
  //  }

  /**
   * Return the current content handler.
   *
   * @return The current content handler, or null if none
   *         has been registered.
   * @see #setContentHandler
   */
  public final ContentHandler getContentHandler()
  {
    return m_contentHandler;
  }

  /**
   * Set the current content handler.
   *
   *
   * @param ch Content Handler to be set
   * @return The current content handler, or null if none
   *         has been registered.
   * @see #getContentHandler
   */
  public void setContentHandler(ContentHandler ch)
  {

    m_contentHandler = ch;

    m_isTransformClient = (m_contentHandler instanceof TransformerClient);

    if (m_contentHandler instanceof LexicalHandler)
      m_lexicalHandler = (LexicalHandler) m_contentHandler;
    else
      m_lexicalHandler = null;

    reInitEvents();
  }

  /**
   * Get a unique namespace value.
   *
   * @return a unique namespace value to be used with a
   * fabricated prefix
   */
  public int getUniqueNSValue()
  {
    return m_uniqueNSValue++;
  }

  /**
   * Get new unique namespace prefix.
   *
   * @return Unique fabricated prefix.
   */
  public String getNewUniqueNSPrefix()
  {
    return S_NAMESPACEPREFIX + String.valueOf(getUniqueNSValue());
  }

  /**
   * Get the pending attributes.  We have to delay the call to
   * m_flistener.startElement(name, atts) because of the
   * xsl:attribute and xsl:copy calls.  In other words,
   * the attributes have to be fully collected before you
   * can call startElement.
   *
   * @return the pending attributes.
   */
  public MutableAttrListImpl getPendingAttributes()
  {
    return m_attributes;
  }

  /**
   * Add an attribute to the end of the list.
   *
   * <p>Do not pass in xmlns decls to this function!
   *
   * <p>For the sake of speed, this method does no checking
   * to see if the attribute is already in the list: that is
   * the responsibility of the application.</p>
   *
   * @param uri The Namespace URI, or the empty string if
   *        none is available or Namespace processing is not
   *        being performed.
   * @param localName The local name, or the empty string if
   *        Namespace processing is not being performed.
   * @param rawName The raw XML 1.0 name, or the empty string
   *        if raw names are not available.
   * @param type The attribute type as a string.
   * @param value The attribute value.
   *
   * @throws TransformerException
   */
  public void addAttribute(
          String uri, String localName, String rawName, String type, String value)
            throws TransformerException
  {
    // %REVIEW% See Bugzilla 4344. Do we need an "else" that announces
    // an error? Technically, this can't happen unless the stylesheet
    // is unreasonable... but it's unclear whether silent or noisy
    // failure is called for.
    if (m_elemIsPending)
    {
      // %REVIEW% %OPT% Is this ever needed?????
      if (!m_nsDeclsHaveBeenAdded)
	addNSDeclsToAttrs();

      if (null == uri)  // defensive, should not really need this.
	uri = "";

      try
      {
	if (!rawName.equals("xmlns"))  // don't handle xmlns default namespace.
	  ensurePrefixIsDeclared(uri, rawName);
      }
      catch (org.xml.sax.SAXException se)
      {
	throw new TransformerException(se);
      }
      
      if (DEBUG)
	System.out.println("ResultTreeHandler#addAttribute Adding attr: "
			   + localName + ", " + uri);

      if (!isDefinedNSDecl(rawName, value))
	m_attributes.addAttribute(uri, localName, rawName, type, value);
    }
  }

  /**
   * Return whether or not a namespace declaration is defined
   *
   *
   * @param rawName Raw name of namespace element
   * @param value URI of given namespace
   *
   * @return True if the namespace is already defined in list of
   * namespaces
   */
  public boolean isDefinedNSDecl(String rawName, String value)
  {

    if (rawName.equals("xmlns") || rawName.startsWith("xmlns:"))
    {
      int index;
      String prefix = (index = rawName.indexOf(":")) < 0
                      ? "" : rawName.substring(0, index);
      String definedURI = m_nsSupport.getURI(prefix);

      if (null != definedURI)
      {
        if (definedURI.equals(value))
        {
          return true;
        }
        else
          return false;
      }
      else
        return false;
    }
    else
      return false;
  }

  /**
   * Returns whether a namespace is defined
   *
   *
   * @param attr Namespace attribute node
   *
   * @return True if the namespace is already defined in
   * list of namespaces
   */
  public boolean isDefinedNSDecl(int attr)
  {

    DTM dtm = m_transformer.getXPathContext().getDTM(attr);

    if (DTM.NAMESPACE_NODE == dtm.getNodeType(attr))
    {

      // String prefix = dtm.getPrefix(attr);
      String prefix = dtm.getNodeNameX(attr);
      String uri = getURI(prefix);

      if ((null != uri) && uri.equals(dtm.getStringValue(attr)))
        return true;
    }

    return false;
  }

  /**
   * Returns whether a namespace is defined
   *
   *
   * @param attr Namespace attribute node
   * @param dtm The DTM that owns attr.
   *
   * @return True if the namespace is already defined in
   * list of namespaces
   */
  public boolean isDefinedNSDecl(int attr, DTM dtm)
  {

    if (DTM.NAMESPACE_NODE == dtm.getNodeType(attr))
    {

      // String prefix = dtm.getPrefix(attr);
      String prefix = dtm.getNodeNameX(attr);
      String uri = getURI(prefix);

      if ((null != uri) && uri.equals(dtm.getStringValue(attr)))
        return true;
    }

    return false;
  }

  /**
   * Copy an DOM attribute to the created output element, executing
   * attribute templates as need be, and processing the xsl:use
   * attribute.
   *
   * @param attr Attribute node to add to result tree
   *
   * @throws TransformerException
   */
  public void addAttribute(int attr) throws TransformerException
  {

    DTM dtm = m_transformer.getXPathContext().getDTM(attr);

    if (isDefinedNSDecl(attr, dtm))
      return;

    String ns = dtm.getNamespaceURI(attr);

    if (ns == null)
      ns = "";

    // %OPT% ...can I just store the node handle?    
    addAttribute(ns, dtm.getLocalName(attr), dtm.getNodeName(attr), "CDATA",
                 dtm.getNodeValue(attr));
  }  // end copyAttributeToTarget method

  /**
   * Copy DOM attributes to the result element.
   *
   * @param src Source node with the attributes
   *
   * @throws TransformerException
   */
  public void addAttributes(int src) throws TransformerException
  {

    DTM dtm = m_transformer.getXPathContext().getDTM(src);

    for (int node = dtm.getFirstAttribute(src); DTM.NULL != node;
            node = dtm.getNextAttribute(node))
    {
      addAttribute(node);
    }
  }

  /**
   * Tell if an element is pending, to be output to the result tree.
   *
   * @return True if an element is pending
   */
  public final boolean isElementPending()
  {
    
    return m_elemIsPending;
  }

  /**
   * Retrieves the stylesheet element that produced
   * the SAX event.
   *
   * <p>Please note that the ElemTemplateElement returned may
   * be in a default template, and thus may not be
   * defined in the stylesheet.</p>
   *
   * @return the stylesheet element that produced the SAX event.
   */
  public ElemTemplateElement getCurrentElement()
  {

    if (m_elemIsPending)
      return m_snapshot.m_currentElement;
    else
      return m_transformer.getCurrentElement();
  }

  /**
   * This method retrieves the current context node
   * in the source tree.
   *
   * @return the current context node in the source tree.
   */
  public org.w3c.dom.Node getCurrentNode()
  {
    
    if (m_snapshot.m_currentNode != null)
    {
      return m_snapshot.m_currentNode;
    }
    else
    {
      DTM dtm = m_transformer.getXPathContext().getDTM(m_transformer.getCurrentNode());
      return dtm.getNode(m_transformer.getCurrentNode());
    }
  }

  /**
   * 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 xsl:template that is in effect
   */
  public ElemTemplate getCurrentTemplate()
  {

    if (m_elemIsPending)
      return m_snapshot.m_currentTemplate;
    else
      return m_transformer.getCurrentTemplate();
  }

  /**
   * 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.
   *
   * <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 xsl:template that was matched.
   */
  public ElemTemplate getMatchedTemplate()
  {

    if (m_elemIsPending)
      return m_snapshot.m_matchedTemplate;
    else
      return m_transformer.getMatchedTemplate();
  }

  /**
   * Retrieves the node in the source tree that matched
   * the template obtained via getMatchedTemplate().
   *
   * @return the node in the source tree that matched
   * the template obtained via getMatchedTemplate().
   */
  public org.w3c.dom.Node getMatchedNode()
  {

    if (m_elemIsPending)
    {
      DTM dtm = m_transformer.getXPathContext().getDTM(m_snapshot.m_matchedNode);
      return dtm.getNode(m_snapshot.m_matchedNode);
    }
    else
    {
      DTM dtm = m_transformer.getXPathContext().getDTM(m_transformer.getMatchedNode());
      return dtm.getNode(m_transformer.getMatchedNode());
    }
  }

  /**
   * Get the current context node list.
   *
   * @return the current context node list.
   */
  public org.w3c.dom.traversal.NodeIterator getContextNodeList()
  {

    if (m_elemIsPending)
    {
      return new org.apache.xml.dtm.ref.DTMNodeIterator(m_snapshot.m_contextNodeList);
    }
    else
      return new org.apache.xml.dtm.ref.DTMNodeIterator(m_transformer.getContextNodeList());
  }

  /**
   * Get the TrAX Transformer object in effect.
   *
   * @return the TrAX Transformer object in effect.
   */
  public Transformer getTransformer()
  {
    return m_transformer;
  }
  
  
  // Implement ErrorHandler
  
  /**
    * Receive notification of a warning.
    *
    * <p>SAX parsers will use this method to report conditions that
    * are not errors or fatal errors as defined by the XML 1.0
    * recommendation.  The default behaviour is to take no action.</p>
    *
    * <p>The SAX parser must continue to provide normal parsing events
    * after invoking this method: it should still be possible for the
    * application to process the document through to the end.</p>
    *
    * <p>Filters may use this method to report other, non-XML warnings
    * as well.</p>
    *
    * @param exception The warning information encapsulated in a
    *                  SAX parse exception.
    * @exception org.xml.sax.SAXException Any SAX exception, possibly
    *            wrapping another exception.
    * @see org.xml.sax.SAXParseException 
    */
  public void warning (SAXParseException exception)
    throws SAXException
  {
    if (m_contentHandler instanceof ErrorHandler)
      ((ErrorHandler)m_contentHandler).warning(exception);
  }
    
    
   /**
    * Receive notification of a recoverable error.
    *
    * <p>This corresponds to the definition of "error" in section 1.2
    * of the W3C XML 1.0 Recommendation.  For example, a validating
    * parser would use this callback to report the violation of a
    * validity constraint.  The default behaviour is to take no
    * action.</p>
    *
    * <p>The SAX parser must continue to provide normal parsing events
    * after invoking this method: it should still be possible for the
    * application to process the document through to the end.  If the
    * application cannot do so, then the parser should report a fatal
    * error even if the XML 1.0 recommendation does not require it to
    * do so.</p>
    *
    * <p>Filters may use this method to report other, non-XML errors
    * as well.</p>
    *
    * @param exception The error information encapsulated in a
    *                  SAX parse exception.
    * @exception org.xml.sax.SAXException Any SAX exception, possibly
    *            wrapping another exception.
    * @see org.xml.sax.SAXParseException 
    */
  public void error (SAXParseException exception)
    throws SAXException
  {
    if (m_contentHandler instanceof ErrorHandler)
      ((ErrorHandler)m_contentHandler).error(exception);
  }
    
    
   /**
    * Receive notification of a non-recoverable error.
    *
    * <p>This corresponds to the definition of "fatal error" in
    * section 1.2 of the W3C XML 1.0 Recommendation.  For example, a
    * parser would use this callback to report the violation of a
    * well-formedness constraint.</p>
    *
    * <p>The application must assume that the document is unusable
    * after the parser has invoked this method, and should continue
    * (if at all) only for the sake of collecting addition error
    * messages: in fact, SAX parsers are free to stop reporting any
    * other events once this method has been invoked.</p>
    *
    * @param exception The error information encapsulated in a
    *                  SAX parse exception.  
    * @exception org.xml.sax.SAXException Any SAX exception, possibly
    *            wrapping another exception.
    * @see org.xml.sax.SAXParseException
    */
  public void fatalError (SAXParseException exception)
    throws SAXException
  {      
    m_elemIsPending = false;
    m_docEnded = true;
    m_docPending = false;
    
    if (m_contentHandler instanceof ErrorHandler)
      ((ErrorHandler)m_contentHandler).fatalError(exception);
  }
  
  boolean m_isTransformClient = false;

  /**
   * Use the SAX2 helper class to track result namespaces.
   */
  NamespaceSupport m_nsSupport = new NamespaceSupport2();

  /**
   * The transformer object.
   */
  private TransformerImpl m_transformer;

  /**
   * The content handler.  May be null, in which
   * case, we'll defer to the content handler in the
   * transformer.
   */
  private ContentHandler m_contentHandler;

  /** The LexicalHandler */
  private LexicalHandler m_lexicalHandler;

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

  /**
   * This is used whenever a unique namespace is needed.
   */
  private int m_uniqueNSValue = 0;

  /** Prefix used to create unique prefix names */
  private static final String S_NAMESPACEPREFIX = "ns";

  /**
   * This class clones nodes to the result tree.
   */
  public ClonerToResultTree m_cloner;

  /**
   * Trace manager for debug support.
   */
  private TraceManager m_tracer;
  
  private QueuedStateSnapshot m_snapshot = new QueuedStateSnapshot();

  // These are passed to flushPending, to help it decide if it 
  // should really flush.
  
  class QueuedStateSnapshot
  {
    /**
     * The stylesheet element that produced the SAX event.
     */
    ElemTemplateElement m_currentElement;
    
    /**
     * The current context node in the source tree.
     */
    org.w3c.dom.Node m_currentNode;
    
    /**
     * The xsl:template that is in effect, which may be a matched template
     * or a named template.
     */
    ElemTemplate m_currentTemplate;
    
    /**
     * The xsl:template that was matched.
     */
    ElemTemplate m_matchedTemplate;
    
    /**
     * The node in the source tree that matched
     * the template obtained via getMatchedTemplate().
     */
    int m_matchedNode;
    
    /**
     * The current context node list.
     */
    DTMIterator m_contextNodeList;
  }
}
