MYFACESTEST-67 Allow use servlet listeners inside mocks
diff --git a/test12/pom.xml b/test12/pom.xml
index 0e83217..a9ea4b3 100644
--- a/test12/pom.xml
+++ b/test12/pom.xml
@@ -91,6 +91,41 @@
             <version>1.0</version>
             <scope>provided</scope>
         </dependency>
+        
+        <dependency>
+            <groupId>org.apache.myfaces.core</groupId>
+            <artifactId>myfaces-api</artifactId>
+            <version>1.2.9</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.myfaces.core</groupId>
+            <artifactId>myfaces-impl</artifactId>
+            <version>1.2.9</version>
+            <scope>test</scope>
+        </dependency>
+        <!-- Servlet 2.5 -->
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-servlet_2.5_spec</artifactId>
+            <version>1.2</version>
+            <scope>provided</scope>
+        </dependency>
+        <!-- JSP 2.1 -->
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-jsp_2.1_spec</artifactId>
+            <version>1.0.1</version>
+            <scope>provided</scope>
+        </dependency>
+        <!-- EL 1.0 -->
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-el_1.0_spec</artifactId>
+            <version>1.0.2</version>
+            <scope>provided</scope>
+        </dependency>
+
 
     </dependencies>
 
@@ -144,144 +179,7 @@
         </plugin>
       </plugins>
     </reporting>
-    <!-- Allow building with JDK 1.4 as well as JDK 1.5,
-         the 1.4 profile caters only to JSF 1.1 -->
     <profiles>
