MYFACESTEST-66 pre-configured containers
diff --git a/test12/src/main/java/org/apache/myfaces/test/mock/MockedJsfTestContainer.java b/test12/src/main/java/org/apache/myfaces/test/mock/MockedJsfTestContainer.java
index 2a33b25..d0d4735 100644
--- a/test12/src/main/java/org/apache/myfaces/test/mock/MockedJsfTestContainer.java
+++ b/test12/src/main/java/org/apache/myfaces/test/mock/MockedJsfTestContainer.java
@@ -18,11 +18,15 @@
  */
 package org.apache.myfaces.test.mock;
 
+import java.util.Locale;
 import javax.faces.FactoryFinder;
 import javax.faces.application.ApplicationFactory;
 import javax.faces.component.UIViewRoot;
 import javax.faces.lifecycle.LifecycleFactory;
 import javax.faces.render.RenderKitFactory;
+import javax.servlet.ServletRequestEvent;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
 import org.apache.myfaces.test.config.ResourceBundleVarNames;
 import org.apache.myfaces.test.mock.lifecycle.MockLifecycle;
 import org.apache.myfaces.test.mock.lifecycle.MockLifecycleFactory;
@@ -30,7 +34,7 @@
 /**
  *
  */
-public class MockedJsfTestContainer
+public class MockedJsfTestContainer implements HttpSessionListener
 {
 
     // ------------------------------------------------------------ Constructors
@@ -49,10 +53,10 @@
     /**
      * <p>Set up instance variables required by this test case.</p>
      */
-    public void setUp() throws Exception
+    public void setUp()
     {
         // Set up Servlet API Objects
-        setUpServletObjects();
+        setUpServletContext();
 
         // Set up JSF API Objects
         FactoryFinder.releaseFactories();
@@ -61,28 +65,40 @@
 
         setUpJSFObjects();
     }
+    
+    /**
+     * This method call both setUp() and startRequest().
+     */
+    public void setUpAll()
+    {
+        setUp();
+        startRequest();
+    }
+    
+    /**
+     * This method call both endRequest() and tearDown().
+     */
+    public void tearDownAll()
+    {
+        endRequest();
+        tearDown();
+    }
 
     /**
      * <p>Setup JSF object used for the test. By default it calls to the following
      * methods in this order:</p>
      * 
      * <ul>
-     * <li><code>setUpExternalContext();</code></li>
      * <li><code>setUpLifecycle();</code></li>
-     * <li><code>setUpFacesContext();</code></li>
-     * <li><code>setUpView();</code></li>
      * <li><code>setUpApplication();</code></li>
      * <li><code>setUpRenderKit();</code></li>
      * </ul>
      * 
      * @throws Exception
      */
-    protected void setUpJSFObjects() throws Exception
+    protected void setUpJSFObjects()
     {
-        setUpExternalContext();
         setUpLifecycle();
-        setUpFacesContext();
-        setUpView();
         setUpApplication();
         setUpRenderKit();
     }
@@ -93,30 +109,92 @@
      * <ul>
      * <li><code>config</code> (<code>MockServletConfig</code>)</li>
      * <li><code>servletContext</code> (<code>MockServletContext</code>)</li>
-     * <li><code>request</code> (<code>MockHttpServletRequest</code></li>
-     * <li><code>response</code> (<code>MockHttpServletResponse</code>)</li>
-     * <li><code>session</code> (<code>MockHttpSession</code>)</li>
      * </ul>
      * 
      * @throws Exception
      */
-    protected void setUpServletObjects() throws Exception
+    protected void setUpServletContext()
     {
         servletContext = new MockServletContext();
         config = new MockServletConfig(servletContext);
-        session = new MockHttpSession();
-        session.setServletContext(servletContext);
-        request = new MockHttpServletRequest(session);
+        webContainer = new MockWebContainer();
+        servletContext.setWebContainer(webContainer);
+        // Subscribe the container to receive session creation and destroy events.
+        webContainer.subscribeListener(this);
+    }
+    
+    /**
+     * <p>Setup servlet objects that will be used for the test:</p>
+     * 
+     * <ul>
+     * <li><code>request</code> (<code>MockHttpServletRequest</code></li>
+     * <li><code>response</code> (<code>MockHttpServletResponse</code>)</li>
+     * </ul>
+     * 
+     * @throws Exception
+     */
+    protected void setUpRequest()
+    {
+        request = lastSession == null ? 
+            new MockHttpServletRequest() : new MockHttpServletRequest(lastSession);
+        requestInitializedCalled = false;
         request.setServletContext(servletContext);
         response = new MockHttpServletResponse();
     }
+    
+    protected void doRequestInitialized()
+    {
+        if (!requestInitializedCalled)
+        {
+            webContainer.requestInitialized(new ServletRequestEvent(servletContext, request));
+            requestInitializedCalled = true;
+        }
+    }
+    
+    public void startRequest()
+    {
+        setUpRequest();        
+        doRequestInitialized();
+        
+        setUpFacesContext();
+        setUpDefaultView();
+    }
+    
+    public void startSession()
+    {
+        if (request != null)
+        {
+            //Create it indirectly through call to getSession(...)
+            request.getSession(true);
+        }
+    }
+    
+    public void endSession()
+    {
+        MockHttpSession session = (MockHttpSession) request.getSession(false);
+        if (session != null)
+        {
+            session.invalidate();
+        }
+    }
+    
+    public void sessionCreated(HttpSessionEvent se)
+    {
+        lastSession = (MockHttpSession) se.getSession();
+        //No op
+    }
 
+    public void sessionDestroyed(HttpSessionEvent se)
+    {
+        lastSession = null;
+    }
+    
     /**
      * <p>Set JSF factories using FactoryFinder method setFactory.</p>
      * 
      * @throws Exception
      */
-    protected void setFactories() throws Exception
+    protected void setFactories()
     {
         FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY,
                 "org.apache.myfaces.test.mock.MockApplicationFactory");
@@ -129,24 +207,12 @@
     }
 
     /**
-     * Setup the <code>externalContext</code> variable, using the 
-     * servlet variables already initialized.
-     * 
-     * @throws Exception
-     */
-    protected void setUpExternalContext() throws Exception
-    {
-        externalContext = new MockExternalContext(servletContext, request,
-                response);
-    }
-
-    /**
      * Setup the <code>lifecycle</code> and <code>lifecycleFactory</code>
      * variables.
      * 
      * @throws Exception
      */
-    protected void setUpLifecycle() throws Exception
+    protected void setUpLifecycle()
     {
         lifecycleFactory = (MockLifecycleFactory) FactoryFinder
                 .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
@@ -163,7 +229,7 @@
      * 
      * @throws Exception
      */
-    protected void setUpFacesContext() throws Exception
+    protected void setUpFacesContext()
     {
         facesContextFactory = (MockFacesContextFactory) FactoryFinder
                 .getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
@@ -174,6 +240,13 @@
             externalContext = (MockExternalContext) facesContext
                     .getExternalContext();
         }
+        else
+        {
+            externalContext = new MockExternalContext(servletContext, request,
+                response);
+            facesContext.setExternalContext(externalContext);
+        }
+        facesContext.setApplication(application);
     }
 
     /**
@@ -182,13 +255,19 @@
      * 
      * @throws Exception
      */
-    protected void setUpView() throws Exception
+    protected void setUpDefaultView()
     {
         UIViewRoot root = new UIViewRoot();
         root.setViewId("/viewId");
+        root.setLocale(getLocale());
         root.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
         facesContext.setViewRoot(root);
     }
+    
+    protected Locale getLocale()
+    {
+        return Locale.getDefault();
+    }    
 
     /**
      * Setup the <code>application</code> variable and before
@@ -197,12 +276,11 @@
      * 
      * @throws Exception
      */
-    protected void setUpApplication() throws Exception
+    protected void setUpApplication()
     {
         ApplicationFactory applicationFactory = (ApplicationFactory) FactoryFinder
                 .getFactory(FactoryFinder.APPLICATION_FACTORY);
         application = (MockApplication) applicationFactory.getApplication();
-        facesContext.setApplication(application);
     }
 
     /**
@@ -212,7 +290,7 @@
      * 
      * @throws Exception
      */
-    protected void setUpRenderKit() throws Exception
+    protected void setUpRenderKit()
     {
         RenderKitFactory renderKitFactory = (RenderKitFactory) FactoryFinder
                 .getFactory(FactoryFinder.RENDER_KIT_FACTORY);
@@ -221,19 +299,86 @@
                 renderKit);
     }
 
