/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2003 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.io.IOException;

import org.xml.sax.XMLReader;
import org.xml.sax.XMLFilter;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.Attributes;
import org.xml.sax.EntityResolver;
import org.xml.sax.DTDHandler;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.ext.DeclHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.ext.LexicalHandler;

import org.apache.xpath.objects.XString;

// import org.xml.sax.ext.DeclHandler;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.Transformer;
import javax.xml.transform.Result;

import org.apache.xpath.XPathContext;
import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMManager;
import org.apache.xml.dtm.ref.IncrementalSAXSource;
import org.apache.xml.dtm.ref.IncrementalSAXSource_Filter;
import org.apache.xml.dtm.ref.sax2dtm.SAX2DTM;

import org.apache.xalan.res.XSLTErrorResources;
import org.apache.xalan.res.XSLMessages;


/**
 * A TransformerHandler
 * listens for SAX ContentHandler parse events and transforms
 * them to a Result.
 */
public class TransformerHandlerImpl
        implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler,
                   LexicalHandler, TransformerHandler, DeclHandler
{
  
  private boolean m_insideParse = false;

  ////////////////////////////////////////////////////////////////////
  // Constructors.
  ////////////////////////////////////////////////////////////////////

  /**
   * Construct a TransformerHandlerImpl.
   *
   * @param transformer Non-null reference to the Xalan transformer impl.
   * @param doFragment True if the result should be a document fragement.
   * @param baseSystemID  The system ID to use as the base for relative URLs.
   */
  public TransformerHandlerImpl(TransformerImpl transformer,
                                boolean doFragment, String baseSystemID)
  {

    super();

    m_transformer = transformer;
    m_baseSystemID = baseSystemID;

    XPathContext xctxt = transformer.getXPathContext();
    DTM dtm = xctxt.getDTM(null, true, transformer, true, true);
    
    m_dtm = dtm;
    dtm.setDocumentBaseURI(baseSystemID);

    m_contentHandler = dtm.getContentHandler();
    m_dtdHandler = dtm.getDTDHandler();
    m_entityResolver = dtm.getEntityResolver();
    m_errorHandler = dtm.getErrorHandler();
    m_lexicalHandler = dtm.getLexicalHandler();
  }
  
  /** 
   * Do what needs to be done to shut down the CoRoutine management.
   */
  protected void clearCoRoutine()
  {
    clearCoRoutine(null);
  }
  
  /** 
   * Do what needs to be done to shut down the CoRoutine management.
   */
  protected void clearCoRoutine(SAXException ex)
  {
    if(null != ex)
      m_transformer.setExceptionThrown(ex);
    
    if(m_dtm instanceof SAX2DTM)
    {
      if(DEBUG)
        System.err.println("In clearCoRoutine...");
      try
      {
        SAX2DTM sax2dtm = ((SAX2DTM)m_dtm);          
        if(null != m_contentHandler 
           && m_contentHandler instanceof IncrementalSAXSource_Filter)
        {
          IncrementalSAXSource_Filter sp =
            (IncrementalSAXSource_Filter)m_contentHandler;
          // This should now be all that's needed.
          sp.deliverMoreNodes(false);
        }
        
        sax2dtm.clearCoRoutine(true);
        m_contentHandler = null;
        m_dtdHandler = null;
        m_entityResolver = null;
        m_errorHandler = null;
        m_lexicalHandler = null;
      }
      catch(Throwable throwable)
      {
        throwable.printStackTrace();
      }
      
      if(DEBUG)
        System.err.println("...exiting clearCoRoutine");
    }
  }
  
  ////////////////////////////////////////////////////////////////////
  // Implementation of javax.xml.transform.sax.TransformerHandler.
  ////////////////////////////////////////////////////////////////////

  /**
   * Enables the user of the TransformerHandler to set the
   * to set the Result for the transformation.
   *
   * @param result A Result instance, should not be null.
   *
   * @throws IllegalArgumentException if result is invalid for some reason.
   */
  public void setResult(Result result) throws IllegalArgumentException
  {

    if (null == result)
      throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_RESULT_NULL, null)); //"result should not be null");

    try
    {
      ContentHandler handler =
        m_transformer.createResultContentHandler(result);

      m_transformer.setContentHandler(handler);
    }
    catch (javax.xml.transform.TransformerException te)
    {
      throw new IllegalArgumentException(XSLMessages.createMessage(XSLTErrorResources.ER_RESULT_COULD_NOT_BE_SET, null)); //"result could not be set");
    }

    m_result = result;
  }

  /**
   * Set the base ID (URI or system ID) from where relative
   * URLs will be resolved.
   * @param systemID Base URI for the source tree.
   */
  public void setSystemId(String systemID)
  {
    m_baseSystemID = systemID;
    m_dtm.setDocumentBaseURI(systemID);
  }

  /**
   * Get the base ID (URI or system ID) from where relative
   * URLs will be resolved.
   * @return The systemID that was set with {@link #setSystemId}.
   */
  public String getSystemId()
  {
    return m_baseSystemID;
  }

  /**
   * Get the Transformer associated with this handler, which
   * is needed in order to set parameters and output properties.
   *
   * @return The Transformer associated with this handler
   */
  public Transformer getTransformer()
  {
    return m_transformer;
  }

  ////////////////////////////////////////////////////////////////////
  // Implementation of org.xml.sax.EntityResolver.
  ////////////////////////////////////////////////////////////////////

  /**
   * Filter an external entity resolution.
   *
   * @param publicId The entity's public identifier, or null.
   * @param systemId The entity's system identifier.
   * @return A new InputSource or null for the default.
   *
   * @throws IOException
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @throws java.io.IOException The client may throw an
   *            I/O-related exception while obtaining the
   *            new InputSource.
   * @see org.xml.sax.EntityResolver#resolveEntity
   */
  public InputSource resolveEntity(String publicId, String systemId)
          throws SAXException, IOException
  {

    if (m_entityResolver != null)
    {
      return m_entityResolver.resolveEntity(publicId, systemId);
    }
    else
    {
      return null;
    }
  }

  ////////////////////////////////////////////////////////////////////
  // Implementation of org.xml.sax.DTDHandler.
  ////////////////////////////////////////////////////////////////////

  /**
   * Filter a notation declaration event.
   *
   * @param name The notation name.
   * @param publicId The notation's public identifier, or null.
   * @param systemId The notation's system identifier, or null.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.DTDHandler#notationDecl
   */
  public void notationDecl(String name, String publicId, String systemId)
          throws SAXException
  {

    if (m_dtdHandler != null)
    {
      m_dtdHandler.notationDecl(name, publicId, systemId);
    }
  }

  /**
   * Filter an unparsed entity declaration event.
   *
   * @param name The entity name.
   * @param publicId The entity's public identifier, or null.
   * @param systemId The entity's system identifier, or null.
   * @param notationName The name of the associated notation.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.DTDHandler#unparsedEntityDecl
   */
  public void unparsedEntityDecl(
          String name, String publicId, String systemId, String notationName)
            throws SAXException
  {

    if (m_dtdHandler != null)
    {
      m_dtdHandler.unparsedEntityDecl(name, publicId, systemId, notationName);
    }
  }

  ////////////////////////////////////////////////////////////////////
  // Implementation of org.xml.sax.ContentHandler.
  ////////////////////////////////////////////////////////////////////

  /**
   * Filter a new document locator event.
   *
   * @param locator The document locator.
   * @see org.xml.sax.ContentHandler#setDocumentLocator
   */
  public void setDocumentLocator(Locator locator)
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#setDocumentLocator: "
                         + locator.getSystemId());

    this.m_locator = locator;
    
    if(null == m_baseSystemID)
    {
      setSystemId(locator.getSystemId());
    }

    if (m_contentHandler != null)
    {
      m_contentHandler.setDocumentLocator(locator);
    }
  }

  /**
   * Filter a start document event.
   *
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#startDocument
   */
  public void startDocument() throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#startDocument");
      
    m_insideParse = true;

   // Thread listener = new Thread(m_transformer);

    if (m_contentHandler != null)
    {
      //m_transformer.setTransformThread(listener);
      if(DTMManager.getIncremental())
      {
        m_transformer.setSourceTreeDocForThread(m_dtm.getDocument());
            
        int cpriority = Thread.currentThread().getPriority();
    
        // runTransformThread is equivalent with the 2.0.1 code,
        // except that the Thread may come from a pool.
        m_transformer.runTransformThread( cpriority );
      }

      // This is now done _last_, because IncrementalSAXSource_Filter
      // will immediately go into a "wait until events are requested"
      // pause. I believe that will close our timing window.
      // %REVIEW%
      m_contentHandler.startDocument();
   }
        
   //listener.setDaemon(false);
   //listener.start();

  }

  /**
   * Filter an end document event.
   *
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#endDocument
   */
  public void endDocument() throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#endDocument");

    m_insideParse = false;
    
    if (m_contentHandler != null)
    {
      m_contentHandler.endDocument();
    }
    
    if(DTMManager.getIncremental())
    {
      m_transformer.waitTransformThread();
    }
    else
    {
      m_transformer.setSourceTreeDocForThread(m_dtm.getDocument());
      m_transformer.run();
    }
   /* Thread transformThread = m_transformer.getTransformThread();

    if (null != transformThread)
    {
      try
      {

        // This should wait until the transformThread is considered not alive.
        transformThread.join();

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

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

        m_transformer.setTransformThread(null);
      }
      catch (InterruptedException ie){}
    }*/
  }

  /**
   * Filter a start Namespace prefix mapping event.
   *
   * @param prefix The Namespace prefix.
   * @param uri The Namespace URI.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#startPrefixMapping
   */
  public void startPrefixMapping(String prefix, String uri)
          throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#startPrefixMapping: "
                         + prefix + ", " + uri);

    if (m_contentHandler != null)
    {
      m_contentHandler.startPrefixMapping(prefix, uri);
    }
  }

  /**
   * Filter an end Namespace prefix mapping event.
   *
   * @param prefix The Namespace prefix.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#endPrefixMapping
   */
  public void endPrefixMapping(String prefix) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#endPrefixMapping: "
                         + prefix);

    if (m_contentHandler != null)
    {
      m_contentHandler.endPrefixMapping(prefix);
    }
  }

  /**
   * Filter a start element event.
   *
   * @param uri The element's Namespace URI, or the empty string.
   * @param localName The element's local name, or the empty string.
   * @param qName The element's qualified (prefixed) name, or the empty
   *        string.
   * @param atts The element's attributes.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#startElement
   */
  public void startElement(
          String uri, String localName, String qName, Attributes atts)
            throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#startElement: " + qName);

    if (m_contentHandler != null)
    {
      m_contentHandler.startElement(uri, localName, qName, atts);
    }
  }

  /**
   * Filter an end element event.
   *
   * @param uri The element's Namespace URI, or the empty string.
   * @param localName The element's local name, or the empty string.
   * @param qName The element's qualified (prefixed) name, or the empty
   *        string.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#endElement
   */
  public void endElement(String uri, String localName, String qName)
          throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#endElement: " + qName);

    if (m_contentHandler != null)
    {
      m_contentHandler.endElement(uri, localName, qName);
    }
  }

  /**
   * Filter a character data event.
   *
   * @param ch An array of characters.
   * @param start The starting position in the array.
   * @param length The number of characters to use from the array.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#characters
   */
  public void characters(char ch[], int start, int length) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#characters: " + start + ", "
                         + length);

    if (m_contentHandler != null)
    {
      m_contentHandler.characters(ch, start, length);
    }
  }

  /**
   * Filter an ignorable whitespace event.
   *
   * @param ch An array of characters.
   * @param start The starting position in the array.
   * @param length The number of characters to use from the array.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#ignorableWhitespace
   */
  public void ignorableWhitespace(char ch[], int start, int length)
          throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#ignorableWhitespace: "
                         + start + ", " + length);

    if (m_contentHandler != null)
    {
      m_contentHandler.ignorableWhitespace(ch, start, length);
    }
  }

  /**
   * Filter a processing instruction event.
   *
   * @param target The processing instruction target.
   * @param data The text following the target.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#processingInstruction
   */
  public void processingInstruction(String target, String data)
          throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#processingInstruction: "
                         + target + ", " + data);

    if (m_contentHandler != null)
    {
      m_contentHandler.processingInstruction(target, data);
    }
  }

  /**
   * Filter a skipped entity event.
   *
   * @param name The name of the skipped entity.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ContentHandler#skippedEntity
   */
  public void skippedEntity(String name) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#skippedEntity: " + name);

    if (m_contentHandler != null)
    {
      m_contentHandler.skippedEntity(name);
    }
  }

  ////////////////////////////////////////////////////////////////////
  // Implementation of org.xml.sax.ErrorHandler.
  ////////////////////////////////////////////////////////////////////

  /**
   * Filter a warning event.
   *
   * @param e The nwarning as an exception.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ErrorHandler#warning
   */
  public void warning(SAXParseException e) throws SAXException
  {
    // This is not great, but we really would rather have the error 
    // handler be the error listener if it is a error handler.  Coroutine's fatalError 
    // can't really be configured, so I think this is the best thing right now 
    // for error reporting.  Possibly another JAXP 1.1 hole.  -sb
    javax.xml.transform.ErrorListener errorListener = m_transformer.getErrorListener();
    if(errorListener instanceof ErrorHandler)
    {
      ((ErrorHandler)errorListener).warning(e);
    }
    else
    {
      try
      {
        errorListener.warning(new javax.xml.transform.TransformerException(e));
      }
      catch(javax.xml.transform.TransformerException te)
      {
        throw e;
      }
    }
  }

  /**
   * Filter an error event.
   *
   * @param e The error as an exception.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ErrorHandler#error
   */
  public void error(SAXParseException e) throws SAXException
  {
    // %REVIEW% I don't think this should be called.  -sb
    // clearCoRoutine(e);

    // This is not great, but we really would rather have the error 
    // handler be the error listener if it is a error handler.  Coroutine's fatalError 
    // can't really be configured, so I think this is the best thing right now 
    // for error reporting.  Possibly another JAXP 1.1 hole.  -sb
    javax.xml.transform.ErrorListener errorListener = m_transformer.getErrorListener();
    if(errorListener instanceof ErrorHandler)
    {
      ((ErrorHandler)errorListener).error(e);
      if(null != m_errorHandler)
        m_errorHandler.error(e); // may not be called.
    }
    else
    {
      try
      {
        errorListener.error(new javax.xml.transform.TransformerException(e));
        if(null != m_errorHandler)
          m_errorHandler.error(e); // may not be called.
      }
      catch(javax.xml.transform.TransformerException te)
      {
        throw e;
      }
    }
  }

  /**
   * Filter a fatal error event.
   *
   * @param e The error as an exception.
   * @throws SAXException The client may throw
   *            an exception during processing.
   * @see org.xml.sax.ErrorHandler#fatalError
   */
  public void fatalError(SAXParseException e) throws SAXException
  {
    if(null != m_errorHandler)
    {
      try
      {
        m_errorHandler.fatalError(e);
      }
      catch(SAXParseException se)
      {
        // ignore
      }
      // clearCoRoutine(e);
    }

    // This is not great, but we really would rather have the error 
    // handler be the error listener if it is a error handler.  Coroutine's fatalError 
    // can't really be configured, so I think this is the best thing right now 
    // for error reporting.  Possibly another JAXP 1.1 hole.  -sb
    javax.xml.transform.ErrorListener errorListener = m_transformer.getErrorListener();
    
    if(errorListener instanceof ErrorHandler)
    {
      ((ErrorHandler)errorListener).fatalError(e);
      if(null != m_errorHandler)
        m_errorHandler.fatalError(e); // may not be called.
    }
    else
    {
      try
      {
        errorListener.fatalError(new javax.xml.transform.TransformerException(e));
        if(null != m_errorHandler)
          m_errorHandler.fatalError(e); // may not be called.
      }
      catch(javax.xml.transform.TransformerException te)
      {
        throw e;
      }
    }
  }

  ////////////////////////////////////////////////////////////////////
  // Implementation of org.xml.sax.ext.LexicalHandler.
  ////////////////////////////////////////////////////////////////////

  /**
   * Report the start of DTD declarations, if any.
   *
   * <p>Any declarations are assumed to be in the internal subset
   * unless otherwise indicated by a {@link #startEntity startEntity}
   * event.</p>
   *
   * <p>Note that the start/endDTD events will appear within
   * the start/endDocument events from ContentHandler and
   * before the first startElement event.</p>
   *
   * @param name The document type name.
   * @param publicId The declared public identifier for the
   *        external DTD subset, or null if none was declared.
   * @param systemId The declared system identifier for the
   *        external DTD subset, or null if none was declared.
   * @throws SAXException The application may raise an
   *            exception.
   * @see #endDTD
   * @see #startEntity
   */
  public void startDTD(String name, String publicId, String systemId)
          throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#startDTD: " + name + ", "
                         + publicId + ", " + systemId);

    if (null != m_lexicalHandler)
    {
      m_lexicalHandler.startDTD(name, publicId, systemId);
    }
  }

  /**
   * Report the end of DTD declarations.
   *
   * @throws SAXException The application may raise an exception.
   * @see #startDTD
   */
  public void endDTD() throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#endDTD");

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

  /**
   * Report the beginning of an entity in content.
   *
   * <p><strong>NOTE:</entity> entity references in attribute
   * values -- and the start and end of the document entity --
   * are never reported.</p>
   *
   * <p>The start and end of the external DTD subset are reported
   * using the pseudo-name "[dtd]".  All other events must be
   * properly nested within start/end entity events.</p>
   *
   * <p>Note that skipped entities will be reported through the
   * {@link org.xml.sax.ContentHandler#skippedEntity skippedEntity}
   * event, which is part of the ContentHandler interface.</p>
   *
   * @param name The name of the entity.  If it is a parameter
   *        entity, the name will begin with '%'.
   * @throws SAXException The application may raise an exception.
   * @see #endEntity
   * @see org.xml.sax.ext.DeclHandler#internalEntityDecl
   * @see org.xml.sax.ext.DeclHandler#externalEntityDecl
   */
  public void startEntity(String name) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#startEntity: " + name);

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

  /**
   * Report the end of an entity.
   *
   * @param name The name of the entity that is ending.
   * @throws SAXException The application may raise an exception.
   * @see #startEntity
   */
  public void endEntity(String name) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#endEntity: " + name);

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

  /**
   * Report the start of a CDATA section.
   *
   * <p>The contents of the CDATA section will be reported through
   * the regular {@link org.xml.sax.ContentHandler#characters
   * characters} event.</p>
   *
   * @throws SAXException The application may raise an exception.
   * @see #endCDATA
   */
  public void startCDATA() throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#startCDATA");

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

  /**
   * Report the end of a CDATA section.
   *
   * @throws SAXException The application may raise an exception.
   * @see #startCDATA
   */
  public void endCDATA() throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#endCDATA");

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

  /**
   * Report an XML comment anywhere in the document.
   *
   * <p>This callback will be used for comments inside or outside the
   * document element, including comments in the external DTD
   * subset (if read).</p>
   *
   * @param ch An array holding the characters in the comment.
   * @param start The starting position in the array.
   * @param length The number of characters to use from the array.
   * @throws SAXException The application may raise an exception.
   */
  public void comment(char ch[], int start, int length) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#comment: " + start + ", "
                         + length);

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

  ////////////////////////////////////////////////////////////////////
  // Implementation of org.xml.sax.ext.DeclHandler.
  ////////////////////////////////////////////////////////////////////

  /**
   * Report an element type declaration.
   *
   * <p>The content model will consist of the string "EMPTY", the
   * string "ANY", or a parenthesised group, optionally followed
   * by an occurrence indicator.  The model will be normalized so
   * that all whitespace is removed,and will include the enclosing
   * parentheses.</p>
   *
   * @param name The element type name.
   * @param model The content model as a normalized string.
   * @throws SAXException The application may raise an exception.
   */
  public void elementDecl(String name, String model) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#elementDecl: " + name + ", "
                         + model);

    if (null != m_declHandler)
    {
      m_declHandler.elementDecl(name, model);
    }
  }

  /**
   * Report an attribute type declaration.
   *
   * <p>Only the effective (first) declaration for an attribute will
   * be reported.  The type will be one of the strings "CDATA",
   * "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY",
   * "ENTITIES", or "NOTATION", or a parenthesized token group with
   * the separator "|" and all whitespace removed.</p>
   *
   * @param eName The name of the associated element.
   * @param aName The name of the attribute.
   * @param type A string representing the attribute type.
   * @param valueDefault A string representing the attribute default
   *        ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if
   *        none of these applies.
   * @param value A string representing the attribute's default value,
   *        or null if there is none.
   * @throws SAXException The application may raise an exception.
   */
  public void attributeDecl(
          String eName, String aName, String type, String valueDefault, String value)
            throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#attributeDecl: " + eName
                         + ", " + aName + ", etc...");

    if (null != m_declHandler)
    {
      m_declHandler.attributeDecl(eName, aName, type, valueDefault, value);
    }
  }

  /**
   * Report an internal entity declaration.
   *
   * <p>Only the effective (first) declaration for each entity
   * will be reported.</p>
   *
   * @param name The name of the entity.  If it is a parameter
   *        entity, the name will begin with '%'.
   * @param value The replacement text of the entity.
   * @throws SAXException The application may raise an exception.
   * @see #externalEntityDecl
   * @see org.xml.sax.DTDHandler#unparsedEntityDecl
   */
  public void internalEntityDecl(String name, String value)
          throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#internalEntityDecl: " + name
                         + ", " + value);

    if (null != m_declHandler)
    {
      m_declHandler.internalEntityDecl(name, value);
    }
  }

  /**
   * Report a parsed external entity declaration.
   *
   * <p>Only the effective (first) declaration for each entity
   * will be reported.</p>
   *
   * @param name The name of the entity.  If it is a parameter
   *        entity, the name will begin with '%'.
   * @param publicId The declared public identifier of the entity, or
   *        null if none was declared.
   * @param systemId The declared system identifier of the entity.
   * @throws SAXException The application may raise an exception.
   * @see #internalEntityDecl
   * @see org.xml.sax.DTDHandler#unparsedEntityDecl
   */
  public void externalEntityDecl(
          String name, String publicId, String systemId) throws SAXException
  {

    if (DEBUG)
      System.out.println("TransformerHandlerImpl#externalEntityDecl: " + name
                         + ", " + publicId + ", " + systemId);

    if (null != m_declHandler)
    {
      m_declHandler.externalEntityDecl(name, publicId, systemId);
    }
  }

  ////////////////////////////////////////////////////////////////////
  // Internal state.
  ////////////////////////////////////////////////////////////////////

  /** Set to true for diagnostics output.         */
  private static boolean DEBUG = false;

  /**
   * The transformer this will use to transform a
   * source tree into a result tree.
   */
  private TransformerImpl m_transformer;

  /** The system ID to use as a base for relative URLs. */
  private String m_baseSystemID;

  /** The result for the transformation. */
  private Result m_result = null;

  /** The locator for this TransformerHandler. */
  private Locator m_locator = null;

  /** The entity resolver to aggregate to. */
  private EntityResolver m_entityResolver = null;

  /** The DTD handler to aggregate to. */
  private DTDHandler m_dtdHandler = null;

  /** The content handler to aggregate to. */
  private ContentHandler m_contentHandler = null;

  /** The error handler to aggregate to. */
  private ErrorHandler m_errorHandler = null;

  /** The lexical handler to aggregate to. */
  private LexicalHandler m_lexicalHandler = null;

  /** The decl handler to aggregate to. */
  private DeclHandler m_declHandler = null;
  
  /** The Document Table Instance we are transforming. */
  DTM m_dtm;
}