-        <!-- 
-        <profile>
-            <id>myfaces-test-jdk14</id>
-            <activation>
-                <jdk>1.4</jdk>
-            </activation>
-            <dependencies>
-                <dependency>
-                    <groupId>org.apache.myfaces.core</groupId>
-                    <artifactId>myfaces-api</artifactId>
-                    <version>1.1.4</version>
-                    <scope>provided</scope>
-                </dependency>
-                <dependency>
-                    <groupId>org.apache.myfaces.core</groupId>
-                    <artifactId>myfaces-impl</artifactId>
-                    <version>1.1.4</version>
-                    <scope>test</scope>
-                </dependency>
-                <dependency>
-                    <groupId>javax.servlet</groupId>
-                    <artifactId>servlet-api</artifactId>
-                    <version>2.4</version>
-                    <scope>provided</scope>
-                </dependency>
-                <dependency>
-                    <groupId>javax.servlet</groupId>
-                    <artifactId>jsp-api</artifactId>
-                    <version>2.0</version>
-                    <scope>provided</scope>
-                </dependency>
-            </dependencies>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-compiler-plugin</artifactId>
-                        <configuration>
-                            <excludes>
-                                <exclude>org/apache/shale/test/el/**</exclude>
-                                <exclude>org/apache/shale/test/mock/*12.java</exclude>
-                            </excludes>
-                            <testExcludes>
-                                <testExclude>org/apache/shale/test/el/**</testExclude>
-                            </testExcludes>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-         -->
-
-        <profile>
-            <id>myfaces-test-jdk15</id>
-            <activation>
-                <jdk>1.5</jdk>
-            </activation>
-            <dependencies>
-                <dependency>
-                    <groupId>org.apache.myfaces.core</groupId>
-                    <artifactId>myfaces-api</artifactId>
-                    <version>1.2.9</version>
-                    <scope>provided</scope>
-                </dependency>
-                <dependency>
-                    <groupId>org.apache.myfaces.core</groupId>
-                    <artifactId>myfaces-impl</artifactId>
-                    <version>1.2.9</version>
-                    <scope>test</scope>
-                </dependency>
-                <!-- Servlet 2.5 -->
-                <dependency>
-                    <groupId>org.apache.geronimo.specs</groupId>
-                    <artifactId>geronimo-servlet_2.5_spec</artifactId>
-                    <version>1.2</version>
-                    <scope>provided</scope>
-                </dependency>
-                <!-- JSP 2.1 -->
-                <dependency>
-                    <groupId>org.apache.geronimo.specs</groupId>
-                    <artifactId>geronimo-jsp_2.1_spec</artifactId>
-                    <version>1.0.1</version>
-                    <scope>provided</scope>
-                </dependency>
-                <!-- EL 1.0 -->
-                <dependency>
-                    <groupId>org.apache.geronimo.specs</groupId>
-                    <artifactId>geronimo-el_1.0_spec</artifactId>
-                    <version>1.0.2</version>
-                    <scope>provided</scope>
-                </dependency>
-            </dependencies>
-        </profile>
-
-        <profile>
-            <id>myfaces-test-jdk16</id>
-            <activation>
-                <jdk>1.6</jdk>
-            </activation>
-            <dependencies>
-                <dependency>
-                    <groupId>org.apache.myfaces.core</groupId>
-                    <artifactId>myfaces-api</artifactId>
-                    <version>1.2.9</version>
-                    <scope>provided</scope>
-                </dependency>
-                <dependency>
-                    <groupId>org.apache.myfaces.core</groupId>
-                    <artifactId>myfaces-impl</artifactId>
-                    <version>1.2.9</version>
-                    <scope>test</scope>
-                </dependency>
-                <!-- Servlet 2.5 -->
-                <dependency>
-                    <groupId>org.apache.geronimo.specs</groupId>
-                    <artifactId>geronimo-servlet_2.5_spec</artifactId>
-                    <version>1.2</version>
-                    <scope>provided</scope>
-                </dependency>
-                <!-- JSP 2.1 -->
-                <dependency>
-                    <groupId>org.apache.geronimo.specs</groupId>
-                    <artifactId>geronimo-jsp_2.1_spec</artifactId>
-                    <version>1.0.1</version>
-                    <scope>provided</scope>
-                </dependency>
-                <!-- EL 1.0 -->
-                <dependency>
-                    <groupId>org.apache.geronimo.specs</groupId>
-                    <artifactId>geronimo-el_1.0_spec</artifactId>
-                    <version>1.0.2</version>
-                    <scope>provided</scope>
-                </dependency>
-            </dependencies>
-        </profile>
         <profile>
             <id>generate-assembly</id>
             <activation>
diff --git a/test12/src/main/java/org/apache/myfaces/test/mock/MockHttpServletRequest.java b/test12/src/main/java/org/apache/myfaces/test/mock/MockHttpServletRequest.java
index 6640517..f42445b 100644
--- a/test12/src/main/java/org/apache/myfaces/test/mock/MockHttpServletRequest.java
+++ b/test12/src/main/java/org/apache/myfaces/test/mock/MockHttpServletRequest.java
@@ -26,7 +26,6 @@
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.Date;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -45,6 +44,7 @@
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionEvent;
 
 /**
  * <p>Mock implementation of <code>HttpServletContext</code>.</p>
@@ -261,6 +261,15 @@
     {
         this.method = method;
     }
+    
+    protected MockWebContainer getWebContainer()
+    {
+        if (this.servletContext instanceof MockServletContext)
+        {
+            return ((MockServletContext)this.servletContext).getWebContainer();
+        }
+        return null;
+    }
 
     // ------------------------------------------------------ Instance Variables
 
@@ -520,6 +529,12 @@
         if (create && (session == null))
         {
             this.session = new MockHttpSession(this.servletContext);
+            MockWebContainer container = getWebContainer();
+            if (container != null)
+            {
+                HttpSessionEvent se = new HttpSessionEvent(this.session);
+                container.sessionCreated(se);
+            }
         }
         return session;
 
diff --git a/test12/src/main/java/org/apache/myfaces/test/mock/MockHttpSession.java b/test12/src/main/java/org/apache/myfaces/test/mock/MockHttpSession.java
index 37acb88..2efe3be 100644
--- a/test12/src/main/java/org/apache/myfaces/test/mock/MockHttpSession.java
+++ b/test12/src/main/java/org/apache/myfaces/test/mock/MockHttpSession.java
@@ -27,7 +27,9 @@
 import javax.servlet.http.HttpSession;
 import javax.servlet.http.HttpSessionAttributeListener;
 import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionBindingListener;
 import javax.servlet.http.HttpSessionContext;
+import javax.servlet.http.HttpSessionEvent;
 
 /**
  * <p>Mock implementation of <code>HttpSession</code>.</p>
@@ -74,7 +76,15 @@
      */
     public void addAttributeListener(HttpSessionAttributeListener listener)
     {
-        attributeListeners.add(listener);
+        MockWebContainer container = getWebContainer();
+        if (container == null)
+        {
+            attributeListeners.add(listener);
+        }
+        else
+        {
+            container.subscribeListener(listener);
+        }
     }
 
     /**
@@ -89,6 +99,15 @@
 
     }
 
+    protected MockWebContainer getWebContainer()
+    {
+        if (this.servletContext instanceof MockServletContext)
+        {
+            return ((MockServletContext)this.servletContext).getWebContainer();
+        }
+        return null;
+    }
+
     // ------------------------------------------------------ Instance Variables
 
     private List attributeListeners = new ArrayList();
@@ -96,6 +115,7 @@
     private String id = "123";
     private ServletContext servletContext = null;
     private boolean invalid = false;
+    private MockWebContainer webContainer;
 
     // ---------------------------------------------------------- Public Methods
 
@@ -203,6 +223,13 @@
 
         attributes.clear();
         invalid = true;
+        
+        MockWebContainer container = getWebContainer();
+        if (container != null)
+        {
+            HttpSessionEvent se = new HttpSessionEvent(this);
+            container.sessionDestroyed(se);
+        }
     }
 
     /** {@inheritDoc} */