-    /**
-     * <p>Tear down instance variables required by this test case.</p>
-     */
-    public void tearDown() throws Exception
+    public MockApplication getApplication()
     {
+        return application;
+    }
+    
+    public MockExternalContext getExternalContext()
+    {
+        return externalContext;
+    }
 
-        application = null;
-        config = null;
-        externalContext = null;
+    public MockFacesContext getFacesContext()
+    {
+        return facesContext;
+    }
+
+    public MockHttpServletRequest getRequest()
+    {
+        return request;
+    }
+
+    public MockHttpServletResponse getResponse()
+    {
+        return response;
+    }
+
+    public MockServletContext getServletContext()
+    {
+        return servletContext;
+    }
+    
+    /**
+     * @return the webContainer
+     */
+    public MockWebContainer getWebContainer()
+    {
+        return webContainer;
+    }
+
+    /**
+     * This method call doRequestDestroyed() and then tearDownRequest(). 
+     */
+    public final void endRequest()
+    {
+        
+        doRequestDestroyed();
+        tearDownRequest();
+    }
+
+    protected void doRequestDestroyed()
+    {
+        if (request != null)
+        {
+            webContainer.requestDestroyed(new ServletRequestEvent(servletContext, request));
+        }
+    }
+
+    protected void tearDownRequest()
+    {
         if (facesContext != null)
         {
             facesContext.release();
         }
+        externalContext = null;
+        facesContext = null;
+        request = null;
+        response = null;
+    }
+    
+    /**
+     * <p>Tear down instance variables required by this test case.</p>
+     */
+    public void tearDown()
+    {
+        if (facesContext != null)
+        {
+            facesContext.release();
+        }
+        application = null;
+        config = null;
+        externalContext = null;
         facesContext = null;
         lifecycle = null;
         lifecycleFactory = null;
@@ -241,7 +386,8 @@
         request = null;
         response = null;
         servletContext = null;
-        session = null;
+        lastSession = null;
+        webContainer = null;
         FactoryFinder.releaseFactories();
         ResourceBundleVarNames.resetNames();
     }
