//  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 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.*;
import org.apache.tapestry.asset.ResourceChecksumSource;
import org.apache.tapestry.asset.ResourceChecksumSourceImpl;
import org.apache.tapestry.enhance.DefaultComponentClassEnhancer;
import org.apache.tapestry.enhance.IEnhancedClassFactory;
import org.apache.tapestry.enhance.javassist.EnhancedClassFactory;
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.*;
import org.apache.tapestry.util.exception.ExceptionAnalyzer;
import org.apache.tapestry.util.io.DataSqueezer;
import org.apache.tapestry.util.pool.Pool;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;

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

    protected static final String CLASS_FACTORY_NAME = "org.apache.tapestry.enhance.javassist.EnhancedClassFactory";

    private transient IEnhancedClassFactory _classFactory;

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

    /**
     *  The name of the context attribute for the {@link ExpressionEvaluator} instance.
     *  The application's name is appended.
     **/
    protected static final String EXPRESSION_EVALUATOR_NAME = "org.apache.tapestry.engine.ExpressionEvaluator";

    private transient ExpressionEvaluator _expressionEvaluator;

    private transient ExpressionCache _expressionCache;

    private transient String _outputEncoding;

    /**
     *  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();
        _expressionCache.reset();
        _expressionEvaluator.reset();
        _outputEncoding = null;
    }

    /**
     *  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)
            {
                try
                {
                    context.getServlet().getLock().lock();

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

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

                        servletContext.setAttribute(name, _propertySource);
                    }
                } finally
                {
                    context.getServlet().getLock().unlock();
                }
            }
        }

        if (_classFactory == null)
        {
            String name = CLASS_FACTORY_NAME + ":" + servletName;

            _classFactory = (IEnhancedClassFactory) servletContext.getAttribute(name);

            if (_classFactory == null)
            {
                try
                {
                    context.getServlet().getLock().lock();

                    _classFactory = (IEnhancedClassFactory) servletContext.getAttribute(name);

                    if (_classFactory == null)
                    {
                        _classFactory = createClassFactory();

                        servletContext.setAttribute(name, _classFactory);
                    }
                } finally
                {
                    context.getServlet().getLock().unlock();
                }
            }
        }

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

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

            if (_enhancer == null)
            {
                try
                {
                    context.getServlet().getLock().lock();

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

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

                        servletContext.setAttribute(name, _enhancer);
                    }
                } finally
                {
                    context.getServlet().getLock().unlock();
                }
            }
        }

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

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

            if (_pool == null)
            {
                try
                {
                    context.getServlet().getLock().lock();

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

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

                        servletContext.setAttribute(name, _pool);
                    }
                } finally
                {
                    context.getServlet().getLock().unlock();
                }
            }
        }

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

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

            if (_templateSource == null)
            {
                try
                {
                    context.getServlet().getLock().lock();

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

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

                        servletContext.setAttribute(name, _templateSource);
                    }
                } finally
                {
                    context.getServlet().getLock().unlock();
                }
            }
        }

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

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

            if (_specificationSource == null)
            {
                try
                {
                    context.getServlet().getLock().lock();

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

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

                        servletContext.setAttribute(name, _specificationSource);
                    }
                } finally
                {
                    context.getServlet().getLock().unlock();
                }
            }
        }

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

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

            if (_pageSource == null)
            {
                try
                {
                    context.getServlet().getLock().lock();

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

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

                        servletContext.setAttribute(name, _pageSource);
                    }
                } finally
                {
                    context.getServlet().getLock().unlock();
                }
            }
        }

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

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

            if (_scriptSource == null)
            {
                try
                {
                    context.getServlet().getLock().lock();

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

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

                        servletContext.setAttribute(name, _scriptSource);
                    }
                } finally
                {
                    context.getServlet().getLock().unlock();
                }
            }
        }

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

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

            if (_serviceMap == null)
            {
                try
                {
                    context.getServlet().getLock().lock();

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

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

                        servletContext.setAttribute(name, _serviceMap);
                    }
                } finally
                {
                    context.getServlet().getLock().unlock();
                }
            }
        }

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

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

            if (_stringsSource == null)
            {
                try
                {
                    context.getServlet().getLock().lock();

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

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

                        servletContext.setAttribute(name, _stringsSource);
                    }
                } finally
                {
                    context.getServlet().getLock().unlock();
                }
            }
        }

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

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

            if (_dataSqueezer == null)
            {
                try
                {
                    context.getServlet().getLock().lock();

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

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

                        servletContext.setAttribute(name, _dataSqueezer);
                    }
                } finally
                {
                    context.getServlet().getLock().unlock();
                }
            }
        }

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

            _global = servletContext.getAttribute(name);

            if (_global == null)
            {
                try
                {
                    context.getServlet().getLock().lock();

                    _global = servletContext.getAttribute(name);

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

                        servletContext.setAttribute(name, _global);
                    }
                } finally
                {
                    context.getServlet().getLock().unlock();
                }
            }
        }

        if (_resourceChecksumSource == null)
        {
            String name = RESOURCE_CHECKSUM_SOURCE_NAME + ":" + servletName;

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

            if (_resourceChecksumSource == null)
            {
                try
                {
                    context.getServlet().getLock().lock();

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

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

                        servletContext.setAttribute(name, _resourceChecksumSource);
                    }
                } finally
                {
                    context.getServlet().getLock().unlock();
                }
            }
        }

        if (_expressionEvaluator == null)
        {
            String name = EXPRESSION_EVALUATOR_NAME + ":" + servletName;

            _expressionEvaluator = (ExpressionEvaluator) servletContext.getAttribute(name);

            if (_expressionEvaluator == null)
            {
                try
                {
                    context.getServlet().getLock().lock();

                    _expressionEvaluator = (ExpressionEvaluator) servletContext.getAttribute(name);

                    if (_expressionEvaluator == null)
                    {
                        _expressionEvaluator = createExpressionEvaluator();

                        servletContext.setAttribute(name, _expressionEvaluator);
                    }
                } finally
                {
                    context.getServlet().getLock().unlock();
                }
            }
        }

        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());
    }
    
    protected ExpressionEvaluator createExpressionEvaluator()
    {
        _expressionCache = (ExpressionCacheImpl) createExpressionCache();

        return new ExpressionEvaluatorImpl(_resolver, _classFactory, _expressionCache, _specification);
    }

    protected ExpressionCache createExpressionCache()
    {
        return new ExpressionCacheImpl();
    }

    /**
     *  Returns an object which can find resources and classes.
     *
     **/

    public IResourceResolver getResourceResolver()
    {
        return _resolver;
    }

    public ExpressionEvaluator getExpressionEvaluator()
    {
        return _expressionEvaluator;
    }

    /**
     *  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, _classFactory);
    }

    protected IEnhancedClassFactory createClassFactory()
    {
        return new EnhancedClassFactory(_resolver);
    }
    
    /** @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()
    {
        if (_outputEncoding != null)
            return _outputEncoding;
        
        IPropertySource source = getPropertySource();

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

        _outputEncoding = encoding;

        return _outputEncoding;
    }

}
