//  Copyright 2004 The Apache Software Foundation
//
// Licensed 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.

package org.apache.tapestry.engine;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

import org.apache.bsf.BSFManager;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tapestry.ApplicationRuntimeException;
import org.apache.tapestry.ApplicationServlet;
import org.apache.tapestry.IEngine;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.INamespace;
import org.apache.tapestry.IPage;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.IResourceResolver;
import org.apache.tapestry.PageRedirectException;
import org.apache.tapestry.RedirectException;
import org.apache.tapestry.StaleLinkException;
import org.apache.tapestry.StaleSessionException;
import org.apache.tapestry.Tapestry;
import org.apache.tapestry.asset.ResourceChecksumSource;
import org.apache.tapestry.asset.ResourceChecksumSourceImpl;
import org.apache.tapestry.enhance.DefaultComponentClassEnhancer;
import org.apache.tapestry.listener.ListenerMap;
import org.apache.tapestry.pageload.PageSource;
import org.apache.tapestry.request.RequestContext;
import org.apache.tapestry.request.ResponseOutputStream;
import org.apache.tapestry.spec.IApplicationSpecification;
import org.apache.tapestry.util.DelegatingPropertySource;
import org.apache.tapestry.util.PropertyHolderPropertySource;
import org.apache.tapestry.util.ResourceBundlePropertySource;
import org.apache.tapestry.util.ServletContextPropertySource;
import org.apache.tapestry.util.ServletPropertySource;
import org.apache.tapestry.util.SystemPropertiesPropertySource;
import org.apache.tapestry.util.exception.ExceptionAnalyzer;
import org.apache.tapestry.util.io.DataSqueezer;
import org.apache.tapestry.util.pool.Pool;

/**
 *  Basis for building real Tapestry applications.  Immediate subclasses
 *  provide different strategies for managing page state and other resources
 *  between request cycles.
 *
 *  Uses a shared instance of
 *  {@link ITemplateSource}, {@link ISpecificationSource},
 *  {@link IScriptSource} and {@link IComponentMessagesSource}
 *  stored as attributes of the  {@link ServletContext}
 *  (they will be shared by all sessions).
 *
 *  <p>An application is designed to be very lightweight.
 *  Particularily, it should <b>never</b> hold references to any
 *  {@link IPage} or {@link org.apache.tapestry.IComponent} objects.  The entire system is
 *  based upon being able to quickly rebuild the state of any page(s).
 *
 * <p>Where possible, instance variables should be transient.  They
 * can be restored inside {@link #setupForRequest(RequestContext)}.
 *
 *  <p>In practice, a subclass (usually {@link BaseEngine})
 *  is used without subclassing.  Instead, a
 *  visit object is specified.  To facilitate this, the application specification
 *  may include a property, <code>org.apache.tapestry.visit-class</code>
 *  which is the class name  to instantiate when a visit object is first needed.  See
 *  {@link #createVisit(IRequestCycle)} for more details.
 *
 * <p>Some of the classes' behavior is controlled by JVM system properties
 * (typically only used during development):
 *
 * <table border=1>
 * 	<tr> <th>Property</th> <th>Description</th> </tr>
 *  <tr> <td>org.apache.tapestry.enable-reset-service</td>
 *		<td>If true, enabled an additional service, reset, that
 *		allow page, specification and template caches to be cleared on demand.
 *  	See {@link #isResetServiceEnabled()}. </td>
 * </tr>
 * <tr>
 *		<td>org.apache.tapestry.disable-caching</td>
 *	<td>If true, then the page, specification, template and script caches
 *  will be cleared after each request. This slows things down,
 *  but ensures that the latest versions of such files are used.
 *  Care should be taken that the source directories for the files
 *  preceeds any versions of the files available in JARs or WARs. </td>
 * </tr>
 * </table>
 *
 *
 *  @author Howard Lewis Ship
 *  @version $Id$
 *
 **/