@@ -258,8 +404,10 @@
     protected MockLifecycleFactory lifecycleFactory = null;
     protected MockRenderKit renderKit = null;
     protected MockHttpServletRequest request = null;
+    protected boolean requestInitializedCalled = false;
     protected MockHttpServletResponse response = null;
+    protected MockHttpSession lastSession = null;
     protected MockServletContext servletContext = null;
-    protected MockHttpSession session = null;
+    private MockWebContainer webContainer = null;
 
 }
diff --git a/test12/src/test/java/org/apache/myfaces/test/mock/MockedJsfTestContainerTestCase.java b/test12/src/test/java/org/apache/myfaces/test/mock/MockedJsfTestContainerTestCase.java
new file mode 100644
index 0000000..31eebe7
--- /dev/null
+++ b/test12/src/test/java/org/apache/myfaces/test/mock/MockedJsfTestContainerTestCase.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.test.mock;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class MockedJsfTestContainerTestCase
+{
+
+    @Test
+    public void testSimpleInit1()
+    {
+        MockedJsfTestContainer container = new MockedJsfTestContainer();
+        
+        container.setUp();
+        
+        Assert.assertNotNull(container.getServletContext());
+        Assert.assertNotNull(container.getApplication());
+        
+        container.tearDown();
+    }
+    
+    @Test
+    public void testSimpleInit2()
+    {
+        MockedJsfTestContainer container = new MockedJsfTestContainer();
+        
+        container.setUpAll();
+        
+        Assert.assertNotNull(container.getFacesContext());
+        Assert.assertNotNull(container.getExternalContext());
+        Assert.assertNotNull(container.getRequest());
+        Assert.assertNotNull(container.getResponse());
+        
+        container.tearDownAll();
+    }
+    
+    @Test
+    public void testSimpleInit3()
+    {
+        MockedJsfTestContainer container = new MockedJsfTestContainer();
+        
+        container.setUp();
+        
+        container.startRequest();
+        
+        container.startSession();
+        
+        MockHttpSession session1 = (MockHttpSession) 
+            container.getRequest().getSession(false);
+        
+        Assert.assertNotNull(session1);
+        
+        container.endRequest();
+        
+        container.startRequest();
+        
+        MockHttpSession session2 = (MockHttpSession) 
+            container.getRequest().getSession(false);
+        
+        Assert.assertNotNull(session2);
+        
+        Assert.assertEquals(session2, session1);
+        
+        container.endSession();
+        
+        container.endRequest();
+        
+        container.startRequest();
+        
+        MockHttpSession session3 = (MockHttpSession) 
+            container.getRequest().getSession(false);
+        
+        Assert.assertNull(session3);
+        
+        container.endRequest();
+    }
+
+}
diff --git a/test20/src/main/java/org/apache/myfaces/test/mock/MockedJsfTestContainer.java b/test20/src/main/java/org/apache/myfaces/test/mock/MockedJsfTestContainer.java
index 23e6601..aaa1d9b 100644
--- a/test20/src/main/java/org/apache/myfaces/test/mock/MockedJsfTestContainer.java
+++ b/test20/src/main/java/org/apache/myfaces/test/mock/MockedJsfTestContainer.java
@@ -18,11 +18,15 @@
  */
 package org.apache.myfaces.test.mock;
 