@@ -262,7 +289,7 @@
         {
             Object oldValue = attributes.get(name);
             attributes.put(name, value);
-            fireAttributeReplaced(name, oldValue);
+            fireAttributeReplaced(name, oldValue, value);
         }
         else
         {
@@ -290,18 +317,36 @@
      */
     private void fireAttributeAdded(String key, Object value)
     {
-        if (attributeListeners.size() < 1)
+        MockWebContainer container = getWebContainer();
+        if (container == null)
         {
-            return;
+            if (attributeListeners.size() < 1)
+            {
+                return;
+            }
+            HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key,
+                    value);
+            if (value instanceof HttpSessionBindingListener)
+            {
+                ((HttpSessionBindingListener)value).valueBound(event);
+            }
+            Iterator listeners = attributeListeners.iterator();
+            while (listeners.hasNext())
+            {
+                HttpSessionAttributeListener listener = (HttpSessionAttributeListener) listeners
+                        .next();
+                listener.attributeAdded(event);
+            }
         }
-        HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key,
-                value);
-        Iterator listeners = attributeListeners.iterator();
-        while (listeners.hasNext())
+        else
         {
-            HttpSessionAttributeListener listener = (HttpSessionAttributeListener) listeners
-                    .next();
-            listener.attributeAdded(event);
+            HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key,
+                    value);
+            if (value instanceof HttpSessionBindingListener)
+            {
+                ((HttpSessionBindingListener)value).valueBound(event);
+            }            
+            container.attributeAdded(event);
         }
     }
 
@@ -313,18 +358,36 @@
      */
     private void fireAttributeRemoved(String key, Object value)
     {
-        if (attributeListeners.size() < 1)
+        MockWebContainer container = getWebContainer();
+        if (container == null)
         {
-            return;
+            if (attributeListeners.size() < 1)
+            {
+                return;
+            }
+            HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key,
+                    value);
+            if (value instanceof HttpSessionBindingListener)
+            {
+                ((HttpSessionBindingListener)value).valueUnbound(event);
+            }            
+            Iterator listeners = attributeListeners.iterator();
+            while (listeners.hasNext())
+            {
+                HttpSessionAttributeListener listener = (HttpSessionAttributeListener) listeners
+                        .next();
+                listener.attributeRemoved(event);
+            }
         }
-        HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key,
-                value);
-        Iterator listeners = attributeListeners.iterator();
-        while (listeners.hasNext())
+        else
         {
-            HttpSessionAttributeListener listener = (HttpSessionAttributeListener) listeners
-                    .next();
-            listener.attributeRemoved(event);
+            HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key,
+                    value);
+            if (value instanceof HttpSessionBindingListener)
+            {
+                ((HttpSessionBindingListener)value).valueUnbound(event);
+            }
+            container.attributeRemoved(event);
         }
     }
 
@@ -334,20 +397,44 @@
      * @param key Attribute whose value was replaced
      * @param value The original value
      */
