package org.apache.commons.digester3;

/*
 * 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.
 */

import static java.lang.String.format;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EmptyStackException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.validation.Schema;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

/**
 * <p>
 * A <strong>Digester</strong> processes an XML input stream by matching a series of element nesting patterns to execute
 * Rules that have been added prior to the start of parsing.
 * </p>
 * <p>
 * See the <a href="package-summary.html#package_description">Digester Developer Guide</a> for more information.
 * </p>
 * <p>
 * <strong>IMPLEMENTATION NOTE</strong> - A single Digester instance may only be used within the context of a single
 * thread at a time, and a call to <code>parse()</code> must be completed before another can be initiated even from the
 * same thread.
 * </p>
 * <p>
 * A Digester instance should not be used for parsing more than one input document. The problem is that the Digester
 * class has quite a few member variables whose values "evolve" as SAX events are received during a parse. When reusing
 * the Digester instance, all these members must be reset back to their initial states before the second parse begins.
 * The "clear()" method makes a stab at resetting these, but it is actually rather a difficult problem. If you are
 * determined to reuse Digester instances, then at the least you should call the clear() method before each parse, and
 * must call it if the Digester parse terminates due to an exception during a parse.
 * </p>
 * <p>
 * <strong>LEGACY IMPLEMENTATION NOTE</strong> - When using the legacy XML schema support (instead of using the
 * {@link Schema} class), a bug in Xerces 2.0.2 prevents the support of XML schema. You need Xerces 2.1/2.3 and up to
 * make this class work with the legacy XML schema support.
 * </p>
 * <p>
 * This package was inspired by the <code>XmlMapper</code> class that was part of Tomcat 3.0 and 3.1, but is organized
 * somewhat differently.
 * </p>
 */