+import java.util.Locale;
 import javax.faces.FactoryFinder;
 import javax.faces.application.ApplicationFactory;
 import javax.faces.component.UIViewRoot;
 import javax.faces.lifecycle.LifecycleFactory;
 import javax.faces.render.RenderKitFactory;
+import javax.servlet.ServletRequestEvent;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
 import org.apache.myfaces.test.config.ResourceBundleVarNames;
 import org.apache.myfaces.test.mock.lifecycle.MockLifecycle;
 import org.apache.myfaces.test.mock.lifecycle.MockLifecycleFactory;
@@ -30,7 +34,7 @@
 /**
  *
  */
-public class MockedJsfTestContainer
+public class MockedJsfTestContainer implements HttpSessionListener
 {
 
     // ------------------------------------------------------------ Constructors
@@ -49,10 +53,10 @@
     /**
      * <p>Set up instance variables required by this test case.</p>
      */
-    public void setUp() throws Exception
+    public void setUp()
     {
         // Set up Servlet API Objects
-        setUpServletObjects();
+        setUpServletContext();
 
         // Set up JSF API Objects
         FactoryFinder.releaseFactories();
@@ -61,28 +65,34 @@
 
         setUpJSFObjects();
     }
+    
+    public void setUpAll()
+    {
+        setUp();
+        startRequest();
+    }
+    
+    public void tearDownAll()
+    {
+        endRequest();
+        tearDownRequest();
+    }
 
     /**
      * <p>Setup JSF object used for the test. By default it calls to the following
      * methods in this order:</p>
      * 
      * <ul>
-     * <li><code>setUpExternalContext();</code></li>
      * <li><code>setUpLifecycle();</code></li>
-     * <li><code>setUpFacesContext();</code></li>
-     * <li><code>setUpView();</code></li>
      * <li><code>setUpApplication();</code></li>
      * <li><code>setUpRenderKit();</code></li>
      * </ul>
      * 
      * @throws Exception
      */
-    protected void setUpJSFObjects() throws Exception
+    protected void setUpJSFObjects()
     {
-        setUpExternalContext();
         setUpLifecycle();
-        setUpFacesContext();
-        setUpView();
         setUpApplication();
         setUpRenderKit();
     }
@@ -93,30 +103,92 @@
      * <ul>
      * <li><code>config</code> (<code>MockServletConfig</code>)</li>
      * <li><code>servletContext</code> (<code>MockServletContext</code>)</li>
-     * <li><code>request</code> (<code>MockHttpServletRequest</code></li>
-     * <li><code>response</code> (<code>MockHttpServletResponse</code>)</li>
-     * <li><code>session</code> (<code>MockHttpSession</code>)</li>
      * </ul>
      * 
      * @throws Exception
      */
-    protected void setUpServletObjects() throws Exception
+    protected void setUpServletContext()
     {
         servletContext = new MockServletContext();
         config = new MockServletConfig(servletContext);
-        session = new MockHttpSession();
-        session.setServletContext(servletContext);
-        request = new MockHttpServletRequest(session);
+        webContainer = new MockWebContainer();
+        servletContext.setWebContainer(webContainer);
+        // Subscribe the container to receive session creation and destroy events.
+        webContainer.subscribeListener(this);
+    }
+    
+    /**
+     * <p>Setup servlet objects that will be used for the test:</p>
+     * 
+     * <ul>
+     * <li><code>request</code> (<code>MockHttpServletRequest</code></li>
+     * <li><code>response</code> (<code>MockHttpServletResponse</code>)</li>
+     * </ul>
+     * 
+     * @throws Exception
+     */
+    protected void setUpRequest()
+    {
+        request = lastSession == null ? 
+            new MockHttpServletRequest() : new MockHttpServletRequest(lastSession);
+        requestInitializedCalled = false;
         request.setServletContext(servletContext);
         response = new MockHttpServletResponse();
     }
+    
+    protected void doRequestInitialized()
+    {
+        if (!requestInitializedCalled)
+        {
+            webContainer.requestInitialized(new ServletRequestEvent(servletContext, request));
+            requestInitializedCalled = true;
+        }
+    }
+    
+    public void startRequest()
+    {
+        setUpRequest();        
+        doRequestInitialized();
+        
+        setUpFacesContext();
+        setUpDefaultView();
+    }
+    
+    public void startSession()
+    {
+        if (request != null)
+        {
+            //Create it indirectly through call to getSession(...)
+            request.getSession(true);
+        }
+    }
+    
+    public void endSession()
+    {
+        MockHttpSession session = (MockHttpSession) request.getSession(false);
+        if (session != null)
+        {
+            session.invalidate();
+        }
+    }
+    
+    public void sessionCreated(HttpSessionEvent se)
+    {
+        lastSession = (MockHttpSession) se.getSession();
+        //No op
+    }
 
+    public void sessionDestroyed(HttpSessionEvent se)
+    {
+        lastSession = null;
+    }
+    
     /**
      * <p>Set JSF factories using FactoryFinder method setFactory.</p>
      * 
      * @throws Exception
      */
-    protected void setFactories() throws Exception
+    protected void setFactories()
     {
         FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY,
                 "org.apache.myfaces.test.mock.MockApplicationFactory");
@@ -135,24 +207,12 @@
     }
 
     /**
-     * Setup the <code>externalContext</code> variable, using the 
-     * servlet variables already initialized.
-     * 
-     * @throws Exception
-     */
-    protected void setUpExternalContext() throws Exception
-    {
-        externalContext = new MockExternalContext(servletContext, request,
-                response);
-    }
-
-    /**
      * Setup the <code>lifecycle</code> and <code>lifecycleFactory</code>
      * variables.
      * 
      * @throws Exception
      */
-    protected void setUpLifecycle() throws Exception
+    protected void setUpLifecycle()
     {
         lifecycleFactory = (MockLifecycleFactory) FactoryFinder
                 .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
@@ -169,7 +229,7 @@
      * 
      * @throws Exception
      */
-    protected void setUpFacesContext() throws Exception
+    protected void setUpFacesContext()
     {
         facesContextFactory = (MockFacesContextFactory) FactoryFinder
                 .getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
@@ -180,6 +240,13 @@
             externalContext = (MockExternalContext) facesContext
                     .getExternalContext();
         }
+        else
+        {
+            externalContext = new MockExternalContext(servletContext, request,
+                response);
+            facesContext.setExternalContext(externalContext);
+        }
+        facesContext.setApplication(application);
     }
 
     /**
@@ -188,13 +255,19 @@
      * 
      * @throws Exception
      */
-    protected void setUpView() throws Exception
+    protected void setUpDefaultView()
     {
         UIViewRoot root = new UIViewRoot();
         root.setViewId("/viewId");
+        root.setLocale(getLocale());
         root.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
         facesContext.setViewRoot(root);
     }
+    
+    protected Locale getLocale()
+    {
+        return Locale.getDefault();
+    }    
 
     /**
      * Setup the <code>application</code> variable and before
@@ -203,12 +276,11 @@
      * 
      * @throws Exception
      */
-    protected void setUpApplication() throws Exception
+    protected void setUpApplication()
     {
         ApplicationFactory applicationFactory = (ApplicationFactory) FactoryFinder
                 .getFactory(FactoryFinder.APPLICATION_FACTORY);
         application = (MockApplication) applicationFactory.getApplication();
-        facesContext.setApplication(application);
     }
 
     /**
@@ -218,7 +290,7 @@
      * 
      * @throws Exception
      */
-    protected void setUpRenderKit() throws Exception
+    protected void setUpRenderKit()
     {
         RenderKitFactory renderKitFactory = (RenderKitFactory) FactoryFinder
                 .getFactory(FactoryFinder.RENDER_KIT_FACTORY);
@@ -227,19 +299,86 @@
                 renderKit);
     }
 