-    private void fireAttributeReplaced(String key, Object value)
+    private void fireAttributeReplaced(String key, Object oldValue, Object value)
     {
-        if (attributeListeners.size() < 1)
+        if (oldValue instanceof HttpSessionBindingListener)
         {
-            return;
+            HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key,
+                    oldValue);
+            ((HttpSessionBindingListener)value).valueUnbound(event);
         }
-        HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key,
-                value);
-        Iterator listeners = attributeListeners.iterator();
-        while (listeners.hasNext())
+        MockWebContainer container = getWebContainer();
+        if (container == null)
+        {        
+            if (attributeListeners.size() < 1)
+            {
+                return;
+            }
+            HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key,
+                    value);
+            if (value instanceof HttpSessionBindingListener)
+            {
+                ((HttpSessionBindingListener)value).valueBound(event);
+            }            
+            Iterator listeners = attributeListeners.iterator();
+            while (listeners.hasNext())
+            {
+                HttpSessionAttributeListener listener = (HttpSessionAttributeListener) listeners
+                        .next();
+                listener.attributeReplaced(event);
+            }
+        }
+        else
         {
-            HttpSessionAttributeListener listener = (HttpSessionAttributeListener) listeners
-                    .next();
-            listener.attributeReplaced(event);
+            HttpSessionBindingEvent event = new HttpSessionBindingEvent(this, key,
+                    value);
+            if (value instanceof HttpSessionBindingListener)
+            {
+                ((HttpSessionBindingListener)value).valueBound(event);
+            }
+            container.attributeReplaced(event);
         }
     }
 