public class Digester
    extends DefaultHandler
{

    // --------------------------------------------------------- Constructors

    /**
     * Construct a new Digester with default properties.
     */
    public Digester()
    {
    }

    /**
     * Construct a new Digester, allowing a SAXParser to be passed in. This allows Digester to be used in environments
     * which are unfriendly to JAXP1.1 (such as WebLogic 6.0). This may help in places where you are able to load JAXP
     * 1.1 classes yourself.
     *
     * @param parser The SAXParser used to parse XML streams
     */
    public Digester( final SAXParser parser )
    {
        this.parser = parser;
    }

    /**
     * Construct a new Digester, allowing an XMLReader to be passed in. This allows Digester to be used in environments
     * which are unfriendly to JAXP1.1 (such as WebLogic 6.0). Note that if you use this option you have to configure
     * namespace and validation support yourself, as these properties only affect the SAXParser and emtpy constructor.
     *
     * @param reader The XMLReader used to parse XML streams
     */
    public Digester( final XMLReader reader )
    {
        this.reader = reader;
    }

    // --------------------------------------------------- Instance Variables

    /**
     * The body text of the current element.
     */
    private StringBuilder bodyText = new StringBuilder();

    /**
     * The stack of body text string buffers for surrounding elements.
     */
    private final Stack<StringBuilder> bodyTexts = new Stack<StringBuilder>();

    /**
     * Stack whose elements are List objects, each containing a list of Rule objects as returned from Rules.getMatch().
     * As each xml element in the input is entered, the matching rules are pushed onto this stack. After the end tag is
     * reached, the matches are popped again. The depth of is stack is therefore exactly the same as the current
     * "nesting" level of the input xml.
     *
     * @since 1.6
     */
    private final Stack<List<Rule>> matches = new Stack<List<Rule>>();

    /**
     * The class loader to use for instantiating application objects. If not specified, the context class loader, or the
     * class loader used to load Digester itself, is used, based on the value of the <code>useContextClassLoader</code>
     * variable.
     */
    private ClassLoader classLoader = null;

    /**
     * Has this Digester been configured yet.
     */
    private boolean configured = false;

    /**
     * The EntityResolver used by the SAX parser. By default it use this class
     */
    private EntityResolver entityResolver;

    /**
     * The URLs of entityValidator that have been registered, keyed by the public identifier that corresponds.
     */
    private final HashMap<String, URL> entityValidator = new HashMap<String, URL>();

    /**
     * The application-supplied error handler that is notified when parsing warnings, errors, or fatal errors occur.
     */
    private ErrorHandler errorHandler = null;

    /**
     * The SAXParserFactory that is created the first time we need it.
     */
    private SAXParserFactory factory = null;

    /**
     * The Locator associated with our parser.
     */
    private Locator locator = null;

    /**
     * The current match pattern for nested element processing.
     */
    private String match = "";

    /**
     * Do we want a "namespace aware" parser.
     */
    private boolean namespaceAware = false;

    /**
     * The executor service to run asynchronous parse method.
     * @since 3.1
     */
    private ExecutorService executorService;

    /**
     * Registered namespaces we are currently processing. The key is the namespace prefix that was declared in the
     * document. The value is an Stack of the namespace URIs this prefix has been mapped to -- the top Stack element is
     * the most current one. (This architecture is required because documents can declare nested uses of the same prefix
     * for different Namespace URIs).
     */
    private final HashMap<String, Stack<String>> namespaces = new HashMap<String, Stack<String>>();

    /**
     * Do we want a "XInclude aware" parser.
     */
    private boolean xincludeAware = false;

    /**
     * The parameters stack being utilized by CallMethodRule and CallParamRule rules.
     *
     * @since 2.0
     */
    private final Stack<Object[]> params = new Stack<Object[]>();

    /**
     * The SAXParser we will use to parse the input stream.
     */
    private SAXParser parser = null;

    /**
     * The public identifier of the DTD we are currently parsing under (if any).
     */
    private String publicId = null;

    /**
     * The XMLReader used to parse digester rules.
     */
    private XMLReader reader = null;

    /**
     * The "root" element of the stack (in other words, the last object that was popped.
     */
    private Object root = null;

    /**
     * The <code>Rules</code> implementation containing our collection of <code>Rule</code> instances and associated
     * matching policy. If not established before the first rule is added, a default implementation will be provided.
     */
    private Rules rules = null;

    /**
     * The XML schema to use for validating an XML instance.
     *
     * @since 2.0
     */
    private Schema schema = null;

    /**
     * The object stack being constructed.
     */
    private final Stack<Object> stack = new Stack<Object>();

    /**
     * Do we want to use the Context ClassLoader when loading classes for instantiating new objects. Default is
     * <code>true</code>.
     */
    private boolean useContextClassLoader = true;

    /**
     * Do we want to use a validating parser.
     */
    private boolean validating = false;

    /**
     * The Log to which most logging calls will be made.
     */
    private Log log = LogFactory.getLog( "org.apache.commons.digester3.Digester" );

    /**
     * The Log to which all SAX event related logging calls will be made.
     */
    private Log saxLog = LogFactory.getLog( "org.apache.commons.digester3.Digester.sax" );

    /**
     * The schema language supported. By default, we use this one.
     */
    protected static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";

    /**
     * An optional class that substitutes values in attributes and body text. This may be null and so a null check is
     * always required before use.
     */
    private Substitutor substitutor;

    /** Stacks used for interrule communication, indexed by name String */
    private final HashMap<String, Stack<Object>> stacksByName = new HashMap<String, Stack<Object>>();

    /**
     * If not null, then calls by the parser to this object's characters, startElement, endElement and
     * processingInstruction methods are forwarded to the specified object. This is intended to allow rules to
     * temporarily "take control" of the sax events. In particular, this is used by NodeCreateRule.
     * <p>
     * See setCustomContentHandler.
     */
    private ContentHandler customContentHandler = null;

    /**
     * Object which will receive callbacks for every pop/push action on the default stack or named stacks.
     */
    private StackAction stackAction = null;

    // ------------------------------------------------------------- Properties

    /**
     * Return the currently mapped namespace URI for the specified prefix, if any; otherwise return <code>null</code>.
     * These mappings come and go dynamically as the document is parsed.
     *
     * @param prefix Prefix to look up
     * @return the currently mapped namespace URI for the specified prefix
     */
    public String findNamespaceURI( final String prefix )
    {
        final Stack<String> nsStack = namespaces.get( prefix );
        if ( nsStack == null )
        {
            return null;
        }
        try
        {
            return ( nsStack.peek() );
        }
        catch ( final EmptyStackException e )
        {
            return null;
        }
    }

    /**
     * Return the class loader to be used for instantiating application objects when required. This is determined based
     * upon the following rules:
     * <ul>
     * <li>The class loader set by <code>setClassLoader()</code>, if any</li>
     * <li>The thread context class loader, if it exists and the <code>useContextClassLoader</code> property is set to
     * true</li>
     * <li>The class loader used to load the Digester class itself.
     * </ul>
     *
     * @return the class loader to be used for instantiating application objects.
     */
    public ClassLoader getClassLoader()
    {
        if ( this.classLoader != null )
        {
            return ( this.classLoader );
        }
        if ( this.useContextClassLoader )
        {
            final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            if ( classLoader != null )
            {
                return ( classLoader );
            }
        }
        return ( this.getClass().getClassLoader() );
    }

    /**
     * Set the class loader to be used for instantiating application objects when required.
     *
     * @param classLoader The new class loader to use, or <code>null</code> to revert to the standard rules
     */
    public void setClassLoader( final ClassLoader classLoader )
    {
        this.classLoader = classLoader;
    }

    /**
     * Return the current depth of the element stack.
     *
     * @return the current depth of the element stack.
     */
    public int getCount()
    {
        return ( stack.size() );
    }

    /**
     * Return the name of the XML element that is currently being processed.
     *
     * @return the name of the XML element that is currently being processed.
     */
    public String getCurrentElementName()
    {
        String elementName = match;
        final int lastSlash = elementName.lastIndexOf( '/' );
        if ( lastSlash >= 0 )
        {
            elementName = elementName.substring( lastSlash + 1 );
        }
        return ( elementName );
    }

    /**
     * Return the error handler for this Digester.
     *
     * @return the error handler for this Digester.
     */
    public ErrorHandler getErrorHandler()
    {
        return ( this.errorHandler );
    }

    /**
     * Set the error handler for this Digester.
     *
     * @param errorHandler The new error handler
     */
    public void setErrorHandler( final ErrorHandler errorHandler )
    {
        this.errorHandler = errorHandler;
    }

    /**
     * Return the SAXParserFactory we will use, creating one if necessary.
     *
     * @return the SAXParserFactory we will use, creating one if necessary.
     */
    public SAXParserFactory getFactory()
    {
        if ( factory == null )
        {
            factory = SAXParserFactory.newInstance();
            factory.setNamespaceAware( namespaceAware );
            factory.setXIncludeAware( xincludeAware );
            factory.setValidating( validating );
            factory.setSchema( schema );
        }
        return ( factory );
    }

    /**
     * Returns a flag indicating whether the requested feature is supported by the underlying implementation of
     * <code>org.xml.sax.XMLReader</code>. See <a href="http://www.saxproject.org">the saxproject website</a> for
     * information about the standard SAX2 feature flags.
     *
     * @param feature Name of the feature to inquire about
     * @return true, if the requested feature is supported by the underlying implementation of
     *         <code>org.xml.sax.XMLReader</code>, false otherwise
     * @throws ParserConfigurationException if a parser configuration error occurs
     * @throws SAXNotRecognizedException if the property name is not recognized
     * @throws SAXNotSupportedException if the property name is recognized but not supported
     */
    public boolean getFeature( final String feature )
        throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException
    {
        return ( getFactory().getFeature( feature ) );
    }

    /**
     * Sets a flag indicating whether the requested feature is supported by the underlying implementation of
     * <code>org.xml.sax.XMLReader</code>. See <a href="http://www.saxproject.org">the saxproject website</a> for
     * information about the standard SAX2 feature flags. In order to be effective, this method must be called
     * <strong>before</strong> the <code>getParser()</code> method is called for the first time, either directly or
     * indirectly.
     *
     * @param feature Name of the feature to set the status for
     * @param value The new value for this feature
     * @throws ParserConfigurationException if a parser configuration error occurs
     * @throws SAXNotRecognizedException if the property name is not recognized
     * @throws SAXNotSupportedException if the property name is recognized but not supported
     */
    public void setFeature( final String feature, final boolean value )
        throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException
    {
        getFactory().setFeature( feature, value );
    }

    /**
     * Return the current Logger associated with this instance of the Digester
     *
     * @return the current Logger associated with this instance of the Digester
     */
    public Log getLogger()
    {
        return log;
    }

    /**
     * Set the current logger for this Digester.
     *
     * @param log the current logger for this Digester.
     */
    public void setLogger( final Log log )
    {
        this.log = log;
    }

    /**
     * Gets the logger used for logging SAX-related information. <strong>Note</strong> the output is finely grained.
     *
     * @return the logger used for logging SAX-related information
     * @since 1.6
     */
    public Log getSAXLogger()
    {
        return saxLog;
    }

    /**
     * Sets the logger used for logging SAX-related information. <strong>Note</strong> the output is finely grained.
     *
     * @param saxLog the logger used for logging SAX-related information, not null
     * @since 1.6
     */
    public void setSAXLogger( final Log saxLog )
    {
        this.saxLog = saxLog;
    }

    /**
     * Return the current rule match path
     *
     * @return the current rule match path
     */
    public String getMatch()
    {
        return match;
    }

    /**
     * Return a Stack whose elements are List objects, each containing a list of
     * Rule objects as returned from Rules.getMatch().
     *
     * @return a Stack whose elements are List objects, each containing a list of
     *         Rule objects as returned from Rules.getMatch().
     * @since 3.0
     */
    public Stack<List<Rule>> getMatches()
    {
        return matches;
    }

    /**
     * Return the "namespace aware" flag for parsers we create.
     *
     * @return the "namespace aware" flag for parsers we create.
     */
    public boolean getNamespaceAware()
    {
        return ( this.namespaceAware );
    }

    /**
     * Set the "namespace aware" flag for parsers we create.
     *
     * @param namespaceAware The new "namespace aware" flag
     */
    public void setNamespaceAware( final boolean namespaceAware )
    {
        this.namespaceAware = namespaceAware;
    }

    /**
     * Return the XInclude-aware flag for parsers we create. XInclude functionality additionally requires
     * namespace-awareness.
     *
     * @return The XInclude-aware flag
     * @see #getNamespaceAware()
     * @since 2.0
     */
    public boolean getXIncludeAware()
    {
        return ( this.xincludeAware );
    }

    /**
     * Set the XInclude-aware flag for parsers we create. This additionally requires namespace-awareness.
     *
     * @param xincludeAware The new XInclude-aware flag
     * @see #setNamespaceAware(boolean)
     * @since 2.0
     */
    public void setXIncludeAware( final boolean xincludeAware )
    {
        this.xincludeAware = xincludeAware;
    }

    /**
     * Set the public id of the current file being parse.
     *
     * @param publicId the DTD/Schema public's id.
     */
    public void setPublicId( final String publicId )
    {
        this.publicId = publicId;
    }

    /**
     * Return the public identifier of the DTD we are currently parsing under, if any.
     *
     * @return the public identifier of the DTD we are currently parsing under, if any.
     */
    public String getPublicId()
    {
        return ( this.publicId );
    }

    /**
     * Return the namespace URI that will be applied to all subsequently added <code>Rule</code> objects.
     *
     * @return the namespace URI that will be applied to all subsequently added <code>Rule</code> objects.
     */
    public String getRuleNamespaceURI()
    {
        return ( getRules().getNamespaceURI() );
    }

    /**
     * Set the namespace URI that will be applied to all subsequently added <code>Rule</code> objects.
     *
     * @param ruleNamespaceURI Namespace URI that must match on all subsequently added rules, or <code>null</code> for
     *            matching regardless of the current namespace URI
     */
    public void setRuleNamespaceURI( final String ruleNamespaceURI )
    {
        getRules().setNamespaceURI( ruleNamespaceURI );
    }

    /**
     * Return the SAXParser we will use to parse the input stream.
     *
     * If there is a problem creating the parser, return <code>null</code>.
     *
     * @return the SAXParser we will use to parse the input stream
     */
    public SAXParser getParser()
    {
        // Return the parser we already created (if any)
        if ( parser != null )
        {
            return ( parser );
        }

        // Create a new parser
        try
        {
            parser = getFactory().newSAXParser();
        }
        catch ( final Exception e )
        {
            log.error( "Digester.getParser: ", e );
            return ( null );
        }

        return ( parser );
    }

    /**
     * Return the current value of the specified property for the underlying <code>XMLReader</code> implementation.
     *
     * See <a href="http://www.saxproject.org">the saxproject website</a> for information about the standard SAX2
     * properties.
     *
     * @param property Property name to be retrieved
     * @return the current value of the specified property for the underlying <code>XMLReader</code> implementation.
     * @throws SAXNotRecognizedException if the property name is not recognized
     * @throws SAXNotSupportedException if the property name is recognized but not supported
     */
    public Object getProperty( final String property )
        throws SAXNotRecognizedException, SAXNotSupportedException
    {
        return ( getParser().getProperty( property ) );
    }

    /**
     * Set the current value of the specified property for the underlying <code>XMLReader</code> implementation. See <a
     * href="http://www.saxproject.org">the saxproject website</a> for information about the standard SAX2 properties.
     *
     * @param property Property name to be set
     * @param value Property value to be set
     * @throws SAXNotRecognizedException if the property name is not recognized
     * @throws SAXNotSupportedException if the property name is recognized but not supported
     */
    public void setProperty( final String property, final Object value )
        throws SAXNotRecognizedException, SAXNotSupportedException
    {
        getParser().setProperty( property, value );
    }

    /**
     * Return the <code>Rules</code> implementation object containing our rules collection and associated matching
     * policy. If none has been established, a default implementation will be created and returned.
     *
     * @return the <code>Rules</code> implementation object.
     */
    public Rules getRules()
    {
        if ( this.rules == null )
        {
            this.rules = new RulesBase();
            this.rules.setDigester( this );
        }
        return ( this.rules );
    }

    /**
     * Set the <code>Rules</code> implementation object containing our rules collection and associated matching policy.
     *
     * @param rules New Rules implementation
     */
    public void setRules( final Rules rules )
    {
        this.rules = rules;
        this.rules.setDigester( this );
    }

    /**
     * Return the XML Schema used when parsing.
     *
     * @return The {@link Schema} instance in use.
     * @since 2.0
     */
    public Schema getXMLSchema()
    {
        return ( this.schema );
    }

    /**
     * Set the XML Schema to be used when parsing.
     *
     * @param schema The {@link Schema} instance to use.
     * @since 2.0
     */
    public void setXMLSchema( final Schema schema )
    {
        this.schema = schema;
    }

    /**
     * Return the boolean as to whether the context ClassLoader should be used.
     *
     * @return true, if the context ClassLoader should be used, false otherwise.
     */
    public boolean getUseContextClassLoader()
    {
        return useContextClassLoader;
    }

    /**
     * Determine whether to use the Context ClassLoader (the one found by calling
     * <code>Thread.currentThread().getContextClassLoader()</code>) to resolve/load classes that are defined in various
     * rules. If not using Context ClassLoader, then the class-loading defaults to using the calling-class' ClassLoader.
     *
     * @param use determines whether to use Context ClassLoader.
     */
    public void setUseContextClassLoader( final boolean use )
    {
        useContextClassLoader = use;
    }

    /**
     * Return the validating parser flag.
     *
     * @return the validating parser flag.
     */
    public boolean getValidating()
    {
        return ( this.validating );
    }

    /**
     * Set the validating parser flag. This must be called before <code>parse()</code> is called the first time.
     * By default the value of this is set to false.
     *
     * It essentially just controls the DTD validation. To use modern schema languages use the
     * {@link #setXMLSchema(Schema)} method to associate a schema to a parser.
     *
     * @param validating The new validating parser flag.
     * @see javax.xml.parsers.SAXParserFactory#setValidating(boolean) for more detail.
     */
    public void setValidating( final boolean validating )
    {
        this.validating = validating;
    }

    /**
     * Return the XMLReader to be used for parsing the input document.
     *
     * FIXME: there is a bug in JAXP/XERCES that prevent the use of a parser that contains a schema with a DTD.
     *
     * @return the XMLReader to be used for parsing the input document.
     * @throws SAXException if no XMLReader can be instantiated
     */
    public XMLReader getXMLReader()
        throws SAXException
    {
        if ( reader == null )
        {
            reader = getParser().getXMLReader();
        }

        reader.setDTDHandler( this );
        reader.setContentHandler( this );

        if ( entityResolver == null )
        {
            reader.setEntityResolver( this );
        }
        else
        {
            reader.setEntityResolver( entityResolver );
        }

        if ( this.errorHandler != null )
        {
            reader.setErrorHandler( this.errorHandler );
        }
        else
        {
            reader.setErrorHandler( this );
        }

        return reader;
    }

    /**
     * Gets the <code>Substitutor</code> used to convert attributes and body text.
     *
     * @return the <code>Substitutor</code> used to convert attributes and body text,
     *         null if not substitutions are to be performed.
     */
    public Substitutor getSubstitutor()
    {
        return substitutor;
    }

    /**
     * Sets the <code>Substitutor</code> to be used to convert attributes and body text.
     *
     * @param substitutor the Substitutor to be used to convert attributes and body text or null if not substitution of
     *            these values is to be performed.
     */
    public void setSubstitutor( final Substitutor substitutor )
    {
        this.substitutor = substitutor;
    }

    /**
     * returns the custom SAX ContentHandler where events are redirected.
     *
     * @return the custom SAX ContentHandler where events are redirected.
     * @see #setCustomContentHandler(ContentHandler)
     * @since 1.7
     */
    public ContentHandler getCustomContentHandler()
    {
        return customContentHandler;
    }

    /**
     * Redirects (or cancels redirecting) of SAX ContentHandler events to an external object.
     * <p>
     * When this object's customContentHandler is non-null, any SAX events received from the parser will simply be
     * passed on to the specified object instead of this object handling them. This allows Rule classes to take control
     * of the SAX event stream for a while in order to do custom processing. Such a rule should save the old value
     * before setting a new one, and restore the old value in order to resume normal digester processing.
     * <p>
     * An example of a Rule which needs this feature is NodeCreateRule.
     * <p>
     * Note that saving the old value is probably not needed as it should always be null; a custom rule that wants to
     * take control could only have been called when there was no custom content handler. But it seems cleaner to
     * properly save/restore the value and maybe some day this will come in useful.
     * <p>
     * Note also that this is not quite equivalent to
     *
     * <pre>
     * digester.getXMLReader().setContentHandler( handler )
     * </pre>
     *
     * for these reasons:
     * <ul>
     * <li>Some xml parsers don't like having setContentHandler called after parsing has started. The Aelfred parser is
     * one example.</li>
     * <li>Directing the events via the Digester object potentially allows us to log information about those SAX events
     * at the digester level.</li>
     * </ul>
     *
     * @param handler the custom SAX ContentHandler where events are redirected.
     * @since 1.7
     */
    public void setCustomContentHandler( final ContentHandler handler )
    {
        customContentHandler = handler;
    }

    /**
     * Define a callback object which is invoked whenever an object is pushed onto a digester object stack,
     * or popped off one.
     *
     * @param stackAction the callback object which is invoked whenever an object is pushed onto a digester
     *        object stack, or popped off one.
     * @since 1.8
     */
    public void setStackAction( final StackAction stackAction )
    {
        this.stackAction = stackAction;
    }

    /**
     * Return the callback object which is invoked whenever an object is pushed onto a digester object stack,
     * or popped off one.
     *
     * @return the callback object which is invoked whenever an object is pushed onto a digester object stack,
     *         or popped off one.
     * @see #setStackAction(StackAction)
     * @since 1.8
     */
    public StackAction getStackAction()
    {
        return stackAction;
    }

    /**
     * Get the most current namespaces for all prefixes.
     *
     * @return Map A map with namespace prefixes as keys and most current namespace URIs for the corresponding prefixes
     *         as values
     * @since 1.8
     */
    public Map<String, String> getCurrentNamespaces()
    {
        if ( !namespaceAware )
        {
            log.warn( "Digester is not namespace aware" );
        }
        final Map<String, String> currentNamespaces = new HashMap<String, String>();
        for ( final Map.Entry<String, Stack<String>> nsEntry : namespaces.entrySet() )
        {
            try
            {
                currentNamespaces.put( nsEntry.getKey(), nsEntry.getValue().peek() );
            }
            catch ( final RuntimeException e )
            {
                // rethrow, after logging
                log.error( e.getMessage(), e );
                throw e;
            }
        }
        return currentNamespaces;
    }

    /**
     * Returns the executor service used to run asynchronous parse method.
     *
     * @return the executor service used to run asynchronous parse method
     * @since 3.1
     */
    public ExecutorService getExecutorService()
    {
        return executorService;
    }

    /**
     * Sets the executor service to run asynchronous parse method.
     *
     * @param executorService the executor service to run asynchronous parse method
     * @since 3.1
     */
    public void setExecutorService( final ExecutorService executorService )
    {
        this.executorService = executorService;
    }

    // ------------------------------------------------- ContentHandler Methods

    /**
     * {@inheritDoc}
     */
    @Override
    public void characters( final char buffer[], final int start, final int length )
        throws SAXException
    {
        if ( customContentHandler != null )
        {
            // forward calls instead of handling them here
            customContentHandler.characters( buffer, start, length );
            return;
        }

        if ( saxLog.isDebugEnabled() )
        {
            saxLog.debug( "characters(" + new String( buffer, start, length ) + ")" );
        }

        bodyText.append( buffer, start, length );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void endDocument()
        throws SAXException
    {
        if ( saxLog.isDebugEnabled() )
        {
            if ( getCount() > 1 )
            {
                saxLog.debug( "endDocument():  " + getCount() + " elements left" );
            }
            else
            {
                saxLog.debug( "endDocument()" );
            }
        }

        // Fire "finish" events for all defined rules
        for ( final Rule rule : getRules().rules() )
        {
            try
            {
                rule.finish();
            }
            catch ( final Exception e )
            {
                log.error( "Finish event threw exception", e );
                throw createSAXException( e );
            }
            catch ( final Error e )
            {
                log.error( "Finish event threw error", e );
                throw e;
            }
        }

        // Perform final cleanup
        clear();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void endElement( final String namespaceURI, final String localName, final String qName )
        throws SAXException
    {
        if ( customContentHandler != null )
        {
            // forward calls instead of handling them here
            customContentHandler.endElement( namespaceURI, localName, qName );
            return;
        }

        final boolean debug = log.isDebugEnabled();

        if ( debug )
        {
            if ( saxLog.isDebugEnabled() )
            {
                saxLog.debug( "endElement(" + namespaceURI + "," + localName + "," + qName + ")" );
            }
            log.debug( "  match='" + match + "'" );
            log.debug( "  bodyText='" + bodyText + "'" );
        }

        // the actual element name is either in localName or qName, depending
        // on whether the parser is namespace aware
        String name = localName;
        if ( ( name == null ) || ( name.length() < 1 ) )
        {
            name = qName;
        }

        // Fire "body" events for all relevant rules
        final List<Rule> rules = matches.pop();
        if ( ( rules != null ) && ( !rules.isEmpty() ) )
        {
            String bodyText = this.bodyText.toString();
            final Substitutor substitutor = getSubstitutor();
            if ( substitutor != null )
            {
                bodyText = substitutor.substitute( bodyText );
            }
            for (final Rule rule : rules) {
                try
                {
                    if ( debug )
                    {
                        log.debug( "  Fire body() for " + rule );
                    }
                    rule.body( namespaceURI, name, bodyText );
                }
                catch ( final Exception e )
                {
                    log.error( "Body event threw exception", e );
                    throw createSAXException( e );
                }
                catch ( final Error e )
                {
                    log.error( "Body event threw error", e );
                    throw e;
                }
            }
        }
        else
        {
            if ( debug )
            {
                log.debug( "  No rules found matching '" + match + "'." );
            }
        }

        // Recover the body text from the surrounding element
        bodyText = bodyTexts.pop();
        if ( debug )
        {
            log.debug( "  Popping body text '" + bodyText.toString() + "'" );
        }

        // Fire "end" events for all relevant rules in reverse order
        if ( rules != null )
        {
            for ( int i = 0; i < rules.size(); i++ )
            {
                final int j = ( rules.size() - i ) - 1;
                try
                {
                    final Rule rule = rules.get( j );
                    if ( debug )
                    {
                        log.debug( "  Fire end() for " + rule );
                    }
                    rule.end( namespaceURI, name );
                }
                catch ( final Exception e )
                {
                    log.error( "End event threw exception", e );
                    throw createSAXException( e );
                }
                catch ( final Error e )
                {
                    log.error( "End event threw error", e );
                    throw e;
                }
            }
        }

        // Recover the previous match expression
        final int slash = match.lastIndexOf( '/' );
        if ( slash >= 0 )
        {
            match = match.substring( 0, slash );
        }
        else
        {
            match = "";
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void endPrefixMapping( final String prefix )
        throws SAXException
    {
        if ( saxLog.isDebugEnabled() )
        {
            saxLog.debug( "endPrefixMapping(" + prefix + ")" );
        }

        // Deregister this prefix mapping
        final Stack<String> stack = namespaces.get( prefix );
        if ( stack == null )
        {
            return;
        }
        try
        {
            stack.pop();
            if ( stack.empty() )
            {
                namespaces.remove( prefix );
            }
        }
        catch ( final EmptyStackException e )
        {
            throw createSAXException( "endPrefixMapping popped too many times" );
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void ignorableWhitespace( final char buffer[], final int start, final int len )
        throws SAXException
    {
        if ( saxLog.isDebugEnabled() )
        {
            saxLog.debug( "ignorableWhitespace(" + new String( buffer, start, len ) + ")" );
        }

        // No processing required
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void processingInstruction( final String target, final String data )
        throws SAXException
    {
        if ( customContentHandler != null )
        {
            // forward calls instead of handling them here
            customContentHandler.processingInstruction( target, data );
            return;
        }

        if ( saxLog.isDebugEnabled() )
        {
            saxLog.debug( "processingInstruction('" + target + "','" + data + "')" );
        }

        // No processing is required
    }

    /**
     * Gets the document locator associated with our parser.
     *
     * @return the Locator supplied by the document parser
     */
    public Locator getDocumentLocator()
    {
        return locator;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setDocumentLocator( final Locator locator )
    {
        if ( saxLog.isDebugEnabled() )
        {
            saxLog.debug( "setDocumentLocator(" + locator + ")" );
        }

        this.locator = locator;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void skippedEntity( final String name )
        throws SAXException
    {
        if ( saxLog.isDebugEnabled() )
        {
            saxLog.debug( "skippedEntity(" + name + ")" );
        }

        // No processing required
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void startDocument()
        throws SAXException
    {
        if ( saxLog.isDebugEnabled() )
        {
            saxLog.debug( "startDocument()" );
        }

        // ensure that the digester is properly configured, as
        // the digester could be used as a SAX ContentHandler
        // rather than via the parse() methods.
        configure();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void startElement( final String namespaceURI, final String localName, final String qName, Attributes list )
        throws SAXException
    {
        final boolean debug = log.isDebugEnabled();

        if ( customContentHandler != null )
        {
            // forward calls instead of handling them here
            customContentHandler.startElement( namespaceURI, localName, qName, list );
            return;
        }

        if ( saxLog.isDebugEnabled() )
        {
            saxLog.debug( "startElement(" + namespaceURI + "," + localName + "," + qName + ")" );
        }

        // Save the body text accumulated for our surrounding element
        bodyTexts.push( bodyText );
        if ( debug )
        {
            log.debug( "  Pushing body text '" + bodyText.toString() + "'" );
        }
        bodyText = new StringBuilder();

        // the actual element name is either in localName or qName, depending
        // on whether the parser is namespace aware
        String name = localName;
        if ( ( name == null ) || ( name.length() < 1 ) )
        {
            name = qName;
        }

        // Compute the current matching rule
        final StringBuilder sb = new StringBuilder( match );
        if ( !match.isEmpty() )
        {
            sb.append( '/' );
        }
        sb.append( name );
        match = sb.toString();
        if ( debug )
        {
            log.debug( "  New match='" + match + "'" );
        }

        // Fire "begin" events for all relevant rules
        final List<Rule> rules = getRules().match( namespaceURI, match, localName, list );
        matches.push( rules );
        if ( ( rules != null ) && ( !rules.isEmpty() ) )
        {
            final Substitutor substitutor = getSubstitutor();
            if ( substitutor != null )
            {
                list = substitutor.substitute( list );
            }
            for (final Rule rule : rules) {
                try
                {
                    if ( debug )
                    {
                        log.debug( "  Fire begin() for " + rule );
                    }
                    rule.begin( namespaceURI, name, list );
                }
                catch ( final Exception e )
                {
                    log.error( "Begin event threw exception", e );
                    throw createSAXException( e );
                }
                catch ( final Error e )
                {
                    log.error( "Begin event threw error", e );
                    throw e;
                }
            }
        }
        else
        {
            if ( debug )
            {
                log.debug( "  No rules found matching '" + match + "'." );
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void startPrefixMapping( final String prefix, final String namespaceURI )
        throws SAXException
    {
        if ( saxLog.isDebugEnabled() )
        {
            saxLog.debug( "startPrefixMapping(" + prefix + "," + namespaceURI + ")" );
        }

        // Register this prefix mapping
        Stack<String> stack = namespaces.get( prefix );
        if ( stack == null )
        {
            stack = new Stack<String>();
            namespaces.put( prefix, stack );
        }
        stack.push( namespaceURI );
    }

    // ----------------------------------------------------- DTDHandler Methods

    /**
     * {@inheritDoc}
     */
    @Override
    public void notationDecl( final String name, final String publicId, final String systemId )
    {
        if ( saxLog.isDebugEnabled() )
        {
            saxLog.debug( "notationDecl(" + name + "," + publicId + "," + systemId + ")" );
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void unparsedEntityDecl( final String name, final String publicId, final String systemId, final String notation )
    {
        if ( saxLog.isDebugEnabled() )
        {
            saxLog.debug( "unparsedEntityDecl(" + name + "," + publicId + "," + systemId + "," + notation + ")" );
        }
    }

    // ----------------------------------------------- EntityResolver Methods

    /**
     * Set the <code>EntityResolver</code> used by SAX when resolving public id and system id. This must be called
     * before the first call to <code>parse()</code>.
     *
     * @param entityResolver a class that implement the <code>EntityResolver</code> interface.
     */
    public void setEntityResolver( final EntityResolver entityResolver )
    {
        this.entityResolver = entityResolver;
    }

    /**
     * Return the Entity Resolver used by the SAX parser.
     *
     * @return the Entity Resolver used by the SAX parser.
     */
    public EntityResolver getEntityResolver()
    {
        return entityResolver;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public InputSource resolveEntity( final String publicId, final String systemId )
        throws SAXException
    {
        if ( saxLog.isDebugEnabled() )
        {
            saxLog.debug( "resolveEntity('" + publicId + "', '" + systemId + "')" );
        }

        if ( publicId != null )
        {
            this.publicId = publicId;
        }

        // Has this system identifier been registered?
        URL entityURL = null;
        if ( publicId != null )
        {
            entityURL = entityValidator.get( publicId );
        }

        // Redirect the schema location to a local destination
        if ( entityURL == null && systemId != null )
        {
            entityURL = entityValidator.get( systemId );
        }

        if ( entityURL == null )
        {
            if ( systemId == null )
            {
                // cannot resolve
                if ( log.isDebugEnabled() )
                {
                    log.debug( " Cannot resolve null entity, returning null InputSource" );
                }
                return ( null );

            }
            // try to resolve using system ID
            if ( log.isDebugEnabled() )
            {
                log.debug( " Trying to resolve using system ID '" + systemId + "'" );
            }
            try
            {
                entityURL = new URL( systemId );
            }
            catch ( final MalformedURLException e )
            {
                throw new IllegalArgumentException( "Malformed URL '" + systemId + "' : " + e.getMessage() );
            }
        }

        // Return an input source to our alternative URL
        if ( log.isDebugEnabled() )
        {
            log.debug( " Resolving to alternate DTD '" + entityURL + "'" );
        }

        try
        {
            return createInputSourceFromURL( entityURL );
        }
        catch ( final Exception e )
        {
            throw createSAXException( e );
        }
    }

    // ------------------------------------------------- ErrorHandler Methods

    /**
     * {@inheritDoc}
     */
    @Override
    public void error( final SAXParseException exception )
        throws SAXException
    {
    	log.error( "Parse Error at line " + exception.getLineNumber() + " column " + exception.getColumnNumber() + ": "
                + exception.getMessage(), exception );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void fatalError( final SAXParseException exception )
        throws SAXException
    {
        log.error( "Parse Fatal Error at line " + exception.getLineNumber() + " column " + exception.getColumnNumber()
                + ": " + exception.getMessage(), exception );
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void warning( final SAXParseException exception )
        throws SAXException
    {
        log.warn( "Parse Warning Error at line " + exception.getLineNumber() + " column "
                + exception.getColumnNumber() + ": " + exception.getMessage(), exception );
    }

    // ------------------------------------------------------- Public Methods

    /**
     * Parse the content of the specified file using this Digester. Returns the root element from the object stack (if
     * any).
     *
     * @param <T> the type used to auto-cast the returned object to the assigned variable type
     * @param file File containing the XML data to be parsed
     * @return the root element from the object stack (if any)
     * @throws IOException if an input/output error occurs
     * @throws SAXException if a parsing exception occurs
     */
    public <T> T parse( final File file )
        throws IOException, SAXException
    {
        if ( file == null )
        {
            throw new IllegalArgumentException( "File to parse is null" );
        }

        final InputSource input = new InputSource( new FileInputStream( file ) );
        input.setSystemId( file.toURI().toURL().toString() );

        return ( this.<T> parse( input ) );
    }

    /**
     * Creates a Callable instance that parse the content of the specified reader using this Digester.
     *
     * @param <T> The result type returned by the returned Future's {@code get} method
     * @param file File containing the XML data to be parsed
     * @return a Future that can be used to track when the parse has been fully processed.
     * @see Digester#parse(File)
     * @since 3.1
     */
    public <T> Future<T> asyncParse( final File file )
    {
        return asyncParse( new Callable<T>()
        {

            @Override
            public T call()
                throws Exception
            {
                return Digester.this.<T> parse( file );
            }

        } );
    }

    /**
     * Parse the content of the specified input source using this Digester. Returns the root element from the object
     * stack (if any).
     *
     * @param <T> the type used to auto-cast the returned object to the assigned variable type
     * @param input Input source containing the XML data to be parsed
     * @return the root element from the object stack (if any)
     * @throws IOException if an input/output error occurs
     * @throws SAXException if a parsing exception occurs
     */
    public <T> T parse( final InputSource input )
        throws IOException, SAXException
    {
        if ( input == null )
        {
            throw new IllegalArgumentException( "InputSource to parse is null" );
        }

        configure();

        String systemId = input.getSystemId();
        if ( systemId == null )
        {
            systemId = "(already loaded from stream)";
        }

        try
        {
            getXMLReader().parse( input );
        }
        catch ( final IOException e )
        {
            log.error( format( "An error occurred while reading stream from '%s', see nested exceptions", systemId ),
                       e );
            throw e;
        }
        cleanup();
        return this.<T> getRoot();
    }

    /**
     * Creates a Callable instance that parse the content of the specified reader using this Digester.
     *
     * @param <T> The result type returned by the returned Future's {@code get} method
     * @param input Input source containing the XML data to be parsed
     * @return a Future that can be used to track when the parse has been fully processed.
     * @see Digester#parse(InputSource)
     * @since 3.1
     */
    public <T> Future<T> asyncParse( final InputSource input )
    {
        return asyncParse( new Callable<T>()
        {

            @Override
            public T call()
                throws Exception
            {
                return Digester.this.<T> parse( input );
            }

        } );
    }

    /**
     * Parse the content of the specified input stream using this Digester. Returns the root element from the object
     * stack (if any).
     *
     * @param <T> the type used to auto-cast the returned object to the assigned variable type
     * @param input Input stream containing the XML data to be parsed
     * @return the root element from the object stack (if any)
     * @throws IOException if an input/output error occurs
     * @throws SAXException if a parsing exception occurs
     */
    public <T> T parse( final InputStream input )
        throws IOException, SAXException
    {
        if ( input == null )
        {
            throw new IllegalArgumentException( "InputStream to parse is null" );
        }

        return ( this.<T> parse( new InputSource( input ) ) );
    }

    /**
     * Creates a Callable instance that parse the content of the specified reader using this Digester.
     *
     * @param <T> The result type returned by the returned Future's {@code get} method
     * @param input Input stream containing the XML data to be parsed
     * @return a Future that can be used to track when the parse has been fully processed.
     * @see Digester#parse(InputStream)
     * @since 3.1
     */
    public <T> Future<T> asyncParse( final InputStream input )
    {
        return asyncParse( new Callable<T>()
        {

            @Override
            public T call()
                throws Exception
            {
                return Digester.this.<T> parse( input );
            }

        } );
    }

    /**
     * Parse the content of the specified reader using this Digester. Returns the root element from the object stack (if
     * any).
     *
     * @param <T> the type used to auto-cast the returned object to the assigned variable type
     * @param reader Reader containing the XML data to be parsed
     * @return the root element from the object stack (if any)
     * @throws IOException if an input/output error occurs
     * @throws SAXException if a parsing exception occurs
     */
    public <T> T parse( final Reader reader )
        throws IOException, SAXException
    {
        if ( reader == null )
        {
            throw new IllegalArgumentException( "Reader to parse is null" );
        }

        return ( this.<T> parse( new InputSource( reader ) ) );
    }

    /**
     * Creates a Callable instance that parse the content of the specified reader using this Digester.
     *
     * @param <T> The result type returned by the returned Future's {@code get} method
     * @param reader Reader containing the XML data to be parsed
     * @return a Future that can be used to track when the parse has been fully processed.
     * @see Digester#parse(Reader)
     * @since 3.1
     */
    public <T> Future<T> asyncParse( final Reader reader )
    {
        return asyncParse( new Callable<T>()
        {

            @Override
            public T call()
                throws Exception
            {
                return Digester.this.<T> parse( reader );
            }

        } );
    }

    /**
     * Parse the content of the specified URI using this Digester. Returns the root element from the object stack (if
     * any).
     *
     * @param <T> the type used to auto-cast the returned object to the assigned variable type
     * @param uri URI containing the XML data to be parsed
     * @return the root element from the object stack (if any)
     * @throws IOException if an input/output error occurs
     * @throws SAXException if a parsing exception occurs
     */
    public <T> T parse( final String uri )
        throws IOException, SAXException
    {
        if ( uri == null )
        {
            throw new IllegalArgumentException( "String URI to parse is null" );
        }

        return ( this.<T> parse( createInputSourceFromURL( uri ) ) );
    }

    /**
     * Creates a Callable instance that parse the content of the specified reader using this Digester.
     *
     * @param <T> The result type returned by the returned Future's {@code get} method
     * @param uri URI containing the XML data to be parsed
     * @return a Future that can be used to track when the parse has been fully processed.
     * @see Digester#parse(String)
     * @since 3.1
     */
    public <T> Future<T> asyncParse( final String uri )
    {
        return asyncParse( new Callable<T>()
        {

            @Override
            public T call()
                throws Exception
            {
                return Digester.this.<T> parse( uri );
            }

        } );
    }

    /**
     * Parse the content of the specified URL using this Digester. Returns the root element from the object stack (if
     * any).
     *
     * @param <T> the type used to auto-cast the returned object to the assigned variable type
     * @param url URL containing the XML data to be parsed
     * @return the root element from the object stack (if any)
     * @throws IOException if an input/output error occurs
     * @throws SAXException if a parsing exception occurs
     * @since 1.8
     */
    public <T> T parse( final URL url )
        throws IOException, SAXException
    {
        if ( url == null )
        {
            throw new IllegalArgumentException( "URL to parse is null" );
        }

        return ( this.<T> parse( createInputSourceFromURL( url ) ) );
    }

    /**
     * Creates a Callable instance that parse the content of the specified reader using this Digester.
     *
     * @param <T> The result type returned by the returned Future's {@code get} method
     * @param url URL containing the XML data to be parsed
     * @return a Future that can be used to track when the parse has been fully processed.
     * @see Digester#parse(URL)
     * @since 3.1
     */
    public <T> Future<T> asyncParse( final URL url )
    {
        return asyncParse( new Callable<T>()
        {

            @Override
            public T call()
                throws Exception
            {
                return Digester.this.<T> parse( url );
            }

        } );
    }

    /**
     * Execute the parse in async mode.
     *
     * @param <T> the type used to auto-cast the returned object to the assigned variable type
     * @param callable
     * @return a Future that can be used to track when the parse has been fully processed.
     * @since 3.1
     */
    private <T> Future<T> asyncParse( final Callable<T> callable )
    {
        if ( executorService == null )
        {
            throw new IllegalStateException( "ExecutorService not set" );
        }

        return executorService.submit( callable );
    }

    /**
     * <p>
     * Register the specified DTD URL for the specified public identifier. This must be called before the first call to
     * <code>parse()</code>.
     * </p>
     * <p>
     * <code>Digester</code> contains an internal <code>EntityResolver</code> implementation. This maps
     * <code>PUBLICID</code>'s to URLs (from which the resource will be loaded). A common use case for this method is to
     * register local URLs (possibly computed at runtime by a classloader) for DTDs. This allows the performance
     * advantage of using a local version without having to ensure every <code>SYSTEM</code> URI on every processed xml
     * document is local. This implementation provides only basic functionality. If more sophisticated features are
     * required, using {@link #setEntityResolver} to set a custom resolver is recommended.
     * </p>
     * <p>
     * <strong>Note:</strong> This method will have no effect when a custom <code>EntityResolver</code> has been set.
     * (Setting a custom <code>EntityResolver</code> overrides the internal implementation.)
     * </p>
     *
     * @param publicId Public identifier of the DTD to be resolved
     * @param entityURL The URL to use for reading this DTD
     * @since 1.8
     */
    public void register( final String publicId, final URL entityURL )
    {
        if ( log.isDebugEnabled() )
        {
            log.debug( "register('" + publicId + "', '" + entityURL + "'" );
        }
        entityValidator.put( publicId, entityURL );
    }

    /**
     * <p>
     * Convenience method that registers the string version of an entity URL instead of a URL version.
     * </p>
     *
     * @param publicId Public identifier of the entity to be resolved
     * @param entityURL The URL to use for reading this entity
     */
    public void register( final String publicId, final String entityURL )
    {
        if ( log.isDebugEnabled() )
        {
            log.debug( "register('" + publicId + "', '" + entityURL + "'" );
        }
        try
        {
            entityValidator.put( publicId, new URL( entityURL ) );
        }
        catch ( final MalformedURLException e )
        {
            throw new IllegalArgumentException( "Malformed URL '" + entityURL + "' : " + e.getMessage() );
        }
    }

    /**
     * Convenience method that registers DTD URLs for the specified public identifiers.
     *
     * @param entityValidator The URLs of entityValidator that have been registered, keyed by the public
     *                        identifier that corresponds.
     * @since 3.0
     */
    public void registerAll( final Map<String, URL> entityValidator )
    {
        this.entityValidator.putAll( entityValidator );
    }

    /**
     * <p>
     * <code>List</code> of <code>InputSource</code> instances created by a <code>createInputSourceFromURL()</code>
     * method call. These represent open input streams that need to be closed to avoid resource leaks, as well as
     * potentially locked JAR files on Windows.
     * </p>
     */
    protected List<InputSource> inputSources = new ArrayList<InputSource>( 5 );

    /**
     * Given a URL, return an InputSource that reads from that URL.
     * <p>
     * Ideally this function would not be needed and code could just use <code>new InputSource(entityURL)</code>.
     * Unfortunately it appears that when the entityURL points to a file within a jar archive a caching mechanism inside
     * the InputSource implementation causes a file-handle to the jar file to remain open. On Windows systems this then
     * causes the jar archive file to be locked on disk ("in use") which makes it impossible to delete the jar file -
     * and that really stuffs up "undeploy" in webapps in particular.
     * <p>
     * In JDK1.4 and later, Apache XercesJ is used as the xml parser. The InputSource object provided is converted into
     * an XMLInputSource, and eventually passed to an instance of XMLDocumentScannerImpl to specify the source data to
     * be converted into tokens for the rest of the XMLReader code to handle. XMLDocumentScannerImpl calls
     * fEntityManager.startDocumentEntity(source), where fEntityManager is declared in ancestor class XMLScanner to be
     * an XMLEntityManager. In that class, if the input source stream is null, then:
     *
     * <pre>
     * URL location = new URL( expandedSystemId );
     * URLConnection connect = location.openConnection();
     * if ( connect instanceof HttpURLConnection )
     * {
     *     setHttpProperties( connect, xmlInputSource );
     * }
     * stream = connect.getInputStream();
     * </pre>
     *
     * This method pretty much duplicates the standard behavior, except that it calls URLConnection.setUseCaches(false)
     * before opening the connection.
     *
     * @param url The URL has to be read
     * @return The InputSource that reads from the input URL
     * @throws IOException if any error occurs while reading the input URL
     * @since 1.8
     */
    public InputSource createInputSourceFromURL( final URL url )
        throws IOException
    {
        final URLConnection connection = url.openConnection();
        connection.setUseCaches( false );
        final InputStream stream = connection.getInputStream();
        final InputSource source = new InputSource( stream );
        source.setSystemId( url.toExternalForm() );
        inputSources.add( source );
        return source;
    }

    /**
     * <p>
     * Convenience method that creates an <code>InputSource</code> from the string version of a URL.
     * </p>
     *
     * @param url URL for which to create an <code>InputSource</code>
     * @return The InputSource that reads from the input URL
     * @throws IOException if any error occurs while reading the input URL
     * @since 1.8
     */
    public InputSource createInputSourceFromURL( final String url )
        throws IOException
    {
        return createInputSourceFromURL( new URL( url ) );
    }

    // --------------------------------------------------------- Rule Methods

    /**
     * <p>
     * Register a new Rule matching the specified pattern. This method sets the <code>Digester</code> property on the
     * rule.
     * </p>
     *
     * @param pattern Element matching pattern
     * @param rule Rule to be registered
     */
    public void addRule( final String pattern, final Rule rule )
    {
        rule.setDigester( this );
        getRules().add( pattern, rule );
    }

    /**
     * Register a set of Rule instances defined in a RuleSet.
     *
     * @param ruleSet The RuleSet instance to configure from
     */
    public void addRuleSet( final RuleSet ruleSet )
    {
        final String oldNamespaceURI = getRuleNamespaceURI();
        final String newNamespaceURI = ruleSet.getNamespaceURI();
        if ( log.isDebugEnabled() )
        {
            if ( newNamespaceURI == null )
            {
                log.debug( "addRuleSet() with no namespace URI" );
            }
            else
            {
                log.debug( "addRuleSet() with namespace URI " + newNamespaceURI );
            }
        }
        setRuleNamespaceURI( newNamespaceURI );
        ruleSet.addRuleInstances( this );
        setRuleNamespaceURI( oldNamespaceURI );
    }

    /**
     * Add a "bean property setter" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @see BeanPropertySetterRule
     */
    public void addBeanPropertySetter( final String pattern )
    {
        addRule( pattern, new BeanPropertySetterRule() );
    }

    /**
     * Add a "bean property setter" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param propertyName Name of property to set
     * @see BeanPropertySetterRule
     */
    public void addBeanPropertySetter( final String pattern, final String propertyName )
    {
        addRule( pattern, new BeanPropertySetterRule( propertyName ) );
    }

    /**
     * Add an "call method" rule for a method which accepts no arguments.
     *
     * @param pattern Element matching pattern
     * @param methodName Method name to be called
     * @see CallMethodRule
     */
    public void addCallMethod( final String pattern, final String methodName )
    {
        addRule( pattern, new CallMethodRule( methodName ) );
    }

    /**
     * Add an "call method" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param methodName Method name to be called
     * @param paramCount Number of expected parameters (or zero for a single parameter from the body of this element)
     * @see CallMethodRule
     */
    public void addCallMethod( final String pattern, final String methodName, final int paramCount )
    {
        addRule( pattern, new CallMethodRule( methodName, paramCount ) );
    }

    /**
     * Add an "call method" rule for the specified parameters. If <code>paramCount</code> is set to zero the rule will
     * use the body of the matched element as the single argument of the method, unless <code>paramTypes</code> is null
     * or empty, in this case the rule will call the specified method with no arguments.
     *
     * @param pattern Element matching pattern
     * @param methodName Method name to be called
     * @param paramCount Number of expected parameters (or zero for a single parameter from the body of this element)
     * @param paramTypes Set of Java class names for the types of the expected parameters (if you wish to use a
     *            primitive type, specify the corresonding Java wrapper class instead, such as
     *            <code>java.lang.Boolean</code> for a <code>boolean</code> parameter)
     * @see CallMethodRule
     */
    public void addCallMethod( final String pattern, final String methodName, final int paramCount, final String paramTypes[] )
    {
        addRule( pattern, new CallMethodRule( methodName, paramCount, paramTypes ) );
    }

    /**
     * Add an "call method" rule for the specified parameters. If <code>paramCount</code> is set to zero the rule will
     * use the body of the matched element as the single argument of the method, unless <code>paramTypes</code> is null
     * or empty, in this case the rule will call the specified method with no arguments.
     *
     * @param pattern Element matching pattern
     * @param methodName Method name to be called
     * @param paramCount Number of expected parameters (or zero for a single parameter from the body of this element)
     * @param paramTypes The Java class names of the arguments (if you wish to use a primitive type, specify the
     *            corresonding Java wrapper class instead, such as <code>java.lang.Boolean</code> for a
     *            <code>boolean</code> parameter)
     * @see CallMethodRule
     */
    public void addCallMethod( final String pattern, final String methodName, final int paramCount, final Class<?> paramTypes[] )
    {
        addRule( pattern, new CallMethodRule( methodName, paramCount, paramTypes ) );
    }

    /**
     * Add a "call parameter" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param paramIndex Zero-relative parameter index to set (from the body of this element)
     * @see CallParamRule
     */
    public void addCallParam( final String pattern, final int paramIndex )
    {
        addRule( pattern, new CallParamRule( paramIndex ) );
    }

    /**
     * Add a "call parameter" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param paramIndex Zero-relative parameter index to set (from the specified attribute)
     * @param attributeName Attribute whose value is used as the parameter value
     * @see CallParamRule
     */
    public void addCallParam( final String pattern, final int paramIndex, final String attributeName )
    {
        addRule( pattern, new CallParamRule( paramIndex, attributeName ) );
    }

    /**
     * Add a "call parameter" rule. This will either take a parameter from the stack or from the current element body
     * text.
     *
     * @param pattern Element matching pattern
     * @param paramIndex The zero-relative parameter number
     * @param fromStack Should the call parameter be taken from the top of the stack?
     * @see CallParamRule
     */
    public void addCallParam( final String pattern, final int paramIndex, final boolean fromStack )
    {
        addRule( pattern, new CallParamRule( paramIndex, fromStack ) );
    }

    /**
     * Add a "call parameter" rule that sets a parameter from the stack. This takes a parameter from the given position
     * on the stack.
     *
     * @param pattern Element matching pattern
     * @param paramIndex The zero-relative parameter number
     * @param stackIndex set the call parameter to the stackIndex'th object down the stack, where 0 is the top of the
     *            stack, 1 the next element down and so on
     * @see CallMethodRule
     */
    public void addCallParam( final String pattern, final int paramIndex, final int stackIndex )
    {
        addRule( pattern, new CallParamRule( paramIndex, stackIndex ) );
    }

    /**
     * Add a "call parameter" rule that sets a parameter from the current <code>Digester</code> matching path. This is
     * sometimes useful when using rules that support wildcards.
     *
     * @param pattern the pattern that this rule should match
     * @param paramIndex The zero-relative parameter number
     * @see CallMethodRule
     */
    public void addCallParamPath( final String pattern, final int paramIndex )
    {
        addRule( pattern, new PathCallParamRule( paramIndex ) );
    }

    /**
     * Add a "call parameter" rule that sets a parameter from a caller-provided object. This can be used to pass
     * constants such as strings to methods; it can also be used to pass mutable objects, providing ways for objects to
     * do things like "register" themselves with some shared object.
     * <p>
     * Note that when attempting to locate a matching method to invoke, the true type of the paramObj is used, so that
     * despite the paramObj being passed in here as type Object, the target method can declare its parameters as being
     * the true type of the object (or some ancestor type, according to the usual type-conversion rules).
     *
     * @param pattern Element matching pattern
     * @param paramIndex The zero-relative parameter number
     * @param paramObj Any arbitrary object to be passed to the target method.
     * @see CallMethodRule
     * @since 1.6
     */
    public void addObjectParam( final String pattern, final int paramIndex, final Object paramObj )
    {
        addRule( pattern, new ObjectParamRule( paramIndex, paramObj ) );
    }

    /**
     * Add a "factory create" rule for the specified parameters. Exceptions thrown during the object creation process
     * will be propagated.
     *
     * @param pattern Element matching pattern
     * @param className Java class name of the object creation factory class
     * @see FactoryCreateRule
     */
    public void addFactoryCreate( final String pattern, final String className )
    {
        addFactoryCreate( pattern, className, false );
    }

    /**
     * Add a "factory create" rule for the specified parameters. Exceptions thrown during the object creation process
     * will be propagated.
     *
     * @param pattern Element matching pattern
     * @param clazz Java class of the object creation factory class
     * @see FactoryCreateRule
     */
    public void addFactoryCreate( final String pattern, final Class<? extends ObjectCreationFactory<?>> clazz )
    {
        addFactoryCreate( pattern, clazz, false );
    }

    /**
     * Add a "factory create" rule for the specified parameters. Exceptions thrown during the object creation process
     * will be propagated.
     *
     * @param pattern Element matching pattern
     * @param className Java class name of the object creation factory class
     * @param attributeName Attribute name which, if present, overrides the value specified by <code>className</code>
     * @see FactoryCreateRule
     */
    public void addFactoryCreate( final String pattern, final String className, final String attributeName )
    {
        addFactoryCreate( pattern, className, attributeName, false );
    }

    /**
     * Add a "factory create" rule for the specified parameters. Exceptions thrown during the object creation process
     * will be propagated.
     *
     * @param pattern Element matching pattern
     * @param clazz Java class of the object creation factory class
     * @param attributeName Attribute name which, if present, overrides the value specified by <code>className</code>
     * @see FactoryCreateRule
     */
    public void addFactoryCreate( final String pattern, final Class<? extends ObjectCreationFactory<?>> clazz,
                                  final String attributeName )
    {
        addFactoryCreate( pattern, clazz, attributeName, false );
    }

    /**
     * Add a "factory create" rule for the specified parameters. Exceptions thrown during the object creation process
     * will be propagated.
     *
     * @param pattern Element matching pattern
     * @param creationFactory Previously instantiated ObjectCreationFactory to be utilized
     * @see FactoryCreateRule
     */
    public void addFactoryCreate( final String pattern, final ObjectCreationFactory<?> creationFactory )
    {
        addFactoryCreate( pattern, creationFactory, false );
    }

    /**
     * Add a "factory create" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param className Java class name of the object creation factory class
     * @param ignoreCreateExceptions when <code>true</code> any exceptions thrown during object creation will be
     *            ignored.
     * @see FactoryCreateRule
     */
    public void addFactoryCreate( final String pattern, final String className, final boolean ignoreCreateExceptions )
    {
        addRule( pattern, new FactoryCreateRule( className, ignoreCreateExceptions ) );
    }

    /**
     * Add a "factory create" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param clazz Java class of the object creation factory class
     * @param ignoreCreateExceptions when <code>true</code> any exceptions thrown during object creation will be
     *            ignored.
     * @see FactoryCreateRule
     */
    public void addFactoryCreate( final String pattern, final Class<? extends ObjectCreationFactory<?>> clazz,
                                  final boolean ignoreCreateExceptions )
    {
        addRule( pattern, new FactoryCreateRule( clazz, ignoreCreateExceptions ) );
    }

    /**
     * Add a "factory create" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param className Java class name of the object creation factory class
     * @param attributeName Attribute name which, if present, overrides the value specified by <code>className</code>
     * @param ignoreCreateExceptions when <code>true</code> any exceptions thrown during object creation will be
     *            ignored.
     * @see FactoryCreateRule
     */
    public void addFactoryCreate( final String pattern, final String className, final String attributeName,
                                  final boolean ignoreCreateExceptions )
    {
        addRule( pattern, new FactoryCreateRule( className, attributeName, ignoreCreateExceptions ) );
    }

    /**
     * Add a "factory create" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param clazz Java class of the object creation factory class
     * @param attributeName Attribute name which, if present, overrides the value specified by <code>className</code>
     * @param ignoreCreateExceptions when <code>true</code> any exceptions thrown during object creation will be
     *            ignored.
     * @see FactoryCreateRule
     */
    public void addFactoryCreate( final String pattern, final Class<? extends ObjectCreationFactory<?>> clazz,
                                  final String attributeName, final boolean ignoreCreateExceptions )
    {
        addRule( pattern, new FactoryCreateRule( clazz, attributeName, ignoreCreateExceptions ) );
    }

    /**
     * Add a "factory create" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param creationFactory Previously instantiated ObjectCreationFactory to be utilized
     * @param ignoreCreateExceptions when <code>true</code> any exceptions thrown during object creation will be
     *            ignored.
     * @see FactoryCreateRule
     */
    public void addFactoryCreate( final String pattern, final ObjectCreationFactory<?> creationFactory,
                                  final boolean ignoreCreateExceptions )
    {
        creationFactory.setDigester( this );
        addRule( pattern, new FactoryCreateRule( creationFactory, ignoreCreateExceptions ) );
    }

    /**
     * Add an "object create" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param className Java class name to be created
     * @see ObjectCreateRule
     */
    public void addObjectCreate( final String pattern, final String className )
    {
        addRule( pattern, new ObjectCreateRule( className ) );
    }

    /**
     * Add an "object create" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param clazz Java class to be created
     * @see ObjectCreateRule
     */
    public void addObjectCreate( final String pattern, final Class<?> clazz )
    {
        addRule( pattern, new ObjectCreateRule( clazz ) );
    }

    /**
     * Add an "object create" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param className Default Java class name to be created
     * @param attributeName Attribute name that optionally overrides the default Java class name to be created
     * @see ObjectCreateRule
     */
    public void addObjectCreate( final String pattern, final String className, final String attributeName )
    {
        addRule( pattern, new ObjectCreateRule( className, attributeName ) );
    }

    /**
     * Add an "object create" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param attributeName Attribute name that optionally overrides
     * @param clazz Default Java class to be created the default Java class name to be created
     * @see ObjectCreateRule
     */
    public void addObjectCreate( final String pattern, final String attributeName, final Class<?> clazz )
    {
        addRule( pattern, new ObjectCreateRule( attributeName, clazz ) );
    }

    /**
     * Adds an {@link SetNestedPropertiesRule}.
     *
     * @param pattern register the rule with this pattern
     * @since 1.6
     */
    public void addSetNestedProperties( final String pattern )
    {
        addRule( pattern, new SetNestedPropertiesRule() );
    }

    /**
     * Adds an {@link SetNestedPropertiesRule}.
     *
     * @param pattern register the rule with this pattern
     * @param elementName elment name that a property maps to
     * @param propertyName property name of the element mapped from
     * @since 1.6
     */
    public void addSetNestedProperties( final String pattern, final String elementName, final String propertyName )
    {
        addRule( pattern, new SetNestedPropertiesRule( elementName, propertyName ) );
    }

    /**
     * Adds an {@link SetNestedPropertiesRule}.
     *
     * @param pattern register the rule with this pattern
     * @param elementNames elment names that (in order) map to properties
     * @param propertyNames property names that (in order) elements are mapped to
     * @since 1.6
     */
    public void addSetNestedProperties( final String pattern, final String[] elementNames, final String[] propertyNames )
    {
        addRule( pattern, new SetNestedPropertiesRule( elementNames, propertyNames ) );
    }

    /**
     * Add a "set next" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param methodName Method name to call on the parent element
     * @see SetNextRule
     */
    public void addSetNext( final String pattern, final String methodName )
    {
        addRule( pattern, new SetNextRule( methodName ) );
    }

    /**
     * Add a "set next" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param methodName Method name to call on the parent element
     * @param paramType Java class name of the expected parameter type (if you wish to use a primitive type, specify the
     *            corresonding Java wrapper class instead, such as <code>java.lang.Boolean</code> for a
     *            <code>boolean</code> parameter)
     * @see SetNextRule
     */
    public void addSetNext( final String pattern, final String methodName, final String paramType )
    {
        addRule( pattern, new SetNextRule( methodName, paramType ) );
    }

    /**
     * Add {@link SetRootRule} with the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param methodName Method name to call on the root object
     * @see SetRootRule
     */
    public void addSetRoot( final String pattern, final String methodName )
    {
        addRule( pattern, new SetRootRule( methodName ) );
    }

    /**
     * Add {@link SetRootRule} with the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param methodName Method name to call on the root object
     * @param paramType Java class name of the expected parameter type
     * @see SetRootRule
     */
    public void addSetRoot( final String pattern, final String methodName, final String paramType )
    {
        addRule( pattern, new SetRootRule( methodName, paramType ) );
    }

    /**
     * Add a "set properties" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @see SetPropertiesRule
     */
    public void addSetProperties( final String pattern )
    {
        addRule( pattern, new SetPropertiesRule() );
    }

    /**
     * Add a "set properties" rule with a single overridden parameter. See
     * {@link SetPropertiesRule#SetPropertiesRule(String attributeName, String propertyName)}
     *
     * @param pattern Element matching pattern
     * @param attributeName map this attribute
     * @param propertyName to this property
     * @see SetPropertiesRule
     */
    public void addSetProperties( final String pattern, final String attributeName, final String propertyName )
    {
        addRule( pattern, new SetPropertiesRule( attributeName, propertyName ) );
    }

    /**
     * Add a "set properties" rule with overridden parameters. See
     * {@link SetPropertiesRule#SetPropertiesRule(String [] attributeNames, String [] propertyNames)}
     *
     * @param pattern Element matching pattern
     * @param attributeNames names of attributes with custom mappings
     * @param propertyNames property names these attributes map to
     * @see SetPropertiesRule
     */
    public void addSetProperties( final String pattern, final String[] attributeNames, final String[] propertyNames )
    {
        addRule( pattern, new SetPropertiesRule( attributeNames, propertyNames ) );
    }

    /**
     * Add a "set property" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param name Attribute name containing the property name to be set
     * @param value Attribute name containing the property value to set
     * @see SetPropertyRule
     */
    public void addSetProperty( final String pattern, final String name, final String value )
    {
        addRule( pattern, new SetPropertyRule( name, value ) );
    }

    /**
     * Add a "set top" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param methodName Method name to call on the parent element
     * @see SetTopRule
     */
    public void addSetTop( final String pattern, final String methodName )
    {
        addRule( pattern, new SetTopRule( methodName ) );
    }

    /**
     * Add a "set top" rule for the specified parameters.
     *
     * @param pattern Element matching pattern
     * @param methodName Method name to call on the parent element
     * @param paramType Java class name of the expected parameter type (if you wish to use a primitive type, specify the
     *            corresonding Java wrapper class instead, such as <code>java.lang.Boolean</code> for a
     *            <code>boolean</code> parameter)
     * @see SetTopRule
     */
    public void addSetTop( final String pattern, final String methodName, final String paramType )
    {
        addRule( pattern, new SetTopRule( methodName, paramType ) );
    }

    // --------------------------------------------------- Object Stack Methods

    /**
     * Clear the current contents of the default object stack, the param stack, all named stacks, and other internal
     * variables.
     * <p>
     * Calling this method <i>might</i> allow another document of the same type to be correctly parsed. However this
     * method was not intended for this purpose (just to tidy up memory usage). In general, a separate Digester object
     * should be created for each document to be parsed.
     * <p>
     * Note that this method is called automatically after a document has been successfully parsed by a Digester
     * instance. However it is not invoked automatically when a parse fails, so when reusing a Digester instance (which
     * is not recommended) this method <i>must</i> be called manually after a parse failure.
     */
    public void clear()
    {
        match = "";
        bodyTexts.clear();
        params.clear();
        publicId = null;
        stack.clear();
        stacksByName.clear();
        customContentHandler = null;
    }

    /**
     * Return the top object on the stack without removing it.
     *
     * If there are no objects on the stack, return <code>null</code>.
     *
     * @param <T> the type used to auto-cast the returned object to the assigned variable type
     * @return the top object on the stack without removing it.
     */
    public <T> T peek()
    {
        try
        {
            return this.<T> npeSafeCast( stack.peek() );
        }
        catch ( final EmptyStackException e )
        {
            log.warn( "Empty stack (returning null)" );
            return ( null );
        }
    }

    /**
     * Return the n'th object down the stack, where 0 is the top element and [getCount()-1] is the bottom element. If
     * the specified index is out of range, return <code>null</code>.
     *
     * @param <T> the type used to auto-cast the returned object to the assigned variable type
     * @param n Index of the desired element, where 0 is the top of the stack, 1 is the next element down, and so on.
     * @return the n'th object down the stack
     */
    public <T> T peek( final int n )
    {
        final int index = ( stack.size() - 1 ) - n;
        if ( index < 0 )
        {
            log.warn( "Empty stack (returning null)" );
            return ( null );
        }
        try
        {
            return this.<T> npeSafeCast( stack.get( index ) );
        }
        catch ( final EmptyStackException e )
        {
            log.warn( "Empty stack (returning null)" );
            return ( null );
        }
    }

    /**
     * Pop the top object off of the stack, and return it. If there are no objects on the stack, return
     * <code>null</code>.
     *
     * @param <T> the type used to auto-cast the returned object to the assigned variable type
     * @return the top object popped off of the stack
     */
    public <T> T pop()
    {
        try
        {
            T popped = this.<T> npeSafeCast( stack.pop() );
            if ( stackAction != null )
            {
                popped = stackAction.onPop( this, null, popped );
            }
            return popped;
        }
        catch ( final EmptyStackException e )
        {
            log.warn( "Empty stack (returning null)" );
            return ( null );
        }
    }

    /**
     * Push a new object onto the top of the object stack.
     *
     * @param <T> any type of the pushed object
     * @param object The new object
     */
    public <T> void push( T object )
    {
        if ( stackAction != null )
        {
            object = stackAction.onPush( this, null, object );
        }

        if ( stack.isEmpty() )
        {
            root = object;
        }
        stack.push( object );
    }

    /**
     * Pushes the given object onto the stack with the given name. If no stack already exists with the given name then
     * one will be created.
     *
     * @param <T> any type of the pushed object
     * @param stackName the name of the stack onto which the object should be pushed
     * @param value the Object to be pushed onto the named stack.
     * @since 1.6
     */
    public <T> void push( final String stackName, T value )
    {
        if ( stackAction != null )
        {
            value = stackAction.onPush( this, stackName, value );
        }

        Stack<Object> namedStack = stacksByName.get( stackName );
        if ( namedStack == null )
        {
            namedStack = new Stack<Object>();
            stacksByName.put( stackName, namedStack );
        }
        namedStack.push( value );
    }

    /**
     * <p>
     * Pops (gets and removes) the top object from the stack with the given name.
     * </p>
     * <p>
     * <strong>Note:</strong> a stack is considered empty if no objects have been pushed onto it yet.
     * </p>
     *
     * @param <T> the type used to auto-cast the returned object to the assigned variable type
     * @param stackName the name of the stack from which the top value is to be popped.
     * @return the top <code>Object</code> on the stack or throws {@code EmptyStackException}
     *         if the stack is either empty or has not been created yet
     * @since 1.6
     */
    public <T> T pop( final String stackName )
    {
        final Stack<Object> namedStack = stacksByName.get( stackName );
        if ( namedStack == null )
        {
            if ( log.isDebugEnabled() )
            {
                log.debug( "Stack '" + stackName + "' is empty" );
            }
            throw new EmptyStackException();
        }

        T result = this.<T> npeSafeCast( namedStack.pop() );

        if ( stackAction != null )
        {
            result = stackAction.onPop( this, stackName, result );
        }

        return result;
    }

    /**
     * <p>
     * Gets the top object from the stack with the given name. This method does not remove the object from the stack.
     * </p>
     * <p>
     * <strong>Note:</strong> a stack is considered empty if no objects have been pushed onto it yet.
     * </p>
     *
     * @param <T> the type used to auto-cast the returned object to the assigned variable type
     * @param stackName the name of the stack to be peeked
     * @return the top <code>Object</code> on the stack or null if the stack is either empty or has not been created yet
     * @since 1.6
     */
    public <T> T peek( final String stackName )
    {
        return this.<T> npeSafeCast( peek( stackName, 0 ) );
    }

    /**
     * <p>
     * Gets the top object from the stack with the given name. This method does not remove the object from the stack.
     * </p>
     * <p>
     * <strong>Note:</strong> a stack is considered empty if no objects have been pushed onto it yet.
     * </p>
     *
     * @param <T> the type used to auto-cast the returned object to the assigned variable type
     * @param stackName the name of the stack to be peeked
     * @param n Index of the desired element, where 0 is the top of the stack, 1 is the next element down, and so on.
     * @return the specified <code>Object</code> on the stack.
     * @since 1.6
     */
    public <T> T peek( final String stackName, final int n )
    {
        T result;
        final Stack<Object> namedStack = stacksByName.get( stackName );
        if ( namedStack == null )
        {
            if ( log.isDebugEnabled() )
            {
                log.debug( "Stack '" + stackName + "' is empty" );
            }
            throw new EmptyStackException();
        }

        final int index = ( namedStack.size() - 1 ) - n;
        if ( index < 0 )
        {
            throw new EmptyStackException();
        }
        result = this.<T> npeSafeCast( namedStack.get( index ) );

        return result;
    }

    /**
     * <p>
     * Is the stack with the given name empty?
     * </p>
     * <p>
     * <strong>Note:</strong> a stack is considered empty if no objects have been pushed onto it yet.
     * </p>
     *
     * @param stackName the name of the stack whose emptiness should be evaluated
     * @return true if the given stack if empty
     * @since 1.6
     */
    public boolean isEmpty( final String stackName )
    {
        boolean result = true;
        final Stack<Object> namedStack = stacksByName.get( stackName );
        if ( namedStack != null )
        {
            result = namedStack.isEmpty();
        }
        return result;
    }

    /**
     * Returns the root element of the tree of objects created as a result of applying the rule objects to the input
     * XML.
     * <p>
     * If the digester stack was "primed" by explicitly pushing a root object onto the stack before parsing started,
     * then that root object is returned here.
     * <p>
     * Alternatively, if a Rule which creates an object (eg ObjectCreateRule) matched the root element of the xml, then
     * the object created will be returned here.
     * <p>
     * In other cases, the object most recently pushed onto an empty digester stack is returned. This would be a most
     * unusual use of digester, however; one of the previous configurations is much more likely.
     * <p>
     * Note that when using one of the Digester.parse methods, the return value from the parse method is exactly the
     * same as the return value from this method. However when the Digester is being used as a SAXContentHandler, no
     * such return value is available; in this case, this method allows you to access the root object that has been
     * created after parsing has completed.
     *
     * @param <T> the type used to auto-cast the returned object to the assigned variable type
     * @return the root object that has been created after parsing or null if the digester has not parsed any XML yet.
     */
    public <T> T getRoot()
    {
        return this.<T> npeSafeCast( root );
    }

    /**
     * This method allows the "root" variable to be reset to null.
     * <p>
     * It is not considered safe for a digester instance to be reused to parse multiple xml documents. However if you
     * are determined to do so, then you should call both clear() and resetRoot() before each parse.
     *
     * @since 1.7
     */
    public void resetRoot()
    {
        root = null;
    }

    // ------------------------------------------------ Parameter Stack Methods

    // ------------------------------------------------------ Protected Methods

    /**
     * <p>
     * Clean up allocated resources after parsing is complete. The default method closes input streams that have been
     * created by Digester itself. If you override this method in a subclass, be sure to call
     * <code>super.cleanup()</code> to invoke this logic.
     * </p>
     *
     * @since 1.8
     */
    protected void cleanup()
    {
        // If we created any InputSource objects in this instance,
        // they each have an input stream that should be closed
        for ( final InputSource source : inputSources )
        {
            try
            {
                source.getByteStream().close();
            }
            catch ( final IOException e )
            {
                // Fall through so we get them all
                if ( log.isWarnEnabled() )
                {
                    log.warn( format( "An error occurred while closing resource %s (%s)",
                                      source.getPublicId(),
                                      source.getSystemId() ), e );
                }
            }
        }
        inputSources.clear();
    }

    /**
     * <p>
     * Provide a hook for lazy configuration of this <code>Digester</code> instance. The default implementation does
     * nothing, but subclasses can override as needed.
     * </p>
     * <p>
     * <strong>Note</strong> This method may be called more than once. Once only initialization code should be placed in
     * {@link #initialize} or the code should take responsibility by checking and setting the {@link #configured} flag.
     * </p>
     */
    protected void configure()
    {
        // Do not configure more than once
        if ( configured )
        {
            return;
        }

        // Perform lazy configuration as needed
        initialize(); // call hook method for subclasses that want to be initialized once only
        // Nothing else required by default

        // Set the configuration flag to avoid repeating
        configured = true;
    }

    /**
     * Checks the Digester instance has been configured.
     *
     * @return true, if the Digester instance has been configured, false otherwise
     * @since 3.0
     */
    public boolean isConfigured()
    {
        return configured;
    }

    /**
     * <p>
     * Provides a hook for lazy initialization of this <code>Digester</code> instance. The default implementation does
     * nothing, but subclasses can override as needed. Digester (by default) only calls this method once.
     * </p>
     * <p>
     * <strong>Note</strong> This method will be called by {@link #configure} only when the {@link #configured} flag is
     * false. Subclasses that override <code>configure</code> or who set <code>configured</code> may find that this
     * method may be called more than once.
     * </p>
     *
     * @since 1.6
     */
    protected void initialize()
    {
        // Perform lazy initialization as needed
        // Nothing required by default
    }

    // -------------------------------------------------------- Package Methods

    /**
     * Return the set of DTD URL registrations, keyed by public identifier. NOTE: the returned map is in read-only mode.
     *
     * @return the read-only Map of DTD URL registrations.
     */
    Map<String, URL> getRegistrations()
    {
        return Collections.unmodifiableMap( entityValidator );
    }

    /**
     * <p>
     * Return the top object on the parameters stack without removing it. If there are no objects on the stack, return
     * <code>null</code>.
     * </p>
     * <p>
     * The parameters stack is used to store <code>CallMethodRule</code> parameters. See {@link #params}.
     * </p>
     *
     * @return the top object on the parameters stack without removing it.
     */
    public Object[] peekParams()
    {
        try
        {
            return ( params.peek() );
        }
        catch ( final EmptyStackException e )
        {
            log.warn( "Empty stack (returning null)" );
            return ( null );
        }
    }

    /**
     * <p>
     * Return the n'th object down the parameters stack, where 0 is the top element and [getCount()-1] is the bottom
     * element. If the specified index is out of range, return <code>null</code>.
     * </p>
     * <p>
     * The parameters stack is used to store <code>CallMethodRule</code> parameters. See {@link #params}.
     * </p>
     *
     * @param n Index of the desired element, where 0 is the top of the stack, 1 is the next element down, and so on.
     * @return the n'th object down the parameters stack
     */
    public Object[] peekParams( final int n )
    {
        final int index = ( params.size() - 1 ) - n;
        if ( index < 0 )
        {
            log.warn( "Empty stack (returning null)" );
            return ( null );
        }
        try
        {
            return ( params.get( index ) );
        }
        catch ( final EmptyStackException e )
        {
            log.warn( "Empty stack (returning null)" );
            return ( null );
        }
    }

    /**
     * <p>
     * Pop the top object off of the parameters stack, and return it. If there are no objects on the stack, return
     * <code>null</code>.
     * </p>
     * <p>
     * The parameters stack is used to store <code>CallMethodRule</code> parameters. See {@link #params}.
     * </p>
     *
     * @return the top object popped off of the parameters stack
     */
    public Object[] popParams()
    {
        try
        {
            if ( log.isTraceEnabled() )
            {
                log.trace( "Popping params" );
            }
            return ( params.pop() );
        }
        catch ( final EmptyStackException e )
        {
            log.warn( "Empty stack (returning null)" );
            return ( null );
        }
    }

    /**
     * <p>
     * Push a new object onto the top of the parameters stack.
     * </p>
     * <p>
     * The parameters stack is used to store <code>CallMethodRule</code> parameters. See {@link #params}.
     * </p>
     *
     * @param object The new object
     */
    public void pushParams( final Object... object )
    {
        if ( log.isTraceEnabled() )
        {
            log.trace( "Pushing params" );
        }
        params.push( object );
    }

    /**
     * Create a SAX exception which also understands about the location in the digester file where the exception occurs
     *
     * @param message the custom SAX exception message
     * @param e the exception cause
     * @return the new SAX exception
     */
    public SAXException createSAXException( final String message, Exception e )
    {
        if ( ( e != null ) && ( e instanceof InvocationTargetException ) )
        {
            final Throwable t = ( (InvocationTargetException) e ).getTargetException();
            if ( ( t != null ) && ( t instanceof Exception ) )
            {
                e = (Exception) t;
            }
        }
        if ( locator != null )
        {
            final String error =
                "Error at line " + locator.getLineNumber() + " char " + locator.getColumnNumber() + ": " + message;
            if ( e != null )
            {
                return new SAXParseException( error, locator, e );
            }
            return new SAXParseException( error, locator );
        }
        log.error( "No Locator!" );
        if ( e != null )
        {
            return new SAXException( message, e );
        }
        return new SAXException( message );
    }

    /**
     * Create a SAX exception which also understands about the location in the digester file where the exception occurs
     *
     * @param e the exception cause
     * @return the new SAX exception
     */
    public SAXException createSAXException( Exception e )
    {
        if ( e instanceof InvocationTargetException )
        {
            final Throwable t = ( (InvocationTargetException) e ).getTargetException();
            if ( ( t != null ) && ( t instanceof Exception ) )
            {
                e = (Exception) t;
            }
        }
        return createSAXException( e.getMessage(), e );
    }

    /**
     * Create a SAX exception which also understands about the location in the digester file where the exception occurs
     *
     * @param message the custom SAX exception message
     * @return the new SAX exception
     */
    public SAXException createSAXException( final String message )
    {
        return createSAXException( message, null );
    }

    /**
     * Helps casting the input object to given type, avoiding NPEs.
     *
     * @since 3.0
     * @param <T> the type the input object has to be cast.
     * @param obj the object has to be cast.
     * @return the casted object, if input object is not null, null otherwise.
     */
    private <T> T npeSafeCast( final Object obj )
    {
        if ( obj == null )
        {
            return null;
        }

        @SuppressWarnings( "unchecked" )
        final
        T result = (T) obj;
        return result;
    }

}