-    /**
-     * <p>Tear down instance variables required by this test case.</p>
-     */
-    public void tearDown() throws Exception
+    public MockApplication getApplication()
     {
+        return application;
+    }
+    
+    public MockExternalContext getExternalContext()
+    {
+        return externalContext;
+    }
 
-        application = null;
-        config = null;
-        externalContext = null;
+    public MockFacesContext getFacesContext()
+    {
+        return facesContext;
+    }
+
+    public MockHttpServletRequest getRequest()
+    {
+        return request;
+    }
+
+    public MockHttpServletResponse getResponse()
+    {
+        return response;
+    }
+
+    public MockServletContext getServletContext()
+    {
+        return servletContext;
+    }
+    
+    /**
+     * @return the webContainer
+     */
+    public MockWebContainer getWebContainer()
+    {
+        return webContainer;
+    }
+
+    /**
+     * This method call doRequestDestroyed() and then tearDownRequest(). 
+     */
+    public final void endRequest()
+    {
+        
+        doRequestDestroyed();
+        tearDownRequest();
+    }
+
+    protected void doRequestDestroyed()
+    {
+        if (request != null)
+        {
+            webContainer.requestDestroyed(new ServletRequestEvent(servletContext, request));
+        }
+    }
+
+    protected void tearDownRequest()
+    {
         if (facesContext != null)
         {
             facesContext.release();
         }
+        externalContext = null;
+        facesContext = null;
+        request = null;
+        response = null;
+    }
+    
+    /**
+     * <p>Tear down instance variables required by this test case.</p>
+     */
+    public void tearDown()
+    {
+        if (facesContext != null)
+        {
+            facesContext.release();
+        }
+        application = null;
+        config = null;
+        externalContext = null;
         facesContext = null;
         lifecycle = null;
         lifecycleFactory = null;
@@ -247,7 +386,8 @@
         request = null;
         response = null;
         servletContext = null;
-        session = null;
+        lastSession = null;
+        webContainer = null;
         FactoryFinder.releaseFactories();
         ResourceBundleVarNames.resetNames();
     }