diff --git a/test12/src/main/java/org/apache/myfaces/test/mock/MockHttpSessionProxy.java b/test12/src/main/java/org/apache/myfaces/test/mock/MockHttpSessionProxy.java
new file mode 100644
index 0000000..181da0d
--- /dev/null
+++ b/test12/src/main/java/org/apache/myfaces/test/mock/MockHttpSessionProxy.java
@@ -0,0 +1,205 @@
+/*
+ * 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 java.util.Enumeration;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpSessionAttributeListener;
+import javax.servlet.http.HttpSessionContext;
+import javax.servlet.http.HttpSessionEvent;
+
+/**
+ * Proxy used to trigger session creation when it is accessed
+ */
+public class MockHttpSessionProxy extends MockHttpSession
+{
+    private MockServletContext servletContext;
+    private MockHttpServletRequest request;
+    private MockHttpSession delegate;
+
+    public MockHttpSessionProxy(MockServletContext servletContext,
+        MockHttpServletRequest request)
+    {
+        super(servletContext);
+        this.servletContext = servletContext;
+    }
+    
+    @Override
+    public void addAttributeListener(HttpSessionAttributeListener listener)
+    {
+        getWrapped().addAttributeListener(listener);
+    }
+
+    @Override
+    public void setServletContext(ServletContext servletContext)
+    {
+        if (servletContext instanceof MockServletContext)
+        {
+            this.servletContext = (MockServletContext) servletContext;
+        }
+        getWrapped().setServletContext(servletContext);
+    }
+
+    @Override
+    public void setId(String id)
+    {
+        getWrapped().setId(id);
+    }
+
+    @Override
+    public Object getAttribute(String name)
+    {
+        return getWrapped().getAttribute(name);
+    }
+
+    @Override
+    public Enumeration getAttributeNames()
+    {
+        return getWrapped().getAttributeNames();
+    }
+
+    @Override
+    public long getCreationTime()
+    {
+        return getWrapped().getCreationTime();
+    }
+
+    @Override
+    public String getId()
+    {
+        return getWrapped().getId();
+    }
+
+    @Override
+    public long getLastAccessedTime()
+    {
+        return getWrapped().getLastAccessedTime();
+    }
+
+    @Override
+    public int getMaxInactiveInterval()
+    {
+        return getWrapped().getMaxInactiveInterval();
+    }
+
+    @Override
+    public ServletContext getServletContext()
+    {
+        return servletContext == null ? getWrapped().getServletContext() : servletContext;
+    }
+
+    @Override
+    public HttpSessionContext getSessionContext()
+    {
+        return getWrapped().getSessionContext();
+    }
+
+    @Override
+    public Object getValue(String name)
+    {
+        return getWrapped().getValue(name);
+    }
+
+    @Override
+    public String[] getValueNames()
+    {
+        return getWrapped().getValueNames();
+    }
+
+    @Override
+    public void invalidate()
+    {
+        getWrapped().invalidate();
+    }
+
+    @Override
+    public boolean isNew()
+    {
+        return getWrapped().isNew();
+    }
+
+    @Override
+    public void putValue(String name, Object value)
+    {
+        getWrapped().putValue(name, value);
+    }
+
+    @Override
+    public void removeAttribute(String name)
+    {
+        getWrapped().removeAttribute(name);
+    }
+
+    @Override
+    public void removeValue(String name)
+    {
+        getWrapped().removeValue(name);
+    }
+
+    @Override
+    public void setAttribute(String name, Object value)
+    {
+        getWrapped().setAttribute(name, value);
+    }
+
+    @Override
+    public void setMaxInactiveInterval(int interval)
+    {
+        getWrapped().setMaxInactiveInterval(interval);
+    }
+    
+    public MockHttpSession getWrapped()
+    {
+        if (delegate == null)
+        {
+            if (request != null)
+            {
+                delegate = (MockHttpSession) request.getSession(true);
+            }
+            else
+            {
+                delegate = new MockHttpSession(this.servletContext);
+                MockWebContainer container = getWebContainer();
+                if (container != null)
+                {
+                    HttpSessionEvent se = new HttpSessionEvent(delegate);
+                    container.sessionCreated(se);
+                }
+            }
+        }
+        return delegate;
+    }
+
+    /**
+     * @return the request
+     */
+    public MockHttpServletRequest getRequest()
+    {
+        return request;
+    }
+
+    /**
+     * @param request the request to set
+     */
+    public void setRequest(MockHttpServletRequest request)
+    {
+        this.request = request;
+    }
+}
diff --git a/test12/src/main/java/org/apache/myfaces/test/mock/MockServletContext.java b/test12/src/main/java/org/apache/myfaces/test/mock/MockServletContext.java
index 9b61510..e189b3a 100644
--- a/test12/src/main/java/org/apache/myfaces/test/mock/MockServletContext.java
+++ b/test12/src/main/java/org/apache/myfaces/test/mock/MockServletContext.java
@@ -112,7 +112,25 @@
      */
     public void addAttributeListener(ServletContextAttributeListener listener)
     {
-        attributeListeners.add(listener);
+        MockWebContainer container = getWebContainer();
+        if (container == null)
+        {
+            attributeListeners.add(listener);
+        }
+        else
+        {
+            container.subscribeListener(listener);
+        }
+    }
+    
+    public MockWebContainer getWebContainer()
+    {
+        return webContainer;
+    }
+    
+    public void setWebContainer(MockWebContainer container)
+    {
+        webContainer = container;
     }
 
     // ------------------------------------------------------ Instance Variables
@@ -122,6 +140,7 @@
     private Hashtable mimeTypes = new Hashtable();
     private Hashtable parameters = new Hashtable();
     private List attributeListeners = new ArrayList();
+    private MockWebContainer webContainer;
 
     // -------------------------------------------------- ServletContext Methods
 