public abstract class AbstractEngine
    implements IEngine, IEngineServiceView, Externalizable, HttpSessionBindingListener
{
    private static final Log LOG = LogFactory.getLog(AbstractEngine.class);

    /**
     *  @since 2.0.4
     *
     **/

    private static final long serialVersionUID = 6884834397673817117L;

    private transient String _contextPath;
    private transient String _servletPath;
    private transient String _clientAddress;
    private transient String _sessionId;
    private transient boolean _stateful;
    private transient ListenerMap _listeners;

    /** @since 2.2 **/

    private transient DataSqueezer _dataSqueezer;

    /**
     *  An object used to contain application-specific server side state.
     *
     **/

    private Object _visit;

    /**
     *  The globally shared application object.  Typically, this is created
     *  when first needed, shared between sessions and engines, and
     *  stored in the {@link ServletContext}.
     *
     *  @since 2.3
     *
     **/

    private transient Object _global;

    /**
     *  The base name for the servlet context key used to store
     *  the application-defined Global object, if any.
     *
     *  @since 2.3
     *
     **/

    public static final String GLOBAL_NAME = "org.apache.tapestry.global";

    /**
     *  The name of the application property that will be used to
     *  determine the encoding to use when generating the output
     *
     *  @since 3.0
     **/

    public static final String OUTPUT_ENCODING_PROPERTY_NAME =
        "org.apache.tapestry.output-encoding";

    /**
     *  The default encoding that will be used when generating the output.
     *  It is used if no output encoding property has been specified.
     *
     *  @since 3.0
     */

    public static final String DEFAULT_OUTPUT_ENCODING = "UTF-8";

    /**
     *  The curent locale for the engine, which may be changed at any time.
     *
     **/

    private Locale _locale;

    /**
     *  Set by {@link #setLocale(Locale)} when the locale is changed;
     *  this allows the locale cookie to be updated.
     *
     **/

    private boolean _localeChanged;

    /**
     *  The specification for the application, which
     *  lives in the {@link ServletContext}.  If the
     *  session (and application) moves to a different context (i.e.,
     *  a different JVM), then
     *  we want to reconnect to the specification in the new context.
     *  A check is made on every request
     *  cycle as needed.
     *
     **/

    protected transient IApplicationSpecification _specification;

    /**
     *  The source for template data. The template source is stored
     *  in the {@link ServletContext} as a named attribute.
     *  After de-serialization, the application can re-connect to
     *  the template source (or create a new one).
     *
     **/

    protected transient ITemplateSource _templateSource;

    /**
     *  The source for component specifications, stored in the
     *  {@link ServletContext} (like {@link #_templateSource}).
     *
     **/

    protected transient ISpecificationSource _specificationSource;

    /**
     *  The source for parsed scripts, again, stored in the
     *  {@link ServletContext}.
     *
     *  @since 1.0.2
     *
     **/

    private transient IScriptSource _scriptSource;

    /**
     *  The name of the context attribute for the {@link IScriptSource} instance.
     *  The application's name is appended.
     *
     *  @since 1.0.2
     *
     **/

    protected static final String SCRIPT_SOURCE_NAME = "org.apache.tapestry.ScriptSource";

    /**
     *  The name of the context attribute for the {@link IComponentMessagesSource}
     *  instance.  The application's name is appended.
     *
     *  @since 2.0.4
     *
     **/

    protected static final String STRINGS_SOURCE_NAME = "org.apache.tapestry.StringsSource";

    private transient IComponentMessagesSource _stringsSource;

    /**
     *  The name of the application specification property used to specify the
     *  class of the visit object.
     *
     **/

    public static final String VISIT_CLASS_PROPERTY_NAME = "org.apache.tapestry.visit-class";

    /**
     *  Servlet context attribute name for the default {@link ITemplateSource}
     *  instance.  The application's name is appended.
     *
     **/

    protected static final String TEMPLATE_SOURCE_NAME = "org.apache.tapestry.TemplateSource";

    /**
     *  Servlet context attribute name for the default {@link ISpecificationSource}
     *  instance.  The application's name is appended.
     *
     **/

    protected static final String SPECIFICATION_SOURCE_NAME =
        "org.apache.tapestry.SpecificationSource";

    /**
     *  Servlet context attribute name for the {@link IPageSource}
     *  instance.  The application's name is appended.
     *
     **/

    protected static final String PAGE_SOURCE_NAME = "org.apache.tapestry.PageSource";

    /**
     *  Servlet context attribute name for a shared instance
     *  of {@link DataSqueezer}.  The instance is actually shared
     *  between Tapestry applications within the same context
     *  (which will have the same ClassLoader).
     *
     *  @since 2.2
     *
     **/

    protected static final String DATA_SQUEEZER_NAME = "org.apache.tapestry.DataSqueezer";

    /**
     * Servlet context attribute name for a shared instance
     * of {@link ResourceChecksumSource}.
     * @since 3.0.3
     */
    protected static final String RESOURCE_CHECKSUM_SOURCE_NAME = 
        "org.apache.tapestry.ResourceChecksumSource";
    
    /**
     *  The source for pages, which acts as a pool, but is capable of
     *  creating pages as needed.  Stored in the
     *  {@link ServletContext}, like {@link #_templateSource}.
     *
     **/

    private transient IPageSource _pageSource;

    /**
     *  If true (set from JVM system parameter
     *  <code>org.apache.tapestry.enable-reset-service</code>)
     *  then the reset service will be enabled, allowing
     *  the cache of pages, specifications and template
     *  to be cleared on demand.
     *
     **/

    private static final boolean _resetServiceEnabled =
        Boolean.getBoolean("org.apache.tapestry.enable-reset-service");

    /**
     * If true (set from the JVM system parameter
     * <code>org.apache.tapestry.disable-caching</code>)
     * then the cache of pages, specifications and template
     * will be cleared after each request.
     *
     **/

    private static final boolean _disableCaching =
        Boolean.getBoolean("org.apache.tapestry.disable-caching");

    private transient IResourceResolver _resolver;

    /**
     *  Constant used to store a {@link org.apache.tapestry.util.IPropertyHolder}
     *  in the servlet context.
     *
     *  @since 2.3
     *
     **/

    protected static final String PROPERTY_SOURCE_NAME = "org.apache.tapestry.PropertySource";

    /**
     *  A shared instance of {@link IPropertySource}
     *
     *  @since 3.0
     *  @see #createPropertySource(RequestContext)
     *
     **/

    private transient IPropertySource _propertySource;

    /**
     *  Map from service name to service instance.
     *
     *  @since 1.0.9
     *
     **/

    private transient Map _serviceMap;

    protected static final String SERVICE_MAP_NAME = "org.apache.tapestry.ServiceMap";

    /**
     *  A shared instance of {@link Pool}.
     *
     *  @since 3.0
     *  @see #createPool(RequestContext)
     *
     **/

    private transient Pool _pool;

    protected static final String POOL_NAME = "org.apache.tapestry.Pool";

    /**
     *  Name of a shared instance of {@link org.apache.tapestry.engine.IComponentClassEnhancer}
     *  stored in the {@link ServletContext}.
     *
     *  @since 3.0
     *
     **/

    protected static final String ENHANCER_NAME = "org.apache.tapestry.ComponentClassEnhancer";

    /**
     *  A shared instance of {@link org.apache.tapestry.engine.IComponentClassEnhancer}.
     *
     *  @since 3.0
     *  @see #createComponentClassEnhancer(RequestContext)
     *
     **/

    private transient IComponentClassEnhancer _enhancer;

    /**
     *  Set to true when there is a (potential)
     *  change to the internal state of the engine, set
     *  to false when the engine is stored into the
     *  {@link HttpSession}.
     *
     *  @since 3.0
     *
     **/

    private transient boolean _dirty;

    /**
     * The instance of {@link IMonitorFactory} used to create a monitor.
     *
     * @since 3.0
     */

    private transient IMonitorFactory _monitorFactory;

    /**
     * Used to obtain resource checksums for the asset service.
     * @since 3.0.3
     */
    private transient ResourceChecksumSource _resourceChecksumSource;
    
    /**
     *  Sets the Exception page's exception property, then renders the Exception page.
     *
     *  <p>If the render throws an exception, then copious output is sent to
     *  <code>System.err</code> and a {@link ServletException} is thrown.
     *
     **/

    protected void activateExceptionPage(
        IRequestCycle cycle,
        ResponseOutputStream output,
        Throwable cause)
        throws ServletException
    {
        try
        {
            IPage exceptionPage = cycle.getPage(getExceptionPageName());

            exceptionPage.setProperty("exception", cause);

            cycle.activate(exceptionPage);

            renderResponse(cycle, output);

        }
        catch (Throwable ex)
        {
            // Worst case scenario.  The exception page itself is broken, leaving
            // us with no option but to write the cause to the output.

            reportException(
                Tapestry.getMessage("AbstractEngine.unable-to-process-client-request"),
                cause);

            // Also, write the exception thrown when redendering the exception
            // page, so that can get fixed as well.

            reportException(
                Tapestry.getMessage("AbstractEngine.unable-to-present-exception-page"),
                ex);

            // And throw the exception.

            throw new ServletException(ex.getMessage(), ex);
        }
    }

    /**
     *  Writes a detailed report of the exception to <code>System.err</code>.
     *
     **/

    public void reportException(String reportTitle, Throwable ex)
    {
        LOG.warn(reportTitle, ex);

        System.err.println("\n\n**********************************************************\n\n");

        System.err.println(reportTitle);

        System.err.println(
            "\n\n      Session id: "
                + _sessionId
                + "\n  Client address: "
                + _clientAddress
                + "\n\nExceptions:\n");

        new ExceptionAnalyzer().reportException(ex, System.err);

        System.err.println("\n**********************************************************\n");

    }

    /**
     *  Invoked at the end of the request cycle to release any resources specific
     *  to the request cycle.
     *
     **/

    protected abstract void cleanupAfterRequest(IRequestCycle cycle);

    /**
     *  Extends the description of the class generated by {@link #toString()}.
     *  If a subclass adds additional instance variables that should be described
     *  in the instance description, it may overide this method. This implementation
     *  does nothing.
     *
     *  @see #toString()
     *
     **/

    protected void extendDescription(ToStringBuilder builder)
    {

    }

    /**
     *  Returns the locale for the engine.  This is initially set
     *  by the {@link ApplicationServlet} but may be updated
     *  by the application.
     *
     **/

    public Locale getLocale()
    {
        return _locale;
    }

    /**
     * Overriden in subclasses that support monitoring.  Should create and return
     * an instance of {@link IMonitor} that is appropriate for the request cycle described
     * by the {@link RequestContext}.
     *
     * <p>The monitor is used to create a {@link RequestCycle}.
     *
     * <p>This implementation uses a {@link IMonitorFactory}
     * to create the monitor instance.  The factory
     * is provided as an application extension.  If the application
     * extension does not exist, {@link DefaultMonitorFactory} is used.
     *
     * <p>As of release 3.0, this method should <em>not</em> return null.
     *
     *
     */

    public IMonitor getMonitor(RequestContext context)
    {
        if (_monitorFactory == null)
        {
            if (_specification.checkExtension(Tapestry.MONITOR_FACTORY_EXTENSION_NAME))
                _monitorFactory =
                    (IMonitorFactory) _specification.getExtension(
                        Tapestry.MONITOR_FACTORY_EXTENSION_NAME,
                        IMonitorFactory.class);
            else
                _monitorFactory = DefaultMonitorFactory.SHARED;
        }

        return _monitorFactory.createMonitor(context);
    }

    public IPageSource getPageSource()
    {
        return _pageSource;
    }

    /**
     *  Returns a service with the given name.  Services are created by the
     *  first call to {@link #setupForRequest(RequestContext)}.
     **/

    public IEngineService getService(String name)
    {
        IEngineService result = (IEngineService) _serviceMap.get(name);

        if (result == null)
            throw new ApplicationRuntimeException(
                Tapestry.format("AbstractEngine.unknown-service", name));

        return result;
    }

    public String getServletPath()
    {
        return _servletPath;
    }

    /**
     * Returns the context path, the prefix to apply to any URLs so that they
     * are recognized as belonging to the Servlet 2.2 context.
     *
     *  @see org.apache.tapestry.asset.ContextAsset
     *
     **/

    public String getContextPath()
    {
        return _contextPath;
    }

    /**
     *  Returns the specification, if available, or null otherwise.
     *
     *  <p>To facilitate deployment across multiple servlet containers, the
     *  application is serializable.  However, the reference to the specification
     *  is transient.   When an application instance is deserialized, it reconnects
     *  with the application specification by locating it in the {@link ServletContext}
     *  or parsing it fresh.
     *
     **/

    public IApplicationSpecification getSpecification()
    {
        return _specification;
    }

    public ISpecificationSource getSpecificationSource()
    {
        return _specificationSource;
    }

    public ITemplateSource getTemplateSource()
    {
        return _templateSource;
    }

    /**
     *  Reads the state serialized by {@link #writeExternal(ObjectOutput)}.
     *
     *  <p>This always set the stateful flag.  By default, a deserialized
     *  session is stateful (else, it would not have been serialized).
     **/

    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
    {
        _stateful = true;

        String localeName = in.readUTF();
        _locale = Tapestry.getLocale(localeName);

        _visit = in.readObject();
    }

    /**
     *  Writes the following properties:
     *
     *  <ul>
     *  <li>locale name ({@link Locale#toString()})
     *  <li>visit
     *  </ul>
     *
     **/

    public void writeExternal(ObjectOutput out) throws IOException
    {
        out.writeUTF(_locale.toString());
        out.writeObject(_visit);
    }

    /**
     *  Invoked, typically, when an exception occurs while servicing the request.
     *  This method resets the output, sets the new page and renders it.
     *
     **/

    protected void redirect(
        String pageName,
        IRequestCycle cycle,
        ResponseOutputStream out,
        ApplicationRuntimeException exception)
        throws IOException, ServletException
    {
        // Discard any output from the previous page.

        out.reset();

        IPage page = cycle.getPage(pageName);

        cycle.activate(page);

        renderResponse(cycle, out);
    }

    public void renderResponse(IRequestCycle cycle, ResponseOutputStream output)
        throws ServletException, IOException
    {
        if (LOG.isDebugEnabled())
            LOG.debug("Begin render response.");

        // If the locale has changed during this request cycle then
        // do the work to propogate the locale change into
        // subsequent request cycles.

        if (_localeChanged)
        {
            _localeChanged = false;

            RequestContext context = cycle.getRequestContext();
            ApplicationServlet servlet = context.getServlet();

            servlet.writeLocaleCookie(_locale, this, context);
        }

        // Commit all changes and ignore further changes.

        IPage page = cycle.getPage();

        IMarkupWriter writer = page.getResponseWriter(output);

        output.setContentType(writer.getContentType());

        boolean discard = true;

        try
        {
            cycle.renderPage(writer);

            discard = false;
        }
        finally
        {
            // Closing the writer closes its PrintWriter and a whole stack of java.io objects,
            // which tend to stream a lot of output that eventually hits the
            // ResponseOutputStream.  If we are discarding output anyway (due to an exception
            // getting thrown during the render), we can save ourselves some trouble
            // by ignoring it.

            if (discard)
                output.setDiscard(true);

            writer.close();

            if (discard)
                output.setDiscard(false);
        }

    }

    /**
     * Invalidates the session, then redirects the client web browser to
     * the servlet's prefix, starting a new visit.
     *
     * <p>Subclasses should perform their own restart (if necessary, which is
     * rarely) before invoking this implementation.
     *
     **/

    public void restart(IRequestCycle cycle) throws IOException
    {
        RequestContext context = cycle.getRequestContext();

        HttpSession session = context.getSession();

        if (session != null)
        {
            try
            {
                session.invalidate();
            }
            catch (IllegalStateException ex)
            {
                if (LOG.isDebugEnabled())
                    LOG.debug("Exception thrown invalidating HttpSession.", ex);

                // Otherwise, ignore it.
            }
        }

        // Make isStateful() return false, so that the servlet doesn't
        // try to store the engine back into the (now invalid) session.

        _stateful = false;

        String url = context.getAbsoluteURL(_servletPath);

        context.redirect(url);
    }

    /**
     *  Delegate method for the servlet.  Services the request.
     *
     **/

    public boolean service(RequestContext context) throws ServletException, IOException
    {
        ApplicationServlet servlet = context.getServlet();
        IRequestCycle cycle = null;
        ResponseOutputStream output = null;
        IMonitor monitor = null;

        if (LOG.isDebugEnabled())
            LOG.debug("Begin service " + context.getRequestURI());

        if (_specification == null)
            _specification = servlet.getApplicationSpecification();

        // The servlet invokes setLocale() before invoking service().  We want
        // to ignore that setLocale() ... that is, not force a cookie to be
        // written.

        _localeChanged = false;

        if (_resolver == null)
            _resolver = servlet.getResourceResolver();

        try
        {
            setupForRequest(context);

            monitor = getMonitor(context);

            output = new ResponseOutputStream(context.getResponse());
        }
        catch (Exception ex)
        {
            reportException(Tapestry.getMessage("AbstractEngine.unable-to-begin-request"), ex);

            throw new ServletException(ex.getMessage(), ex);
        }

        IEngineService service = null;

        try
        {
            try
            {
                String serviceName;

                try
                {
                    serviceName = extractServiceName(context);

                    if (Tapestry.isBlank(serviceName))
                        serviceName = Tapestry.HOME_SERVICE;

                    // Must have a service to create the request cycle.
                    // Must have a request cycle to report an exception.

                    service = getService(serviceName);
                }
                catch (Exception ex)
                {
                    service = getService(Tapestry.HOME_SERVICE);
                    cycle = createRequestCycle(context, service, monitor);

                    throw ex;
                }

                cycle = createRequestCycle(context, service, monitor);

                monitor.serviceBegin(serviceName, context.getRequestURI());

                // Invoke the service, which returns true if it may have changed
                // the state of the engine (most do return true).

                service.service(this, cycle, output);

                // Return true only if the engine is actually dirty.  This cuts down
                // on the number of times the engine is stored into the
                // session unceccesarily.

                return _dirty;
            }
            catch (PageRedirectException ex)
            {
                handlePageRedirectException(ex, cycle, output);
            }
            catch (RedirectException ex)
            {
                handleRedirectException(cycle, ex);
            }
            catch (StaleLinkException ex)
            {
                handleStaleLinkException(ex, cycle, output);
            }
            catch (StaleSessionException ex)
            {
                handleStaleSessionException(ex, cycle, output);
            }
        }
        catch (Exception ex)
        {
            monitor.serviceException(ex);

            // Discard any output (if possible).  If output has already been sent to
            // the client, then things get dicey.  Note that this block
            // gets activated if the StaleLink or StaleSession pages throws
            // any kind of exception.

            // Attempt to switch to the exception page.  However, this may itself fail
            // for a number of reasons, in which case a ServletException is thrown.

            output.reset();

            if (LOG.isDebugEnabled())
                LOG.debug("Uncaught exception", ex);

            activateExceptionPage(cycle, output, ex);
        }
        finally
        {
            if (service != null)
                monitor.serviceEnd(service.getName());

            try
            {
                cycle.cleanup();

                // Closing the buffered output closes the underlying stream as well.

                if (output != null)
                    output.forceFlush();
            }
            catch (Exception ex)
            {
                reportException(Tapestry.getMessage("AbstractEngine.exception-during-cleanup"), ex);
            }
			finally
			{
                cleanupAfterRequest(cycle);
			}

            if (_disableCaching)
            {
                try
                {
                    clearCachedData();
                }
                catch (Exception ex)
                {
                    reportException(
                        Tapestry.getMessage("AbstractEngine.exception-during-cache-clear"),
                        ex);
                }
            }

            if (LOG.isDebugEnabled())
                LOG.debug("End service");

        }

        return _dirty;
    }

    /**
     *  Handles {@link PageRedirectException} which involves
     *  executing {@link IPage#validate(IRequestCycle)} on the target page
     *  (of the exception), until either a loop is found, or a page
     *  succesfully validates and can be activated.
     *
     *  <p>This should generally not be overriden in subclasses.
     *
     *  @since 3.0
     */

    protected void handlePageRedirectException(
        PageRedirectException ex,
        IRequestCycle cycle,
        ResponseOutputStream output)
        throws IOException, ServletException
    {
        List pageNames = new ArrayList();

        String pageName = ex.getTargetPageName();

        while (true)
        {
            if (pageNames.contains(pageName))
            {
                // Add the offending page to pageNames so it shows in the
                // list.

                pageNames.add(pageName);

                StringBuffer buffer = new StringBuffer();
                int count = pageNames.size();

                for (int i = 0; i < count; i++)
                {
                    if (i > 0)
                        buffer.append("; ");

                    buffer.append(pageNames.get(i));
                }

                throw new ApplicationRuntimeException(
                    Tapestry.format("AbstractEngine.validate-cycle", buffer.toString()));
            }

            // Record that this page has been a target.

            pageNames.add(pageName);

            try
            {
                // Attempt to activate the new page.

                cycle.activate(pageName);

                break;
            }
            catch (PageRedirectException ex2)
            {
                pageName = ex2.getTargetPageName();
            }
        }

        // Discard any output from the previous page.

        output.reset();

        renderResponse(cycle, output);
    }

    /**
     *  Invoked from {@link #service(RequestContext)} to create an instance of
     *  {@link IRequestCycle} for the current request.  This implementation creates
     *  an returns an instance of {@link RequestCycle}.
     *
     *  @since 3.0
     *
     **/

    protected IRequestCycle createRequestCycle(
        RequestContext context,
        IEngineService service,
        IMonitor monitor)
    {
        return new RequestCycle(this, context, service, monitor);
    }

    /**
     *  Invoked by {@link #service(RequestContext)} if a {@link StaleLinkException}
     *  is thrown by the {@link IEngineService service}.  This implementation
     *  sets the message property of the StaleLink page to the
     *  message provided in the exception,
     *  then invokes
     *  {@link #redirect(String, IRequestCycle, ResponseOutputStream, ApplicationRuntimeException)}
     *  to render the StaleLink page.
     *
     *  <p>Subclasses may overide this method (without
     *  invoking this implementation).  A common practice
     *  is to present an error message on the application's
     *  Home page.
     *
     *  <p>Alternately, the application may provide its own version of
     *  the StaleLink page, overriding
     *  the framework's implementation (probably a good idea, because the
     *  default page hints at "application errors" and isn't localized).
     *  The overriding StaleLink implementation must
     *  implement a message property of type String.
     *
     *  @since 0.2.10
     *
     **/

    protected void handleStaleLinkException(
        StaleLinkException ex,
        IRequestCycle cycle,
        ResponseOutputStream output)
        throws IOException, ServletException
    {
        String staleLinkPageName = getStaleLinkPageName();
        IPage page = cycle.getPage(staleLinkPageName);

        page.setProperty("message", ex.getMessage());

        redirect(staleLinkPageName, cycle, output, ex);
    }

    /**
     *  Invoked by {@link #service(RequestContext)} if a {@link StaleSessionException}
     *  is thrown by the {@link IEngineService service}.  This implementation
     *  invokes
     *  {@link #redirect(String, IRequestCycle, ResponseOutputStream, ApplicationRuntimeException)}
     *  to render the StaleSession page.
     *
     *  <p>Subclasses may overide this method (without
     *  invoking this implementation).  A common practice
     *  is to present an eror message on the application's
     *  Home page.
     *
     *  @since 0.2.10
     **/

    protected void handleStaleSessionException(
        StaleSessionException ex,
        IRequestCycle cycle,
        ResponseOutputStream output)
        throws IOException, ServletException
    {
        redirect(getStaleSessionPageName(), cycle, output, ex);
    }

    /**
     *  Discards all cached pages, component specifications and templates.
     *  Subclasses who override this method should invoke this implementation
     *  as well.
     *
     *  @since 1.0.1
     *
     **/

    public void clearCachedData()
    {
        _pool.clear();
        _pageSource.reset();
        _specificationSource.reset();
        _templateSource.reset();
        _scriptSource.reset();
        _stringsSource.reset();
        _enhancer.reset();
        _resourceChecksumSource.reset();
    }

    /**
     *  Changes the locale for the engine.
     *
     **/

    public void setLocale(Locale value)
    {
        if (value == null)
            throw new IllegalArgumentException("May not change engine locale to null.");

        // Because locale changes are expensive (it involves writing a cookie and all that),
        // we're careful not to really change unless there's a true change in value.

        if (!value.equals(_locale))
        {
            _locale = value;
            _localeChanged = true;
            markDirty();
        }
    }

    /**
     *  Invoked from {@link #service(RequestContext)} to ensure that the engine's
     *  instance variables are setup.  This allows the application a chance to
     *  restore transient variables that will not have survived deserialization.
     *
     *  Determines the servlet prefix:  this is the base URL used by
     *  {@link IEngineService services} to build URLs.  It consists
     *  of two parts:  the context path and the servlet path.
     *
     *  <p>The servlet path is retrieved from {@link HttpServletRequest#getServletPath()}.
     *
     *  <p>The context path is retrieved from {@link HttpServletRequest#getContextPath()}.
     *
     *  <p>The global object is retrieved from {@link IEngine#getGlobal()} method.
     *
     *  <p>The final path is available via the {@link #getServletPath()} method.
     *
     *  <p>In addition, this method locates and/or creates the:
     *  <ul>
     *  <li>{@link IComponentClassEnhancer}
     *  <li>{@link Pool}
     *  <li>{@link ITemplateSource}
     *  <li>{@link ISpecificationSource}
     *  <li>{@link IPageSource}
     *  <li>{@link IEngineService} {@link Map}
     *  <ll>{@link IScriptSource}
     *  <li>{@link IComponentMessagesSource}
     *  <li>{@link IPropertySource}
     *  </ul>
     *
     *  <p>This order is important, because some of the later shared objects
     *  depend on some of the earlier shared objects already having
     *  been located or created
     *  (especially {@link #getPool() pool}).
     *
     *  <p>Subclasses should invoke this implementation first, then perform their
     *  own setup.
     *
     **/

    protected void setupForRequest(RequestContext context)
    {
        HttpServlet servlet = context.getServlet();
        ServletContext servletContext = servlet.getServletContext();
        HttpServletRequest request = context.getRequest();
        HttpSession session = context.getSession();

        if (session != null)
            _sessionId = context.getSession().getId();
        else
            _sessionId = null;

        // Previously, this used getRemoteHost(), but that requires an
        // expensive reverse DNS lookup. Possibly, the host name lookup
        // should occur ... but only if there's an actual error message
        // to display.

        if (_clientAddress == null)
            _clientAddress = request.getRemoteAddr();

        // servletPath is null, so this means either we're doing the
        // first request in this session, or we're handling a subsequent
        // request in another JVM (i.e. another server in the cluster).
        // In any case, we have to do some late (re-)initialization.

        if (_servletPath == null)
        {
            // Get the path *within* the servlet context

            // In rare cases related to the tagsupport service, getServletPath() is wrong
            // (its a JSP, which invokes Tapestry as an include, thus muddling what
            // the real servlet and servlet path is).  In those cases, the JSP tag
            // will inform us.

            String path =
                (String) request.getAttribute(Tapestry.TAG_SUPPORT_SERVLET_PATH_ATTRIBUTE);

            if (path == null)
                path = request.getServletPath();

            // Get the context path, which may be the empty string
            // (but won't be null).

            _contextPath = request.getContextPath();

            _servletPath = _contextPath + path;
        }

        String servletName = context.getServlet().getServletName();

        if (_propertySource == null)
        {
            String name = PROPERTY_SOURCE_NAME + ":" + servletName;

            _propertySource = (IPropertySource) servletContext.getAttribute(name);

            if (_propertySource == null)
            {
                _propertySource = createPropertySource(context);

                servletContext.setAttribute(name, _propertySource);
            }
        }

        if (_enhancer == null)
        {
            String name = ENHANCER_NAME + ":" + servletName;

            _enhancer = (IComponentClassEnhancer) servletContext.getAttribute(name);

            if (_enhancer == null)
            {
                _enhancer = createComponentClassEnhancer(context);

                servletContext.setAttribute(name, _enhancer);
            }
        }

        if (_pool == null)
        {
            String name = POOL_NAME + ":" + servletName;

            _pool = (Pool) servletContext.getAttribute(name);

            if (_pool == null)
            {
                _pool = createPool(context);

                servletContext.setAttribute(name, _pool);
            }
        }

        if (_templateSource == null)
        {
            String name = TEMPLATE_SOURCE_NAME + ":" + servletName;

            _templateSource = (ITemplateSource) servletContext.getAttribute(name);

            if (_templateSource == null)
            {
                _templateSource = createTemplateSource(context);

                servletContext.setAttribute(name, _templateSource);
            }
        }

        if (_specificationSource == null)
        {
            String name = SPECIFICATION_SOURCE_NAME + ":" + servletName;

            _specificationSource = (ISpecificationSource) servletContext.getAttribute(name);

            if (_specificationSource == null)
            {
                _specificationSource = createSpecificationSource(context);

                servletContext.setAttribute(name, _specificationSource);
            }
        }

        if (_pageSource == null)
        {
            String name = PAGE_SOURCE_NAME + ":" + servletName;

            _pageSource = (IPageSource) servletContext.getAttribute(name);

            if (_pageSource == null)
            {
                _pageSource = createPageSource(context);

                servletContext.setAttribute(name, _pageSource);
            }
        }

        if (_scriptSource == null)
        {
            String name = SCRIPT_SOURCE_NAME + ":" + servletName;

            _scriptSource = (IScriptSource) servletContext.getAttribute(name);

            if (_scriptSource == null)
            {
                _scriptSource = createScriptSource(context);

                servletContext.setAttribute(name, _scriptSource);
            }
        }

        if (_serviceMap == null)
        {
            String name = SERVICE_MAP_NAME + ":" + servletName;

            _serviceMap = (Map) servletContext.getAttribute(name);

            if (_serviceMap == null)
            {
                _serviceMap = createServiceMap();

                servletContext.setAttribute(name, _serviceMap);
            }
        }

        if (_stringsSource == null)
        {
            String name = STRINGS_SOURCE_NAME + ":" + servletName;

            _stringsSource = (IComponentMessagesSource) servletContext.getAttribute(name);

            if (_stringsSource == null)
            {
                _stringsSource = createComponentStringsSource(context);

                servletContext.setAttribute(name, _stringsSource);
            }
        }

        if (_dataSqueezer == null)
        {
            String name = DATA_SQUEEZER_NAME + ":" + servletName;

            _dataSqueezer = (DataSqueezer) servletContext.getAttribute(name);

            if (_dataSqueezer == null)
            {
                _dataSqueezer = createDataSqueezer();

                servletContext.setAttribute(name, _dataSqueezer);
            }
        }

        if (_global == null)
        {
            String name = GLOBAL_NAME + ":" + servletName;

            _global = servletContext.getAttribute(name);

            if (_global == null)
            {
                _global = createGlobal(context);

                servletContext.setAttribute(name, _global);
            }
        }
        
        if (_resourceChecksumSource == null)
        {
            String name = RESOURCE_CHECKSUM_SOURCE_NAME + ":" + servletName;

            _resourceChecksumSource = (ResourceChecksumSource) servletContext.getAttribute(name);

            if (_resourceChecksumSource == null)
            {
                _resourceChecksumSource = createResourceChecksumSource();

                servletContext.setAttribute(name, _resourceChecksumSource);
            }
        }

        String encoding = request.getCharacterEncoding();
        if (encoding == null)
        {
            encoding = getOutputEncoding();
            try
            {
                request.setCharacterEncoding(encoding);
            }
            catch (UnsupportedEncodingException e)
            {
                throw new IllegalArgumentException(Tapestry.format("illegal-encoding", encoding));
            }
            catch (NoSuchMethodError e)
            {
                // Servlet API 2.2 compatibility
                // Behave okay if the setCharacterEncoding() method is unavailable
            }
            catch (AbstractMethodError e)
            {
                // Servlet API 2.2 compatibility
                // Behave okay if the setCharacterEncoding() method is unavailable
            }
        }
    }

    /**
     *
     *  Invoked from {@link #setupForRequest(RequestContext)} to provide
     *  a new instance of {@link IComponentMessagesSource}.
     *
     *  @return an instance of {@link DefaultComponentMessagesSource}
     *  @since 2.0.4
     *
     **/

    public IComponentMessagesSource createComponentStringsSource(RequestContext context)
    {
        return new DefaultComponentMessagesSource();
    }

    /**
     *  Invoked from {@link #setupForRequest(RequestContext)} to provide
     *  an instance of {@link IScriptSource} that will be stored into
     *  the {@link ServletContext}.  Subclasses may override this method
     *  to provide a different implementation.
     *
     *
     *  @return an instance of {@link DefaultScriptSource}
     *  @since 1.0.9
     *
     **/

    protected IScriptSource createScriptSource(RequestContext context)
    {
        return new DefaultScriptSource(getResourceResolver());
    }

    /**
     *  Invoked from {@link #setupForRequest(RequestContext)} to provide
     *  an instance of {@link IPageSource} that will be stored into
     *  the {@link ServletContext}.  Subclasses may override this method
     *  to provide a different implementation.
     *
     *  @return an instance of {@link PageSource}
     *  @since 1.0.9
     *
     **/

    protected IPageSource createPageSource(RequestContext context)
    {
        return new PageSource(this);
    }

    /**
     *  Invoked from {@link #setupForRequest(RequestContext)} to provide
     *  an instance of {@link ISpecificationSource} that will be stored into
     *  the {@link ServletContext}.  Subclasses may override this method
     *  to provide a different implementation.
     *
     *  @return an instance of {@link DefaultSpecificationSource}
     *  @since 1.0.9
     **/

    protected ISpecificationSource createSpecificationSource(RequestContext context)
    {
        return new DefaultSpecificationSource(getResourceResolver(), _specification, _pool);
    }

    /**
     *  Invoked from {@link #setupForRequest(RequestContext)} to provide
     *  an instance of {@link ITemplateSource} that will be stored into
     *  the {@link ServletContext}.  Subclasses may override this method
     *  to provide a different implementation.
     *
     *  @return an instance of {@link DefaultTemplateSource}
     *  @since 1.0.9
     *
     **/

    protected ITemplateSource createTemplateSource(RequestContext context)
    {
        return new DefaultTemplateSource();
    }

    /**
     * Invoked from {@link #setupForRequest(RequestContext)} to provide
     * an instance of {@link ResourceChecksumSource} that will be stored into
     * the {@link ServletContext}.  Subclasses may override this method
     * to provide a different implementation.
     * @return an instance of {@link ResourceChecksumSourceImpl} that uses MD5 and Hex encoding.
     * @since 3.0.3
     */
    protected ResourceChecksumSource createResourceChecksumSource()
    {
        return new ResourceChecksumSourceImpl("MD5", new Hex());
    }
    
    /**
     *  Returns an object which can find resources and classes.
     *
     **/

    public IResourceResolver getResourceResolver()
    {
        return _resolver;
    }

    /**
     *  Generates a description of the instance.
     *  Invokes {@link #extendDescription(ToStringBuilder)}
     *  to fill in details about the instance.
     *
     *  @see #extendDescription(ToStringBuilder)
     *
     **/

    public String toString()
    {
        ToStringBuilder builder = new ToStringBuilder(this);

        builder.append(
            "name",
            _specification == null
                ? Tapestry.getMessage("AbstractEngine.unknown-specification")
                : _specification.getName());

        builder.append("dirty", _dirty);
        builder.append("locale", _locale);
        builder.append("stateful", _stateful);
        builder.append("visit", _visit);

        extendDescription(builder);

        return builder.toString();
    }

    /**
     *  Returns true if the reset service is curently enabled.
     *
     **/

    public boolean isResetServiceEnabled()
    {
        return _resetServiceEnabled;
    }

    /**
     *  Implemented by subclasses to return the names of the active pages
     *  (pages for which recorders exist).  May return the empty list,
     *  but should not return null.
     *
     **/

    abstract public Collection getActivePageNames();

    /**
     *  Gets the visit object, if it has been created already.
     *
     *  <p>
     *  If the visit is non-null then
     *  the {@link #isDirty()} flag is set (because
     *  the engine can't tell what the caller will
     *  <i>do</i> with the visit).
     *
     **/

    public Object getVisit()
    {
        if (_visit != null)
            markDirty();

        return _visit;
    }

    /**
     *  Gets the visit object, invoking {@link #createVisit(IRequestCycle)} to create
     *  it lazily if needed.  If cycle is null, the visit will not be lazily created.
     *
     *  <p>
     *  After creating the visit, but before returning,
     *  the {@link HttpSession} will be created, and
     *  {@link #setStateful()} will be invoked.
     *
     *  <p>
     *  Sets the {@link #isDirty()} flag, if the return value
     *  is not null.
     *
     *
     **/

    public Object getVisit(IRequestCycle cycle)
    {
        if (_visit == null && cycle != null)
        {
            _visit = createVisit(cycle);

            // Now that a visit object exists, we need to force the creation
            // of a HttpSession.

            cycle.getRequestContext().createSession();

            setStateful();
        }

        if (_visit != null)
            markDirty();

        return _visit;
    }

    /**
     *  Updates the visit object and
     *  sets the {@link #isDirty() dirty flag}.
     *
     **/

    public void setVisit(Object value)
    {
        _visit = value;

        markDirty();
    }

    public boolean getHasVisit()
    {
        return _visit != null;
    }

    /**
     *  Invoked to lazily create a new visit object when it is first
     *  referenced (by {@link #getVisit(IRequestCycle)}).  This implementation works
     *  by looking up the name of the class to instantiate
     *  in the {@link #getPropertySource() configuration}.
     *
     *  <p>Subclasses may want to overide this method if some other means
     *  of instantiating a visit object is required.
     **/

    protected Object createVisit(IRequestCycle cycle)
    {
        String visitClassName;
        Class visitClass;
        Object result = null;

        visitClassName = _propertySource.getPropertyValue(VISIT_CLASS_PROPERTY_NAME);

        if (LOG.isDebugEnabled())
            LOG.debug("Creating visit object as instance of " + visitClassName);

        visitClass = _resolver.findClass(visitClassName);

        try
        {
            result = visitClass.newInstance();
        }
        catch (Throwable t)
        {
            throw new ApplicationRuntimeException(
                Tapestry.format("AbstractEngine.unable-to-instantiate-visit", visitClassName),
                t);
        }

        return result;
    }

    /**
     *  Returns the global object for the application.  The global object is created at the start
     *  of the request ({@link #setupForRequest(RequestContext)} invokes
     *  {@link #createGlobal(RequestContext)} if needed),
     *  and is stored into the {@link ServletContext}.  All instances of the engine for
     *  the application share
     *  the global object; however, the global object is explicitly <em>not</em>
     *  replicated to other servers within
     *  a cluster.
     *
     *  @since 2.3
     *
     **/

    public Object getGlobal()
    {
        return _global;
    }

    public IScriptSource getScriptSource()
    {
        return _scriptSource;
    }

    public boolean isStateful()
    {
        return _stateful;
    }

    /**
     *  Invoked by subclasses to indicate that some state must now be stored
     *  in the engine (and that the engine should now be stored in the
     *  HttpSession).  The caller is responsible for actually creating
     *  the HttpSession (it will have access to the {@link RequestContext}).
     *
     *  @since 1.0.2
     *
     **/

    protected void setStateful()
    {
        _stateful = true;
    }

    /**
     *  Allows subclasses to include listener methods easily.
     *
     * @since 1.0.2
     **/

    public ListenerMap getListeners()
    {
        if (_listeners == null)
            _listeners = new ListenerMap(this);

        return _listeners;
    }

    private static class RedirectAnalyzer
    {
        private boolean _internal;
        private String _location;

        private RedirectAnalyzer(String location)
        {
            if (Tapestry.isBlank(location))
            {
                _location = "";
                _internal = true;

                return;
            }

            _location = location;

            _internal = !(location.startsWith("/") || location.indexOf("://") > 0);
        }

        public void process(IRequestCycle cycle)
        {
            RequestContext context = cycle.getRequestContext();

            if (_internal)
                forward(context);
            else
                redirect(context);
        }

        private void forward(RequestContext context)
        {
            HttpServletRequest request = context.getRequest();
            HttpServletResponse response = context.getResponse();

            RequestDispatcher dispatcher = request.getRequestDispatcher("/" + _location);

            if (dispatcher == null)
                throw new ApplicationRuntimeException(
                    Tapestry.format("AbstractEngine.unable-to-find-dispatcher", _location));

            try
            {
                dispatcher.forward(request, response);
            }
            catch (ServletException ex)
            {
                throw new ApplicationRuntimeException(
                    Tapestry.format("AbstractEngine.unable-to-forward", _location),
                    ex);
            }
            catch (IOException ex)
            {
                throw new ApplicationRuntimeException(
                    Tapestry.format("AbstractEngine.unable-to-forward", _location),
                    ex);
            }
        }

        private void redirect(RequestContext context)
        {
            HttpServletResponse response = context.getResponse();

            String finalURL = response.encodeRedirectURL(_location);

            try
            {
                response.sendRedirect(finalURL);
            }
            catch (IOException ex)
            {
                throw new ApplicationRuntimeException(
                    Tapestry.format("AbstractEngine.unable-to-redirect", _location),
                    ex);
            }
        }

    }

    /**
     *  Invoked when a {@link RedirectException} is thrown during the processing of a request.
     *
     *  @throws ApplicationRuntimeException if an {@link IOException},
     *  {@link ServletException} is thrown by the redirect, or if no
     *  {@link RequestDispatcher} can be found for local resource.
     *
     *  @since 2.2
     *
     **/

    protected void handleRedirectException(IRequestCycle cycle, RedirectException ex)
    {
        String location = ex.getRedirectLocation();

        if (LOG.isDebugEnabled())
            LOG.debug("Redirecting to: " + location);

        RedirectAnalyzer analyzer = new RedirectAnalyzer(location);

        analyzer.process(cycle);
    }

    /**
     *  Creates a Map of all the services available to the application.
     *
     *  <p>Note: the Map returned is not synchronized, on the theory that returned
     *  map is not further modified and therefore threadsafe.
     *
     **/

    private Map createServiceMap()
    {
        if (LOG.isDebugEnabled())
            LOG.debug("Creating service map.");

        ISpecificationSource source = getSpecificationSource();

        // Build the initial version of the result map,
        // where each value is the *name* of a class.

        Map result = new HashMap();

        // Do the framework first.

        addServices(source.getFrameworkNamespace(), result);

        // And allow the application to override the framework.

        addServices(source.getApplicationNamespace(), result);

        IResourceResolver resolver = getResourceResolver();

        Iterator i = result.entrySet().iterator();

        while (i.hasNext())
        {
            Map.Entry entry = (Map.Entry) i.next();

            String name = (String) entry.getKey();
            String className = (String) entry.getValue();

            if (LOG.isDebugEnabled())
                LOG.debug("Creating service " + name + " as instance of " + className);

            Class serviceClass = resolver.findClass(className);

            try
            {
                IEngineService service = (IEngineService) serviceClass.newInstance();
                String serviceName = service.getName();

                if (!service.getName().equals(name))
                    throw new ApplicationRuntimeException(
                        Tapestry.format(
                            "AbstractEngine.service-name-mismatch",
                            name,
                            className,
                            serviceName));

                // Replace the class name with an instance
                // of the named class.

                entry.setValue(service);
            }
            catch (InstantiationException ex)
            {
                String message =
                    Tapestry.format(
                        "AbstractEngine.unable-to-instantiate-service",
                        name,
                        className);

                LOG.error(message, ex);

                throw new ApplicationRuntimeException(message, ex);
            }
            catch (IllegalAccessException ex)
            {
                String message =
                    Tapestry.format(
                        "AbstractEngine.unable-to-instantiate-service",
                        name,
                        className);

                LOG.error(message, ex);

                throw new ApplicationRuntimeException(message, ex);
            }
        }

        // Result should not be modified after this point, for threadsafety issues.
        // We could wrap it in an unmodifiable, but for efficiency we don't.

        return result;
    }

    /**
     *  Locates all services in the namespace and adds key/value
     *  pairs to the map (name and class name).  Then recursively
     *  descendends into child namespaces to collect more
     *  service names.
     *
     *  @since 2.2
     *
     **/

    private void addServices(INamespace namespace, Map map)
    {
        List names = namespace.getServiceNames();
        int count = names.size();

        for (int i = 0; i < count; i++)
        {
            String name = (String) names.get(i);

            map.put(name, namespace.getServiceClassName(name));
        }

        List namespaceIds = namespace.getChildIds();
        count = namespaceIds.size();

        for (int i = 0; i < count; i++)
        {
            String id = (String) namespaceIds.get(i);

            addServices(namespace.getChildNamespace(id), map);
        }
    }

    /**
     *  @since 2.0.4
     *
     **/

    public IComponentMessagesSource getComponentMessagesSource()
    {
        return _stringsSource;
    }

    /**
     *  @since 2.2
     *
     **/

    public DataSqueezer getDataSqueezer()
    {
        return _dataSqueezer;
    }

    /**
     *
     *  Invoked from {@link #setupForRequest(RequestContext)} to create
     *  a {@link DataSqueezer} when needed (typically, just the very first time).
     *  This implementation returns a standard, new instance.
     *
     *  @since 2.2
     *
     **/

    public DataSqueezer createDataSqueezer()
    {
        return new DataSqueezer(_resolver);
    }

    /**
     *  Invoked from {@link #service(RequestContext)} to extract, from the URL,
     *  the name of the service.  The current implementation expects the first
     *  pathInfo element to be the service name.  At some point in the future,
     *  the method of constructing and parsing URLs may be abstracted into
     *  a developer-selected class.
     *
     *  <p>Subclasses may override this method if the application defines
     *  specific services with unusual URL encoding rules.
     *
     *  <p>This implementation simply extracts the value for
     *  query parameter {@link Tapestry#SERVICE_QUERY_PARAMETER_NAME}
     *  and extracts the service name from that.
     *
     *  <p>
     *  For supporting the JSP tags, this method first
     *  checks for attribute {@link Tapestry#TAG_SUPPORT_SERVICE_ATTRIBUTE}.  If non-null,
     *  then {@link Tapestry#TAGSUPPORT_SERVICE} is returned.
     *
     *  @since 2.2
     *
     **/

    protected String extractServiceName(RequestContext context)
    {
        if (context.getRequest().getAttribute(Tapestry.TAG_SUPPORT_SERVICE_ATTRIBUTE) != null)
            return Tapestry.TAGSUPPORT_SERVICE;

        String serviceData = context.getParameter(Tapestry.SERVICE_QUERY_PARAMETER_NAME);

        if (serviceData == null)
            return Tapestry.HOME_SERVICE;

        // The service name is anything before the first slash,
        // if there is one.

        int slashx = serviceData.indexOf('/');

        if (slashx < 0)
            return serviceData;

        return serviceData.substring(0, slashx);
    }

    /** @since 2.3 **/

    public IPropertySource getPropertySource()
    {
        return _propertySource;
    }

    /** @since 3.0.3 */
    
    public ResourceChecksumSource getResourceChecksumSource()
    {
        return _resourceChecksumSource;
    }
    
    /** @since 3.0 **/

    protected String getExceptionPageName()
    {
        return EXCEPTION_PAGE;
    }

    /** @since 3.0 **/

    protected String getStaleLinkPageName()
    {
        return STALE_LINK_PAGE;
    }

    /** @since 3.0 **/

    protected String getStaleSessionPageName()
    {
        return STALE_SESSION_PAGE;
    }

    /**
     *  Name of an application extension that can provide configuration properties.
     *
     *  @see #createPropertySource(RequestContext)
     *  @since 2.3
     *
     **/

    private static final String EXTENSION_PROPERTY_SOURCE_NAME =
        "org.apache.tapestry.property-source";

    /**
     *  Creates a shared property source that will be stored into
     *  the servlet context.
     *  Subclasses may override this method to build thier
     *  own search path.
     *
     *  <p>If the application specification contains an extension
     *  named "org.apache.tapestry.property-source" it is inserted
     *  in the search path just before
     *  the property source for JVM System Properties.  This is a simple
     *  hook at allow application-specific methods of obtaining
     *  configuration values (typically, from a database or from JMX,
     *  in some way).  Alternately, subclasses may
     *  override this method to provide whatever search path
     *  is appropriate.
     *
     *
     *  @since 2.3
     *
     **/

    protected IPropertySource createPropertySource(RequestContext context)
    {
        DelegatingPropertySource result = new DelegatingPropertySource();

        ApplicationServlet servlet = context.getServlet();
        IApplicationSpecification spec = servlet.getApplicationSpecification();

        result.addSource(new PropertyHolderPropertySource(spec));
        result.addSource(new ServletPropertySource(servlet.getServletConfig()));
        result.addSource(new ServletContextPropertySource(servlet.getServletContext()));

        if (spec.checkExtension(EXTENSION_PROPERTY_SOURCE_NAME))
        {
            IPropertySource source =
                (IPropertySource) spec.getExtension(
                    EXTENSION_PROPERTY_SOURCE_NAME,
                    IPropertySource.class);

            result.addSource(source);
        }

        result.addSource(SystemPropertiesPropertySource.getInstance());

        // Lastly, add a final source to handle "factory defaults".

        ResourceBundle bundle =
            ResourceBundle.getBundle("org.apache.tapestry.ConfigurationDefaults");

        result.addSource(new ResourceBundlePropertySource(bundle));

        return result;
    }

    /**
     *  Creates the shared Global object.  This implementation looks for an configuration
     *  property, <code>org.apache.tapestry.global-class</code>, and instantiates that class
     *  using a no-arguments
     *  constructor.  If the property is not defined, a synchronized
     *  {@link java.util.HashMap} is created.
     *
     *  @since 2.3
     *
     **/

    protected Object createGlobal(RequestContext context)
    {
        String className = _propertySource.getPropertyValue("org.apache.tapestry.global-class");

        if (className == null)
            return Collections.synchronizedMap(new HashMap());

        Class globalClass = _resolver.findClass(className);

        try
        {
            return globalClass.newInstance();
        }
        catch (Exception ex)
        {
            throw new ApplicationRuntimeException(
                Tapestry.format("AbstractEngine.unable-to-instantiate-global", className),
                ex);
        }
    }

    /**
     *  Returns an new instance of {@link Pool}, with the standard
     *  set of adaptors, plus {@link BSFManagerPoolableAdaptor} for
     *  {@link BSFManager}.
     *
     *  <p>Subclasses may override this
     *  method to configure the Pool differently.
     *
     *  @since 3.0
     *
     **/

    protected Pool createPool(RequestContext context)
    {
        Pool result = new Pool();

        result.registerAdaptor(BSFManager.class, new BSFManagerPoolableAdaptor());

        return result;
    }

    /** @since 3.0 **/

    public Pool getPool()
    {
        return _pool;
    }

    /**
     *
     * Invoked from {@link #setupForRequest(RequestContext)}.  Creates
     * a new instance of {@link DefaultComponentClassEnhancer}.  Subclasses
     * may override to return a different object.
     * 
     * <p>
     * Check the property <code>org.apache.tapestry.enhance.disable-abstract-method-validation</code>
     * and, if true, disables abstract method validation. This is used  in some
     * errant JDK's (such as IBM's 1.3.1) that incorrectly report concrete methods from
     * abstract classes as abstract.
     *
     * @since 3.0
     */

    protected IComponentClassEnhancer createComponentClassEnhancer(RequestContext context)
    {
        boolean disableValidation =
            "true".equals(
                _propertySource.getPropertyValue(
                    "org.apache.tapestry.enhance.disable-abstract-method-validation"));

        return new DefaultComponentClassEnhancer(_resolver, disableValidation);
    }

    /** @since 3.0 **/

    public IComponentClassEnhancer getComponentClassEnhancer()
    {
        return _enhancer;
    }

    /**
     *  Returns true if the engine has (potentially) changed
     *  state since the last time it was stored
     *  into the {@link javax.servlet.http.HttpSession}.  Various
     *  events set this property to true.
     *
     *  @since 3.0
     *
     **/

    public boolean isDirty()
    {
        return _dirty;
    }

    /**
     *  Invoked to set the dirty flag, indicating that the
     *  engine should be stored into the
     *  {@link javax.servlet.http.HttpSession}.
     *
     *
     *  @since 3.0
     *
     **/

    protected void markDirty()
    {
        if (!_dirty)
            LOG.debug("Setting dirty flag.");

        _dirty = true;
    }

    /**
     *
     *  Clears the dirty flag when a engine is stored into the
     *  {@link HttpSession}.
     *
     *
     *  @since 3.0
     *
     **/

    public void valueBound(HttpSessionBindingEvent arg0)
    {
        LOG.debug(_dirty ? "Clearing dirty flag." : "Dirty flag already cleared.");

        _dirty = false;
    }

    /**
     *  Does nothing.
     *
     *  @since 3.0
     *
     **/

    public void valueUnbound(HttpSessionBindingEvent arg0)
    {
    }

    /**
     *
     *  The encoding to be used if none has been defined using the output encoding property.
     *  Override this method to change the default.
     *
     *  @return the default output encoding
     *  @since 3.0
     *
     **/
    protected String getDefaultOutputEncoding()
    {
        return DEFAULT_OUTPUT_ENCODING;
    }

    /**
     *
     *  Returns the encoding to be used to generate the servlet responses and
     *  accept the servlet requests.
     *
     *  The encoding is defined using the org.apache.tapestry.output-encoding
     *  and is UTF-8 by default
     *
     *  @since 3.0
     *  @see org.apache.tapestry.IEngine#getOutputEncoding()
     *
     **/
    public String getOutputEncoding()
    {
        IPropertySource source = getPropertySource();

        String encoding = source.getPropertyValue(OUTPUT_ENCODING_PROPERTY_NAME);
        if (encoding == null)
            encoding = getDefaultOutputEncoding();

        return encoding;
    }

}