@@ -264,8 +404,10 @@
     protected MockLifecycleFactory lifecycleFactory = null;
     protected MockRenderKit renderKit = null;
     protected MockHttpServletRequest request = null;
+    protected boolean requestInitializedCalled = false;
     protected MockHttpServletResponse response = null;
+    protected MockHttpSession lastSession = null;
     protected MockServletContext servletContext = null;
-    protected MockHttpSession session = null;
+    private MockWebContainer webContainer = null;
 
 }
diff --git a/test22/src/main/java/org/apache/myfaces/test/mock/MockedJsfTestContainer.java b/test22/src/main/java/org/apache/myfaces/test/mock/MockedJsfTestContainer.java
index 13b4bfa..0a54621 100644
--- a/test22/src/main/java/org/apache/myfaces/test/mock/MockedJsfTestContainer.java
+++ b/test22/src/main/java/org/apache/myfaces/test/mock/MockedJsfTestContainer.java
@@ -16,14 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.myfaces.test.mock;
 
+import java.util.Locale;
 import javax.faces.FactoryFinder;
 import javax.faces.application.ApplicationFactory;
 import javax.faces.component.UIViewRoot;
 import javax.faces.lifecycle.LifecycleFactory;
 import javax.faces.render.RenderKitFactory;
+import javax.servlet.ServletRequestEvent;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
 import org.apache.myfaces.test.config.ResourceBundleVarNames;
 import org.apache.myfaces.test.mock.lifecycle.MockLifecycle;
 import org.apache.myfaces.test.mock.lifecycle.MockLifecycleFactory;
@@ -31,7 +34,7 @@
 /**
  *
  */