@@ -464,18 +483,28 @@
      */
     void fireAttributeAdded(String key, Object value)
     {
-        if (attributeListeners.size() < 1)
-        {
-            return;
+        MockWebContainer container = getWebContainer();
+        if (container == null)
+        {        
+            if (attributeListeners.size() < 1)
+            {
+                return;
+            }
+            ServletContextAttributeEvent event = new ServletContextAttributeEvent(
+                    this, key, value);
+            Iterator listeners = attributeListeners.iterator();
+            while (listeners.hasNext())
+            {
+                ServletContextAttributeListener listener = (ServletContextAttributeListener) listeners
+                        .next();
+                listener.attributeAdded(event);
+            }
         }
-        ServletContextAttributeEvent event = new ServletContextAttributeEvent(
-                this, key, value);
-        Iterator listeners = attributeListeners.iterator();
-        while (listeners.hasNext())
+        else
         {
-            ServletContextAttributeListener listener = (ServletContextAttributeListener) listeners
-                    .next();
-            listener.attributeAdded(event);
+            ServletContextAttributeEvent event = new ServletContextAttributeEvent(
+                    this, key, value);
+            container.attributeAdded(event);
         }
     }
 
@@ -487,18 +516,28 @@
      */
     void fireAttributeRemoved(String key, Object value)
     {
-        if (attributeListeners.size() < 1)
+        MockWebContainer container = getWebContainer();
+        if (container == null)
         {
-            return;
+            if (attributeListeners.size() < 1)
+            {
+                return;
+            }
+            ServletContextAttributeEvent event = new ServletContextAttributeEvent(
+                    this, key, value);
+            Iterator listeners = attributeListeners.iterator();
+            while (listeners.hasNext())
+            {
+                ServletContextAttributeListener listener = (ServletContextAttributeListener) listeners
+                        .next();
+                listener.attributeRemoved(event);
+            }
         }
-        ServletContextAttributeEvent event = new ServletContextAttributeEvent(
-                this, key, value);
-        Iterator listeners = attributeListeners.iterator();
-        while (listeners.hasNext())
+        else
         {
-            ServletContextAttributeListener listener = (ServletContextAttributeListener) listeners
-                    .next();
-            listener.attributeRemoved(event);
+            ServletContextAttributeEvent event = new ServletContextAttributeEvent(
+                    this, key, value);
+            container.attributeRemoved(event);
         }
     }
 
@@ -510,18 +549,28 @@
      */
     void fireAttributeReplaced(String key, Object value)
     {
-        if (attributeListeners.size() < 1)
+        MockWebContainer container = getWebContainer();
+        if (container == null)
         {
-            return;
+            if (attributeListeners.size() < 1)
+            {
+                return;
+            }
+            ServletContextAttributeEvent event = new ServletContextAttributeEvent(
+                    this, key, value);
+            Iterator listeners = attributeListeners.iterator();
+            while (listeners.hasNext())
+            {
+                ServletContextAttributeListener listener = (ServletContextAttributeListener) listeners
+                        .next();
+                listener.attributeReplaced(event);
+            }
         }
-        ServletContextAttributeEvent event = new ServletContextAttributeEvent(
-                this, key, value);
-        Iterator listeners = attributeListeners.iterator();
-        while (listeners.hasNext())
+        else
         {
-            ServletContextAttributeListener listener = (ServletContextAttributeListener) listeners
-                    .next();
-            listener.attributeReplaced(event);
+            ServletContextAttributeEvent event = new ServletContextAttributeEvent(
+                    this, key, value);            
+            container.attributeReplaced(event);
         }
     }
 }
diff --git a/test12/src/main/java/org/apache/myfaces/test/mock/MockWebContainer.java b/test12/src/main/java/org/apache/myfaces/test/mock/MockWebContainer.java
new file mode 100644
index 0000000..108bcea
--- /dev/null
+++ b/test12/src/main/java/org/apache/myfaces/test/mock/MockWebContainer.java
@@ -0,0 +1,299 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.List;
+import javax.servlet.ServletContextAttributeEvent;
+import javax.servlet.ServletContextAttributeListener;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.ServletRequestAttributeEvent;
+import javax.servlet.ServletRequestAttributeListener;
+import javax.servlet.ServletRequestEvent;
+import javax.servlet.ServletRequestListener;
+import javax.servlet.http.HttpSessionAttributeListener;
+import javax.servlet.http.HttpSessionBindingEvent;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+
+/**
+ * 
+ */
+public class MockWebContainer 
+    implements ServletContextListener, ServletContextAttributeListener,
+               ServletRequestListener, ServletRequestAttributeListener,
+               HttpSessionListener, HttpSessionAttributeListener
+{
+    
+    // context
+    private List<ServletContextListener> contextListeners;
+    private List<ServletContextAttributeListener> contextAttributeListeners;
+    
+    // request
+    private List<ServletRequestListener> requestListeners;
+    private List<ServletRequestAttributeListener> requestAttributeListeners;
+    
+    // session
+    private List<HttpSessionListener> sessionListeners;
+    private List<HttpSessionAttributeListener> sessionAttributeListeners;
+
+    public MockWebContainer()
+    {
+    }
+    
+    /**
+     * Create an instance of the passes class and subscribe it as as servlet listener
+     * 
+     * @param listenerClassName
+     * @throws ClassNotFoundException
+     * @throws InstantiationException
+     * @throws IllegalAccessException 
+     */
+    public void subscribeListener(String listenerClassName) 
+        throws ClassNotFoundException, InstantiationException, IllegalAccessException
+    {
+        Class clazz = this.getClass().getClassLoader().loadClass(listenerClassName);
+        Object instance = clazz.newInstance();
+        subscribeListener(instance);
+    }
+    
+    /**
+     * Subscribe a servlet listener
+     * 
+     * @param listener 
+     */
+    public void subscribeListener(Object listener)
+    {
+        if (listener instanceof ServletContextListener)
+        {
+            if (contextListeners == null)
+            {
+                contextListeners = new ArrayList<ServletContextListener>();
+            }
+            contextListeners.add((ServletContextListener)listener);
+        }
+        if (listener instanceof ServletContextAttributeListener)
+        {
+            if (contextAttributeListeners == null)
+            {
+                contextAttributeListeners = new ArrayList<ServletContextAttributeListener>();
+            }
+            contextAttributeListeners.add((ServletContextAttributeListener)listener);
+        }
+        if (listener instanceof ServletRequestListener)
+        {
+            if (requestListeners == null)
+            {
+                requestListeners = new ArrayList<ServletRequestListener>();
+            }
+            requestListeners.add((ServletRequestListener)listener);
+        }
+        if (listener instanceof ServletRequestAttributeListener)
+        {
+            if (requestAttributeListeners == null)
+            {
+                requestAttributeListeners = new ArrayList<ServletRequestAttributeListener>();
+            }
+            requestAttributeListeners.add((ServletRequestAttributeListener)listener);
+        }
+        if (listener instanceof HttpSessionListener)
+        {
+            if (sessionListeners == null)
+            {
+                sessionListeners = new ArrayList<HttpSessionListener>();
+            }
+            sessionListeners.add((HttpSessionListener)listener);
+        }
+        if (listener instanceof HttpSessionAttributeListener)
+        {
+            if (sessionAttributeListeners == null)
+            {
+                sessionAttributeListeners = new ArrayList<HttpSessionAttributeListener>();
+            }
+            sessionAttributeListeners.add((HttpSessionAttributeListener)listener);
+        }
+    }
+    
+    public void contextInitialized(ServletContextEvent sce)
+    {
+        if (contextListeners != null && !contextListeners.isEmpty())
+        {
+            for (ServletContextListener listener : contextListeners)
+            {
+                listener.contextInitialized(sce);
+            }
+        }
+    }
+    
+    public void contextDestroyed(ServletContextEvent sce)
+    {
+        if (contextListeners != null && !contextListeners.isEmpty())
+        {
+            for (ServletContextListener listener : contextListeners)
+            {
+                listener.contextDestroyed(sce);
+            }
+        }
+    }
+    
+    public void attributeAdded(ServletContextAttributeEvent scab)
+    {
+        if (contextAttributeListeners != null && !contextAttributeListeners.isEmpty())
+        {
+            for (ServletContextAttributeListener listener : contextAttributeListeners)
+            {
+                listener.attributeAdded(scab);
+            }
+        }
+    }
+
+    public void attributeRemoved(ServletContextAttributeEvent scab)
+    {
+        if (contextAttributeListeners != null && !contextAttributeListeners.isEmpty())
+        {
+            for (ServletContextAttributeListener listener : contextAttributeListeners)
+            {
+                listener.attributeRemoved(scab);
+            }
+        }
+    }
+
+    public void attributeReplaced(ServletContextAttributeEvent scab)
+    {
+        if (contextAttributeListeners != null && !contextAttributeListeners.isEmpty())
+        {
+            for (ServletContextAttributeListener listener : contextAttributeListeners)
+            {
+                listener.attributeReplaced(scab);
+            }
+        }
+    }
+    
+    public void requestInitialized ( ServletRequestEvent sre )
+    {
+        if (requestListeners != null && !requestListeners.isEmpty())
+        {
+            for (ServletRequestListener listener : requestListeners)
+            {
+                listener.requestInitialized(sre);
+            }
+        }        
+    }
+    
+    public void requestDestroyed ( ServletRequestEvent sre )
+    {
+        if (requestListeners != null && !requestListeners.isEmpty())
+        {
+            for (ServletRequestListener listener : requestListeners)
+            {
+                listener.requestDestroyed(sre);
+            }
+        }
+    }
+
+    public void sessionCreated ( HttpSessionEvent se )
+    {
+        if (sessionListeners != null && !sessionListeners.isEmpty())
+        {
+            for (HttpSessionListener listener : sessionListeners)
+            {
+                listener.sessionCreated(se);
+            }
+        }
+    }
+    
+    public void sessionDestroyed ( HttpSessionEvent se )
+    {
+        if (sessionListeners != null && !sessionListeners.isEmpty())
+        {
+            for (HttpSessionListener listener : sessionListeners)
+            {
+                listener.sessionDestroyed(se);
+            }
+        }        
+    }
+
+    public void attributeAdded(ServletRequestAttributeEvent srae)
+    {
+        if (requestAttributeListeners != null && !requestAttributeListeners.isEmpty())
+        {
+            for (ServletRequestAttributeListener listener : requestAttributeListeners)
+            {
+                listener.attributeAdded(srae);
+            }
+        }
+    }
+
+    public void attributeRemoved(ServletRequestAttributeEvent srae)
+    {
+        if (requestAttributeListeners != null && !requestAttributeListeners.isEmpty())
+        {
+            for (ServletRequestAttributeListener listener : requestAttributeListeners)
+            {
+                listener.attributeRemoved(srae);
+            }
+        }
+    }
+
+    public void attributeReplaced(ServletRequestAttributeEvent srae)
+    {
+        if (requestAttributeListeners != null && !requestAttributeListeners.isEmpty())
+        {
+            for (ServletRequestAttributeListener listener : requestAttributeListeners)
+            {
+                listener.attributeReplaced(srae);
+            }
+        }
+    }
+
+    public void attributeAdded(HttpSessionBindingEvent se)
+    {
+        if (sessionAttributeListeners != null && !sessionAttributeListeners.isEmpty())
+        {
+            for (HttpSessionAttributeListener listener : sessionAttributeListeners)
+            {
+                listener.attributeAdded(se);
+            }
+        }
+    }
+
+    public void attributeRemoved(HttpSessionBindingEvent se)
+    {
+        if (sessionAttributeListeners != null && !sessionAttributeListeners.isEmpty())
+        {
+            for (HttpSessionAttributeListener listener : sessionAttributeListeners)
+            {
+                listener.attributeRemoved(se);
+            }
+        }
+    }
+
+    public void attributeReplaced(HttpSessionBindingEvent se)
+    {
+        if (sessionAttributeListeners != null && !sessionAttributeListeners.isEmpty())
+        {
+            for (HttpSessionAttributeListener listener : sessionAttributeListeners)
+            {
+                listener.attributeReplaced(se);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/test20/pom.xml b/test20/pom.xml
index 0352c62..ba7aff2 100644
--- a/test20/pom.xml
+++ b/test20/pom.xml
@@ -192,7 +192,7 @@
                         <artifactItem>
                           <groupId>org.apache.myfaces.test</groupId>
                           <artifactId>myfaces-test12</artifactId>
-                          <version>1.0.4</version>
+                          <version>${project.version}</version>
                           <classifier>sources</classifier>                   
                           <outputDirectory>${project.build.directory}/test12_sources</outputDirectory>
                           <includes>org/apache/myfaces/**/*.java</includes>
diff --git a/test22/pom.xml b/test22/pom.xml
index 8c9a795..beef7ca 100644
--- a/test22/pom.xml
+++ b/test22/pom.xml
@@ -200,7 +200,7 @@
                         <artifactItem>
                           <groupId>org.apache.myfaces.test</groupId>
                           <artifactId>myfaces-test20</artifactId>
-                          <version>1.0.5-SNAPSHOT</version>
+                          <version>${project.version}</version>
                           <classifier>sources</classifier>                   
                           <outputDirectory>${project.build.directory}/test20_sources</outputDirectory>
                           <includes>org/apache/myfaces/**/*.java</includes>