-public class MockedJsfTestContainer
+public class MockedJsfTestContainer implements HttpSessionListener
 {
 
     // ------------------------------------------------------------ Constructors
@@ -50,10 +53,10 @@
     /**
      * <p>Set up instance variables required by this test case.</p>
      */
-    public void setUp() throws Exception
+    public void setUp()
     {
         // Set up Servlet API Objects
-        setUpServletObjects();
+        setUpServletContext();
 
         // Set up JSF API Objects
         FactoryFinder.releaseFactories();
@@ -62,28 +65,34 @@
 
         setUpJSFObjects();
     }
+    
+    public void setUpAll()
+    {
+        setUp();
+        startRequest();
+    }
+    
+    public void tearDownAll()
+    {
+        endRequest();
+        tearDownRequest();
+    }
 
     /**
      * <p>Setup JSF object used for the test. By default it calls to the following
      * methods in this order:</p>
      * 
      * <ul>
-     * <li><code>setUpExternalContext();</code></li>
      * <li><code>setUpLifecycle();</code></li>
-     * <li><code>setUpFacesContext();</code></li>
-     * <li><code>setUpView();</code></li>
      * <li><code>setUpApplication();</code></li>
      * <li><code>setUpRenderKit();</code></li>
      * </ul>
      * 
      * @throws Exception
      */
-    protected void setUpJSFObjects() throws Exception
+    protected void setUpJSFObjects()
     {
-        setUpExternalContext();
         setUpLifecycle();
-        setUpFacesContext();
-        setUpView();
         setUpApplication();
         setUpRenderKit();
     }
@@ -94,30 +103,92 @@
      * <ul>
      * <li><code>config</code> (<code>MockServletConfig</code>)</li>
      * <li><code>servletContext</code> (<code>MockServletContext</code>)</li>
-     * <li><code>request</code> (<code>MockHttpServletRequest</code></li>
-     * <li><code>response</code> (<code>MockHttpServletResponse</code>)</li>
-     * <li><code>session</code> (<code>MockHttpSession</code>)</li>
      * </ul>
      * 
      * @throws Exception
      */
-    protected void setUpServletObjects() throws Exception
+    protected void setUpServletContext()
     {
         servletContext = new MockServletContext();
         config = new MockServletConfig(servletContext);
-        session = new MockHttpSession();
-        session.setServletContext(servletContext);
-        request = new MockHttpServletRequest(session);
+        webContainer = new MockWebContainer();
+        servletContext.setWebContainer(webContainer);
+        // Subscribe the container to receive session creation and destroy events.
+        webContainer.subscribeListener(this);
+    }
+    
+    /**
+     * <p>Setup servlet objects that will be used for the test:</p>
+     * 
+     * <ul>
+     * <li><code>request</code> (<code>MockHttpServletRequest</code></li>
+     * <li><code>response</code> (<code>MockHttpServletResponse</code>)</li>
+     * </ul>
+     * 
+     * @throws Exception
+     */
+    protected void setUpRequest()
+    {
+        request = lastSession == null ? 
+            new MockHttpServletRequest() : new MockHttpServletRequest(lastSession);
+        requestInitializedCalled = false;
         request.setServletContext(servletContext);
         response = new MockHttpServletResponse();
     }
+    
+    protected void doRequestInitialized()
+    {
+        if (!requestInitializedCalled)
+        {
+            webContainer.requestInitialized(new ServletRequestEvent(servletContext, request));
+            requestInitializedCalled = true;
+        }
+    }
+    
+    public void startRequest()
+    {
+        setUpRequest();        
+        doRequestInitialized();
+        
+        setUpFacesContext();
+        setUpDefaultView();
+    }
+    
+    public void startSession()
+    {
+        if (request != null)
+        {
+            //Create it indirectly through call to getSession(...)
+            request.getSession(true);
+        }
+    }
+    
+    public void endSession()
+    {
+        MockHttpSession session = (MockHttpSession) request.getSession(false);
+        if (session != null)
+        {
+            session.invalidate();
+        }
+    }
+    
+    public void sessionCreated(HttpSessionEvent se)
+    {
+        lastSession = (MockHttpSession) se.getSession();
+        //No op
+    }
 
+    public void sessionDestroyed(HttpSessionEvent se)
+    {
+        lastSession = null;
+    }
+    
     /**
      * <p>Set JSF factories using FactoryFinder method setFactory.</p>
      * 
      * @throws Exception
      */
-    protected void setFactories() throws Exception
+    protected void setFactories()
     {
         FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY,
                 "org.apache.myfaces.test.mock.MockApplicationFactory");
@@ -138,24 +209,12 @@
     }
 
     /**
-     * Setup the <code>externalContext</code> variable, using the 
-     * servlet variables already initialized.
-     * 
-     * @throws Exception
-     */
-    protected void setUpExternalContext() throws Exception
-    {
-        externalContext = new MockExternalContext(servletContext, request,
-                response);
-    }
-
-    /**
      * Setup the <code>lifecycle</code> and <code>lifecycleFactory</code>
      * variables.
      * 
      * @throws Exception
      */
-    protected void setUpLifecycle() throws Exception
+    protected void setUpLifecycle()
     {
         lifecycleFactory = (MockLifecycleFactory) FactoryFinder
                 .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
@@ -172,7 +231,7 @@
      * 
      * @throws Exception
      */
-    protected void setUpFacesContext() throws Exception
+    protected void setUpFacesContext()
     {
         facesContextFactory = (MockFacesContextFactory) FactoryFinder
                 .getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
@@ -183,6 +242,13 @@
             externalContext = (MockExternalContext) facesContext
                     .getExternalContext();
         }
+        else
+        {
+            externalContext = new MockExternalContext(servletContext, request,
+                response);
+            facesContext.setExternalContext(externalContext);
+        }
+        facesContext.setApplication(application);
     }
 
     /**
@@ -191,13 +257,19 @@
      * 
      * @throws Exception
      */
-    protected void setUpView() throws Exception
+    protected void setUpDefaultView()
     {
         UIViewRoot root = new UIViewRoot();
         root.setViewId("/viewId");
+        root.setLocale(getLocale());
         root.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
         facesContext.setViewRoot(root);
     }
+    
+    protected Locale getLocale()
+    {
+        return Locale.getDefault();
+    }    
 
     /**
      * Setup the <code>application</code> variable and before
@@ -206,12 +278,11 @@
      * 
      * @throws Exception
      */
-    protected void setUpApplication() throws Exception
+    protected void setUpApplication()
     {
         ApplicationFactory applicationFactory = (ApplicationFactory) FactoryFinder
                 .getFactory(FactoryFinder.APPLICATION_FACTORY);
         application = (MockApplication) applicationFactory.getApplication();
-        facesContext.setApplication(application);
     }
 
     /**
@@ -221,7 +292,7 @@
      * 
      * @throws Exception
      */
-    protected void setUpRenderKit() throws Exception
+    protected void setUpRenderKit()
     {
         RenderKitFactory renderKitFactory = (RenderKitFactory) FactoryFinder
                 .getFactory(FactoryFinder.RENDER_KIT_FACTORY);
@@ -230,19 +301,86 @@
                 renderKit);
     }
 
-    /**
-     * <p>Tear down instance variables required by this test case.</p>
-     */
-    public void tearDown() throws Exception
+    public MockApplication getApplication()
     {
+        return application;
+    }
+    
+    public MockExternalContext getExternalContext()
+    {
+        return externalContext;
+    }
 
-        application = null;
-        config = null;
-        externalContext = null;
+    public MockFacesContext getFacesContext()
+    {
+        return facesContext;
+    }
+
+    public MockHttpServletRequest getRequest()
+    {
+        return request;
+    }
+
+    public MockHttpServletResponse getResponse()
+    {
+        return response;
+    }
+
+    public MockServletContext getServletContext()
+    {
+        return servletContext;
+    }
+    
+    /**
+     * @return the webContainer
+     */
+    public MockWebContainer getWebContainer()
+    {
+        return webContainer;
+    }
+
+    /**
+     * This method call doRequestDestroyed() and then tearDownRequest(). 
+     */
+    public final void endRequest()
+    {
+        
+        doRequestDestroyed();
+        tearDownRequest();
+    }
+
+    protected void doRequestDestroyed()
+    {
+        if (request != null)
+        {
+            webContainer.requestDestroyed(new ServletRequestEvent(servletContext, request));
+        }
+    }
+
+    protected void tearDownRequest()
+    {
         if (facesContext != null)
         {
             facesContext.release();
         }
+        externalContext = null;
+        facesContext = null;
+        request = null;
+        response = null;
+    }
+    
+    /**
+     * <p>Tear down instance variables required by this test case.</p>
+     */
+    public void tearDown()
+    {
+        if (facesContext != null)
+        {
+            facesContext.release();
+        }
+        application = null;
+        config = null;
+        externalContext = null;
         facesContext = null;
         lifecycle = null;
         lifecycleFactory = null;
@@ -250,7 +388,8 @@
         request = null;
         response = null;
         servletContext = null;
-        session = null;
+        lastSession = null;
+        webContainer = null;
         FactoryFinder.releaseFactories();
         ResourceBundleVarNames.resetNames();
     }
@@ -267,9 +406,10 @@
     protected MockLifecycleFactory lifecycleFactory = null;
     protected MockRenderKit renderKit = null;
     protected MockHttpServletRequest request = null;
+    protected boolean requestInitializedCalled = false;
     protected MockHttpServletResponse response = null;
+    protected MockHttpSession lastSession = null;
     protected MockServletContext servletContext = null;
-    protected MockHttpSession session = null;
-
+    private MockWebContainer webContainer = null;
 
 }
diff --git a/test22/src/test/java/org/apache/myfaces/test/mock/MockedJsfTestContainerTestCase.java b/test22/src/test/java/org/apache/myfaces/test/mock/MockedJsfTestContainerTestCase.java
new file mode 100644
index 0000000..31eebe7
--- /dev/null
+++ b/test22/src/test/java/org/apache/myfaces/test/mock/MockedJsfTestContainerTestCase.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.myfaces.test.mock;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class MockedJsfTestContainerTestCase
+{
+
+    @Test
+    public void testSimpleInit1()
+    {
+        MockedJsfTestContainer container = new MockedJsfTestContainer();
+        
+        container.setUp();
+        
+        Assert.assertNotNull(container.getServletContext());
+        Assert.assertNotNull(container.getApplication());
+        
+        container.tearDown();
+    }
+    
+    @Test
+    public void testSimpleInit2()
+    {
+        MockedJsfTestContainer container = new MockedJsfTestContainer();
+        
+        container.setUpAll();
+        
+        Assert.assertNotNull(container.getFacesContext());
+        Assert.assertNotNull(container.getExternalContext());
+        Assert.assertNotNull(container.getRequest());
+        Assert.assertNotNull(container.getResponse());
+        
+        container.tearDownAll();
+    }
+    
+    @Test
+    public void testSimpleInit3()
+    {
+        MockedJsfTestContainer container = new MockedJsfTestContainer();
+        
+        container.setUp();
+        
+        container.startRequest();
+        
+        container.startSession();
+        
+        MockHttpSession session1 = (MockHttpSession) 
+            container.getRequest().getSession(false);
+        
+        Assert.assertNotNull(session1);
+        
+        container.endRequest();
+        
+        container.startRequest();
+        
+        MockHttpSession session2 = (MockHttpSession) 
+            container.getRequest().getSession(false);
+        
+        Assert.assertNotNull(session2);
+        
+        Assert.assertEquals(session2, session1);
+        
+        container.endSession();
+        
+        container.endRequest();
+        
+        container.startRequest();
+        
+        MockHttpSession session3 = (MockHttpSession) 
+            container.getRequest().getSession(false);
+        
+        Assert.assertNull(session3);
+        
+        container.endRequest();
+    }
+
+}