You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by de...@apache.org on 2018/05/08 12:48:05 UTC

[myfaces] 02/28: MYFACES-3588 window-id support (step 1, implement JSF 2.2 early draft api)

This is an automated email from the ASF dual-hosted git repository.

deki pushed a commit to branch 2.1.x-client-window
in repository https://gitbox.apache.org/repos/asf/myfaces.git

commit 0b8d39d586d22b0c0fafba5b143b36e2f185726c
Author: Leonardo Uribe <lu...@apache.org>
AuthorDate: Fri Aug 3 14:33:13 2012 +0000

    MYFACES-3588 window-id support (step 1, implement JSF 2.2 early draft api)
---
 .../java/javax/faces/context/ExternalContext.java  |  31 ++
 .../faces/context/ExternalContextWrapper.java      |  14 +
 .../java/javax/faces/lifecycle/ClientWindow.java   |  57 +++
 .../main/java/javax/faces/lifecycle/Lifecycle.java |  11 +
 .../javax/faces/lifecycle/LifecycleWrapper.java    |  65 +++
 .../javax/faces/render/ResponseStateManager.java   |   3 +
 .../main/java/javax/faces/webapp/FacesServlet.java |   2 +
 client-window-example/pom.xml                      | 504 +++++++++++++++++++++
 .../example/clientWindow/DisableClientWindow.java  |  39 ++
 .../example/clientWindow/EnableClientWindow.java   |  38 ++
 .../example/clientWindow/HelloWorldController.java |  64 +++
 .../apache/myfaces/example/flash/FlashBean.java    |  39 +-
 .../myfaces/example/flash/HelloWorldFlashBean.java | 147 ++++++
 .../myfaces/example/windowScope/SubKeyMap.java     | 316 +++++++++++++
 .../myfaces/example/windowScope/WindowScope.java   |  28 ++
 .../example/windowScope/WindowScopeELResolver.java | 260 +++++++++++
 .../example/windowScope/WindowScopeImpl.java       | 169 +++++++
 .../main/webapp/META-INF/templates/example.xhtml   |  38 ++
 .../src/main/webapp/WEB-INF/faces-config.xml       |  64 +++
 .../src/main/webapp/WEB-INF/web.xml                | 114 +++++
 client-window-example/src/main/webapp/flash1.xhtml |  29 ++
 client-window-example/src/main/webapp/flash2.xhtml |  29 ++
 client-window-example/src/main/webapp/flash3.xhtml |  28 ++
 .../src/main/webapp/flashKeep1.xhtml               |  43 ++
 .../src/main/webapp/flashKeep2.xhtml               |  41 ++
 .../src/main/webapp/flashKeep3.xhtml               |  39 ++
 .../src/main/webapp/flashKeepConfirmation.xhtml    |  43 ++
 .../src/main/webapp/flashKeepEntry.xhtml           |  43 ++
 .../src/main/webapp/flashKeepFinished.xhtml        |  41 ++
 .../src/main/webapp/flashg1.xhtml                  |  20 +
 .../src/main/webapp/flashg2.xhtml                  |  20 +
 .../src/main/webapp/flashhw1.xhtml                 |  26 ++
 .../src/main/webapp/flashhw2.xhtml                 |  23 +
 .../src/main/webapp/flashprg1.xhtml                |  24 +
 .../src/main/webapp/flashprg2.xhtml                |  22 +
 .../src/main/webapp/helloWorld.xhtml               |  41 ++
 client-window-example/src/main/webapp/home.xhtml   |  59 +++
 client-window-example/src/main/webapp/index.html   |  24 +
 client-window-example/src/main/webapp/page2.xhtml  |  36 ++
 .../clientWindow/disableClientWindow.xhtml         |   9 +
 .../clientWindow/enableClientWindow.xhtml          |   9 +
 .../src/main/webapp/resources/css/style.css        |  33 +-
 .../clientWindow/CheckFaceletsFileTestCase.java    | 159 +++++++
 .../src/test/resources/webapp/README.txt           |   1 +
 .../servlet/ServletExternalContextImpl.java        |  33 +-
 .../servlet/ServletExternalContextImplBase.java    |  15 +
 .../myfaces/lifecycle/CODIClientSideWindow.java    | 424 +++++++++++++++++
 .../org/apache/myfaces/lifecycle/ClientConfig.java | 241 ++++++++++
 .../apache/myfaces/lifecycle/LifecycleImpl.java    |  54 +++
 .../apache/myfaces/lifecycle/TokenGenerator.java   |  75 +++
 .../apache/myfaces/lifecycle/UrlClientWindow.java  |  87 ++++
 .../myfaces/lifecycle/WindowContextConfig.java     | 152 +++++++
 .../renderkit/ServerSideStateCacheImpl.java        |  45 +-
 .../renderkit/html/HtmlResponseStateManager.java   |  31 ++
 .../myfaces/view/facelets/util/Classpath.java      |  20 +-
 .../org.apache.myfaces.windowId/windowhandler.html | 215 +++++++++
 pom.xml                                            |   1 +
 .../myfaces/shared/context/flash/FlashImpl.java    |  58 ++-
 58 files changed, 4233 insertions(+), 63 deletions(-)

diff --git a/api/src/main/java/javax/faces/context/ExternalContext.java b/api/src/main/java/javax/faces/context/ExternalContext.java
index 8baab63..d1ccb17 100755
--- a/api/src/main/java/javax/faces/context/ExternalContext.java
+++ b/api/src/main/java/javax/faces/context/ExternalContext.java
@@ -26,6 +26,7 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
+import javax.faces.lifecycle.ClientWindow;
 
 /**
  * see Javadoc of <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a>
@@ -736,4 +737,34 @@ public abstract class ExternalContext
         
         ctx.setSessionMaxInactiveInterval(interval);
     }
+
+    public ClientWindow getClientWindow()
+    {
+        ExternalContext ctx = _MyFacesExternalContextHelper.firstInstance.get();
+        
+        if (ctx == null)
+        {
+            /*throw new UnsupportedOperationException();*/
+            // TODO: Return null for now, but it should throw exception
+            // in JSF 2.2
+            return null;
+        }
+        
+        return ctx.getClientWindow();
+    }
+    
+    public void setClientWindow(ClientWindow window)
+    {
+        // No op for now.
+        /*
+        ExternalContext ctx = _MyFacesExternalContextHelper.firstInstance.get();
+        
+        if (ctx == null)
+        {
+            throw new UnsupportedOperationException();
+        }
+        
+        ctx.setClientWindow(window);
+        */
+    }
 }
diff --git a/api/src/main/java/javax/faces/context/ExternalContextWrapper.java b/api/src/main/java/javax/faces/context/ExternalContextWrapper.java
index 39eb7d9..929fcc4 100644
--- a/api/src/main/java/javax/faces/context/ExternalContextWrapper.java
+++ b/api/src/main/java/javax/faces/context/ExternalContextWrapper.java
@@ -33,6 +33,7 @@ import java.util.Map;
 import java.util.Set;
 
 import javax.faces.FacesWrapper;
+import javax.faces.lifecycle.ClientWindow;
 
 /**
  * @author Simon Lessard (latest modification by $Author$)
@@ -477,4 +478,17 @@ public abstract class ExternalContextWrapper extends ExternalContext implements
     {
         getWrapped().setSessionMaxInactiveInterval(interval);
     }
+
+    @Override
+    public ClientWindow getClientWindow()
+    {
+        return getWrapped().getClientWindow();
+    }
+
+    @Override
+    public void setClientWindow(ClientWindow window)
+    {
+        getWrapped().setClientWindow(window);
+    }
+    
 }
diff --git a/api/src/main/java/javax/faces/lifecycle/ClientWindow.java b/api/src/main/java/javax/faces/lifecycle/ClientWindow.java
new file mode 100644
index 0000000..d9f3796
--- /dev/null
+++ b/api/src/main/java/javax/faces/lifecycle/ClientWindow.java
@@ -0,0 +1,57 @@
+/*
+ * 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 javax.faces.lifecycle;
+
+import javax.faces.context.FacesContext;
+
+/**
+ *
+ * @since 2.2
+ * @author Leonardo Uribe
+ */
+public abstract class ClientWindow
+{
+    
+    public static final String CLIENT_WINDOW_MODE_PARAM_NAME = 
+            "javax.faces.CLIENT_WINDOW_MODE";
+    
+    private static final String CLIENT_WINDOW_URL_QUERY_PARAMETER_DISABLED = 
+            "org.apache.myfaces.CLIENT_WINDOW_URL_QUERY_PARAMETER_DISABLED";
+    
+    public abstract void decode(FacesContext context);
+    
+    public abstract String getId();
+    
+    public static boolean isClientWindowUrlQueryParameterEnabled(FacesContext context)
+    {
+        // By default is enabled, so it is easier to check the opposite.
+        return !Boolean.TRUE.equals(
+                context.getAttributes().get(CLIENT_WINDOW_URL_QUERY_PARAMETER_DISABLED));
+    }
+    
+    public static void disableClientWindowUrlQueryParameter(FacesContext context)
+    {
+        context.getAttributes().put(CLIENT_WINDOW_URL_QUERY_PARAMETER_DISABLED, Boolean.TRUE);
+    }
+    
+    public static void enableClientWindowUrlQueryParameter(FacesContext context)
+    {
+        context.getAttributes().put(CLIENT_WINDOW_URL_QUERY_PARAMETER_DISABLED, Boolean.FALSE);
+    }
+}
diff --git a/api/src/main/java/javax/faces/lifecycle/Lifecycle.java b/api/src/main/java/javax/faces/lifecycle/Lifecycle.java
index 128c616..9a60930 100755
--- a/api/src/main/java/javax/faces/lifecycle/Lifecycle.java
+++ b/api/src/main/java/javax/faces/lifecycle/Lifecycle.java
@@ -19,6 +19,7 @@
 package javax.faces.lifecycle;
 
 import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
 
 /**
  * see Javadoc of <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a>
@@ -39,4 +40,14 @@ public abstract class Lifecycle
 
     public abstract void render(javax.faces.context.FacesContext context)
             throws FacesException;
+    
+    /**
+     * 
+     * @since 2.2
+     * @param context 
+     */
+    public void attachWindow(FacesContext context)
+    {
+        
+    }
 }
diff --git a/api/src/main/java/javax/faces/lifecycle/LifecycleWrapper.java b/api/src/main/java/javax/faces/lifecycle/LifecycleWrapper.java
new file mode 100644
index 0000000..0928673
--- /dev/null
+++ b/api/src/main/java/javax/faces/lifecycle/LifecycleWrapper.java
@@ -0,0 +1,65 @@
+/*
+ * 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 javax.faces.lifecycle;
+
+import javax.faces.FacesException;
+import javax.faces.FacesWrapper;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PhaseListener;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+public abstract class LifecycleWrapper extends Lifecycle implements FacesWrapper<Lifecycle>
+{
+    
+    public void render(FacesContext context) throws FacesException
+    {
+        getWrapped().render(context);
+    }
+
+    public void removePhaseListener(PhaseListener listener)
+    {
+        getWrapped().removePhaseListener(listener);
+    }
+
+    public PhaseListener[] getPhaseListeners()
+    {
+        return getWrapped().getPhaseListeners();
+    }
+
+    public void execute(FacesContext context) throws FacesException
+    {
+        getWrapped().execute(context);
+    }
+
+    public void attachWindow(FacesContext context)
+    {
+        getWrapped().attachWindow(context);
+    }
+
+    public void addPhaseListener(PhaseListener listener)
+    {
+        getWrapped().addPhaseListener(listener);
+    }
+    
+    public abstract LifecycleWrapper getWrapped();
+    
+}
diff --git a/api/src/main/java/javax/faces/render/ResponseStateManager.java b/api/src/main/java/javax/faces/render/ResponseStateManager.java
index bed6f82..9bce04e 100755
--- a/api/src/main/java/javax/faces/render/ResponseStateManager.java
+++ b/api/src/main/java/javax/faces/render/ResponseStateManager.java
@@ -34,6 +34,9 @@ public abstract class ResponseStateManager
 {
     public static final String RENDER_KIT_ID_PARAM = "javax.faces.RenderKitId";
     public static final String VIEW_STATE_PARAM = "javax.faces.ViewState";
+    
+    public static final String CLIENT_WINDOW_PARAM = "javax.faces.ClientWindow";
+    public static final String CLIENT_WINDOW_URL_PARAM = "jfwid";
 
     public void writeState(FacesContext context, Object state) throws IOException
     {
diff --git a/api/src/main/java/javax/faces/webapp/FacesServlet.java b/api/src/main/java/javax/faces/webapp/FacesServlet.java
index 57e79e5..fb7fc37 100755
--- a/api/src/main/java/javax/faces/webapp/FacesServlet.java
+++ b/api/src/main/java/javax/faces/webapp/FacesServlet.java
@@ -192,6 +192,8 @@ public final class FacesServlet implements Servlet
             }
             else
             {
+                //JSF 2.2: attach window
+                _lifecycle.attachWindow(facesContext);
                 // If this returns false, handle as follows:
                 // call Lifecycle.execute(javax.faces.context.FacesContext)
                 _lifecycle.execute(facesContext);
diff --git a/client-window-example/pom.xml b/client-window-example/pom.xml
new file mode 100644
index 0000000..71af5c9
--- /dev/null
+++ b/client-window-example/pom.xml
@@ -0,0 +1,504 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+    <artifactId>myfaces-core-module</artifactId>
+    <groupId>org.apache.myfaces.core</groupId>
+    <version>2.1.9-CLIENT-WINDOW-SNAPSHOT</version>
+  </parent>
+    <groupId>org.apache.myfaces.example.clientWindow</groupId>
+    <artifactId>client-window-example</artifactId>
+    <packaging>war</packaging>
+    <version>2.1.9-CLIENT-WINDOW-SNAPSHOT</version>
+    <name>client-window-example</name>
+    <description>A custom project used to debug MyFaces Core 2.0</description>
+    <url>http://www.myorganization.org</url>
+
+    <!-- Instructions 
+      This project uses myfaces-test and myfaces-impl test jar
+      to make easier create specific tests for myfaces core that
+      later could be included into myfaces codebase.
+      - Run using jetty 
+          mvn clean jetty:run
+          mvn clean -Dcontainer=jetty-mojarra jetty:run
+          Set your browser to http://localhost:8080/client-window-example
+      - Run using tomcat
+          mvn clean -Dcontainer=tomcat7 tomcat:run
+          Set your browser to http://localhost:8080/client-window-example
+      - Run war using tomcat
+          mvn clean -Dcontainer=tomcat7 tomcat:run-war
+          Set your browser to http://localhost:8080/client-window-example
+      - Run war using jetty (remove <webApp> config inside plugin config first)
+          mvn clean jetty:run-war
+          mvn clean -Dcontainer=jetty-mojarra jetty:run-war
+          Set your browser to http://localhost:8080
+      - Build war and bundle JSF jars 
+          mvn clean -Pbundle-myfaces install
+          mvn clean -Pbundle-mojarra install
+      - Run using tomcat 6.0
+          mvn clean -Dcontainer=tomcat tomcat:run-war
+      - Run using tomcat 7.0 through cargo
+          mvn clean -Dcontainer=tomcat7 install cargo:run
+     -->
+
+    <properties>
+        <jsf-myfaces.version>2.1.9-CLIENT-WINDOW-SNAPSHOT</jsf-myfaces.version>
+        <jsf-mojarra.version>2.1.7</jsf-mojarra.version>        
+        <jetty.maven.plugin.version>8.1.3.v20120416</jetty.maven.plugin.version>
+        <cargo.version>1.1.1</cargo.version>
+    </properties>
+
+    <build>
+        <finalName>client-window-example</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.5</source>
+                    <target>1.5</target>
+                </configuration>
+            </plugin>
+            <!-- The following plugin is used to pack everything inside
+                 webapp folder and make it available on test jar under
+                 the path "webapp". This allows create junit tests over
+                 those files like for example, check if all facelets
+                 compile, if a view is correctly built or if render 
+                 what is expected. -->
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <version>1.7</version>
+                <executions>
+                    <execution>
+                        <id>add-webapp-folder-as-test</id>
+                        <phase>generate-test-resources</phase>
+                        <goals>
+                            <goal>add-test-resource</goal>
+                        </goals>
+                        <configuration>
+                          <resources>
+                            <resource>
+                                <directory>src/main/webapp</directory>
+                                <targetPath>webapp</targetPath>
+                            </resource>
+                          </resources>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            
+        </plugins>
+    </build>
+
+    <!-- Project dependencies -->
+    <dependencies>
+
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-servlet_2.5_spec</artifactId>
+            <version>1.2</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-el_2.2_spec</artifactId>
+            <version>1.0.2</version>
+            <scope>provided</scope>
+        </dependency>
+        
+        <dependency>
+            <groupId>org.apache.geronimo.specs</groupId>
+            <artifactId>geronimo-annotation_1.0_spec</artifactId>
+            <version>1.1.1</version>
+            <scope>provided</scope>
+        </dependency>
+        
+        <!-- JSF API: Add here as provided dependency and then add it
+             on jetty-maven-plugin as compile/runtime dependency.
+             The same goes for other JSF libraries. -->
+        <dependency>
+            <groupId>org.apache.myfaces.core</groupId>
+            <artifactId>myfaces-api</artifactId>
+            <version>${jsf-myfaces.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.myfaces.core</groupId>
+            <artifactId>myfaces-impl</artifactId>
+            <version>${jsf-myfaces.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>jstl</artifactId>
+            <version>1.2</version>
+            <scope>runtime</scope>
+        </dependency>
+        
+        <dependency>
+            <groupId>org.apache.myfaces.test</groupId>
+            <artifactId>myfaces-test20</artifactId>
+            <version>1.0.4</version>
+            <scope>test</scope>
+        </dependency>
+        
+        <dependency>
+            <groupId>org.apache.myfaces.core</groupId>
+            <artifactId>myfaces-impl</artifactId>
+            <version>${jsf-myfaces.version}</version>
+            <classifier>tests</classifier>
+            <scope>test</scope>
+        </dependency>
+        
+        <dependency>
+            <groupId>org.apache.myfaces.core</groupId>
+            <artifactId>myfaces-impl</artifactId>
+            <version>${jsf-myfaces.version}</version>
+            <scope>test</scope>
+        </dependency>
+        
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.8.2</version>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <id>bundle-myfaces</id>
+            <activation>
+                <property>
+                    <name>jsf</name>
+                    <value>myfaces</value>
+                </property>
+            </activation>
+            <!-- Include MyFaces jars into the war -->
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.myfaces.core</groupId>
+                    <artifactId>myfaces-api</artifactId>
+                    <version>${jsf-myfaces.version}</version>
+                    <scope>compile</scope>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.myfaces.core</groupId>
+                    <artifactId>myfaces-impl</artifactId>
+                    <version>${jsf-myfaces.version}</version>
+                    <scope>runtime</scope>
+                </dependency>
+            </dependencies>
+        </profile>
+
+        <profile>
+            <!-- Plugin embedded jetty 8 container. 
+                 Just running use:
+                 mvn clean jetty:run
+            -->
+            <!-- For debugging use (attach debugger port 8000):
+                 mvnDebug clean jetty:run
+            -->
+            <id>jettyConfig</id>
+            <activation>
+                <property>
+                    <name>!container</name>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <!--This plugin allows to run the war using mvn jetty:run -->
+                        <groupId>org.mortbay.jetty</groupId>
+                        <artifactId>jetty-maven-plugin</artifactId>
+                        <version>${jetty.maven.plugin.version}</version>
+                        <configuration>
+                            <systemProperties>
+                                <systemProperty>
+                                    <!-- optional to use the ecj compiler -->
+                                    <name>org.apache.jasper.compiler.disablejsr199</name>
+                                    <value>true</value>
+                                </systemProperty>
+                            </systemProperties>
+                            <webApp>
+                                <contextPath>/${artifactId}</contextPath>
+                            </webApp>
+                            <scanIntervalSeconds>5</scanIntervalSeconds>
+                        </configuration>
+                        <dependencies>
+                           <!-- Tld scanning only works when JSF is included
+                                as container dependency. Add other jsf libraries
+                                here, so jetty:run goal can find and process them -->
+                            <dependency>
+                                <groupId>org.apache.myfaces.core</groupId>
+                                <artifactId>myfaces-api</artifactId>
+                                <version>${jsf-myfaces.version}</version>
+                                <scope>compile</scope>
+                            </dependency>
+                            <dependency>
+                                <groupId>org.apache.myfaces.core</groupId>
+                                <artifactId>myfaces-impl</artifactId>
+                                <version>${jsf-myfaces.version}</version>
+                                <scope>runtime</scope>
+                            </dependency>
+                        </dependencies>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        
+        <profile>
+            <id>bundle-mojarra</id>
+            <activation>
+                <property>
+                    <name>jsf</name>
+                    <value>mojarra</value>
+                </property>
+            </activation>
+            <!-- Include Mojarra jars into the war -->
+            <dependencies>
+                <dependency>
+                    <groupId>com.sun.faces</groupId>
+                    <artifactId>jsf-api</artifactId>
+                    <version>${jsf-mojarra.version}</version>
+                    <scope>compile</scope>
+                </dependency>
+                <dependency>
+                    <groupId>com.sun.faces</groupId>
+                    <artifactId>jsf-impl</artifactId>
+                    <version>${jsf-mojarra.version}</version>
+                    <scope>runtime</scope>
+                </dependency>
+            </dependencies>
+            <repositories>
+                <repository>
+                    <id>java.net</id>
+                    <url>http://download.java.net/maven/2</url>
+                </repository>
+            </repositories>
+        </profile>
+
+        <profile>
+            <!-- Plugin embedded jetty 8 container. 
+                 Just running use:
+                 mvn clean -Dcontainer=jetty-mojarra jetty:run 
+            -->
+            <!-- For debugging use (attach debugger port 8000):
+                 mvn clean -Dcontainer=jetty-mojarra jetty:run 
+            -->
+            <id>jettyConfig-mojarra</id>
+            <activation>
+                <property>
+                    <name>container</name>
+                    <value>jetty-mojarra</value>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <!--This plugin allows to run the war using mvn jetty:run -->
+                        <groupId>org.mortbay.jetty</groupId>
+                        <artifactId>jetty-maven-plugin</artifactId>
+                        <version>${jetty.maven.plugin.version}</version>
+                        <configuration>
+                            <systemProperties>
+                                <systemProperty>
+                                    <!-- optional to use the ecj compiler -->
+                                    <name>org.apache.jasper.compiler.disablejsr199</name>
+                                    <value>true</value>
+                                </systemProperty>
+                            </systemProperties>
+                            <webApp>
+                                <contextPath>/${artifactId}</contextPath>
+                            </webApp>
+                            <scanIntervalSeconds>5</scanIntervalSeconds>
+                        </configuration>
+                        <dependencies>
+                           <!-- Tld scanning only works when JSF is included
+                                as container dependency. Add other jsf libraries
+                                here, so jetty:run goal can find and process them -->
+                           <dependency>
+                               <groupId>com.sun.faces</groupId>
+                               <artifactId>jsf-api</artifactId>
+                               <version>${jsf-mojarra.version}</version>
+                               <scope>compile</scope>
+                           </dependency>
+                           <dependency>
+                               <groupId>com.sun.faces</groupId>
+                               <artifactId>jsf-impl</artifactId>
+                               <version>${jsf-mojarra.version}</version>
+                               <scope>runtime</scope>
+                           </dependency>
+                        </dependencies>
+                    </plugin>
+                </plugins>
+            </build>
+            <repositories>
+                <repository>
+                    <id>java.net</id>
+                    <url>http://download.java.net/maven/2</url>
+                </repository>
+            </repositories>
+        </profile>
+        
+        <profile>
+            <id>maven-tomcat7</id>
+            <activation>
+                <property>
+                    <name>container</name>
+                    <value>tomcat7</value>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                      <groupId>org.apache.tomcat.maven</groupId>
+                      <artifactId>tomcat7-maven-plugin</artifactId>
+                      <version>2.0-beta-1</version>
+                    </plugin>
+                </plugins>
+            </build>
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.myfaces.core</groupId>
+                    <artifactId>myfaces-api</artifactId>
+                    <version>${jsf-myfaces.version}</version>
+                    <scope>compile</scope>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.myfaces.core</groupId>
+                    <artifactId>myfaces-impl</artifactId>
+                    <version>${jsf-myfaces.version}</version>
+                    <scope>runtime</scope>
+                </dependency>
+            </dependencies>
+        </profile>
+
+        <profile>
+            <!-- Plugin embedded tomcat 6 container. 
+                 Just running use:
+                 mvn clean -Dcontainer=tomcat tomcat:run-war 
+            -->
+            <!-- For debugging use (attach debugger port 8000):
+                 mvnDebug clean -Dcontainer=tomcat tomcat:run-war 
+            -->
+            <id>tomcat</id>
+            <activation>
+                <property>
+                    <name>container</name>
+                    <value>tomcat</value>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                      <groupId>org.codehaus.mojo</groupId>
+                      <artifactId>tomcat-maven-plugin</artifactId>
+                      <version>1.1</version>
+                    </plugin>
+                </plugins>
+            </build>
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.myfaces.core</groupId>
+                    <artifactId>myfaces-api</artifactId>
+                    <version>${jsf-myfaces.version}</version>
+                    <scope>compile</scope>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.myfaces.core</groupId>
+                    <artifactId>myfaces-impl</artifactId>
+                    <version>${jsf-myfaces.version}</version>
+                    <scope>runtime</scope>
+                </dependency>
+            </dependencies>
+        </profile>
+        
+        <profile>
+            <!-- Installed tomcat 7 running war file through cargo 
+                 Attach debugger on port 8000:
+                 mvn clean -Dcontainer=tomcat7 install cargo:run -->
+            <id>cargo-tomcat7</id>
+            <activation>
+                <property>
+                    <name>container</name>
+                    <value>tomcat7</value>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                      <groupId>org.codehaus.cargo</groupId>
+                      <artifactId>cargo-maven2-plugin</artifactId>
+                      <version>${cargo.version}</version>
+                      <configuration>
+                        <wait>true</wait>
+                        <properties>
+                            <cargo.servlet.port>8080</cargo.servlet.port>
+                            <cargo.jvmargs>-Xdebug
+                              -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000
+                              -Xnoagent
+                              -Djava.compiler=NONE</cargo.jvmargs>
+                        </properties>
+                        <container>
+                          <containerId>tomcat7x</containerId>
+                          <zipUrlInstaller>
+                            <url>http://archive.apache.org/dist/tomcat/tomcat-7/v7.0.25/bin/apache-tomcat-7.0.25.zip</url>
+                            <!-- 
+                            <installDir>${basedir}/tomcat7x</installDir>
+                             -->
+                            <downloadDir>${basedir}/downloads</downloadDir>
+                            <extractDir>${basedir}/tomcat7x</extractDir>
+                          </zipUrlInstaller>
+                        </container>
+                        <configuration>
+                          <home>${basedir}/target/tomcat7x</home>
+                          <properties>
+                            <cargo.jvmargs>-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000 -Xnoagent -Djava.compiler=NONE</cargo.jvmargs>
+                          </properties>
+                        </configuration>
+                      </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.myfaces.core</groupId>
+                    <artifactId>myfaces-api</artifactId>
+                    <version>${jsf-myfaces.version}</version>
+                    <scope>compile</scope>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.myfaces.core</groupId>
+                    <artifactId>myfaces-impl</artifactId>
+                    <version>${jsf-myfaces.version}</version>
+                    <scope>runtime</scope>
+                </dependency>
+            </dependencies>
+        </profile>
+        
+    </profiles>
+
+</project>
diff --git a/client-window-example/src/main/java/org/apache/myfaces/example/clientWindow/DisableClientWindow.java b/client-window-example/src/main/java/org/apache/myfaces/example/clientWindow/DisableClientWindow.java
new file mode 100644
index 0000000..6f06b9a
--- /dev/null
+++ b/client-window-example/src/main/java/org/apache/myfaces/example/clientWindow/DisableClientWindow.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2012 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.myfaces.example.clientWindow;
+
+import java.io.IOException;
+import javax.faces.component.FacesComponent;
+import javax.faces.component.UINamingContainer;
+import javax.faces.context.FacesContext;
+import javax.faces.lifecycle.ClientWindow;
+
+/**
+ *
+ * @author lu4242
+ */
+@FacesComponent("oam.clientWindow.disable")
+public class DisableClientWindow extends UINamingContainer
+{
+
+    @Override
+    public void encodeBegin(FacesContext context) throws IOException
+    {
+        ClientWindow.disableClientWindowUrlQueryParameter(context);
+        super.encodeBegin(context);
+    }
+    
+}
diff --git a/client-window-example/src/main/java/org/apache/myfaces/example/clientWindow/EnableClientWindow.java b/client-window-example/src/main/java/org/apache/myfaces/example/clientWindow/EnableClientWindow.java
new file mode 100644
index 0000000..c8ca66b
--- /dev/null
+++ b/client-window-example/src/main/java/org/apache/myfaces/example/clientWindow/EnableClientWindow.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2012 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.myfaces.example.clientWindow;
+
+import java.io.IOException;
+import javax.faces.component.FacesComponent;
+import javax.faces.component.UINamingContainer;
+import javax.faces.context.FacesContext;
+import javax.faces.lifecycle.ClientWindow;
+
+/**
+ *
+ * @author lu4242
+ */
+@FacesComponent("oam.clientWindow.enable")
+public class EnableClientWindow extends UINamingContainer
+{
+
+    @Override
+    public void encodeBegin(FacesContext context) throws IOException
+    {
+        ClientWindow.enableClientWindowUrlQueryParameter(context);
+        super.encodeBegin(context);
+    }    
+}
diff --git a/client-window-example/src/main/java/org/apache/myfaces/example/clientWindow/HelloWorldController.java b/client-window-example/src/main/java/org/apache/myfaces/example/clientWindow/HelloWorldController.java
new file mode 100644
index 0000000..28b8f57
--- /dev/null
+++ b/client-window-example/src/main/java/org/apache/myfaces/example/clientWindow/HelloWorldController.java
@@ -0,0 +1,64 @@
+/*
+ * 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.example.clientWindow;
+
+import java.io.Serializable;
+import javax.faces.bean.CustomScoped;
+import javax.faces.bean.ManagedBean;
+
+/**
+ * A typical simple backing bean, that is backed to <code>helloWorld.xhtml</code>
+ */
+@ManagedBean(name = "helloWorld")
+@CustomScoped("#{window}")
+public class HelloWorldController implements Serializable
+{
+
+    //properties
+    private String name;
+
+    /**
+     * default empty constructor
+     */
+    public HelloWorldController()
+    {
+    }
+
+    /**
+     * Method that is backed to a submit button of a form.
+     */
+    public String send()
+    {
+        //do real logic, return a string which will be used for the navigation system of JSF
+        return "page2.xhtml";
+    }
+
+    //-------------------getter & setter
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+}
diff --git a/api/src/main/java/javax/faces/lifecycle/Lifecycle.java b/client-window-example/src/main/java/org/apache/myfaces/example/flash/FlashBean.java
old mode 100755
new mode 100644
similarity index 50%
copy from api/src/main/java/javax/faces/lifecycle/Lifecycle.java
copy to client-window-example/src/main/java/org/apache/myfaces/example/flash/FlashBean.java
index 128c616..378a1ad
--- a/api/src/main/java/javax/faces/lifecycle/Lifecycle.java
+++ b/client-window-example/src/main/java/org/apache/myfaces/example/flash/FlashBean.java
@@ -15,28 +15,31 @@
  * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
- */
-package javax.faces.lifecycle;
+*/
+package org.apache.myfaces.example.flash;
 
-import javax.faces.FacesException;
+import java.awt.event.ActionEvent;
+import javax.faces.bean.ManagedBean;
+import javax.faces.bean.RequestScoped;
 
-/**
- * see Javadoc of <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a>
- *
- * @author Manfred Geiler (latest modification by $Author$)
- * @version $Revision$ $Date$
- */
-public abstract class Lifecycle
+@ManagedBean(name="flashBean")
+@RequestScoped
+public class FlashBean
 {
-    public abstract void addPhaseListener(javax.faces.event.PhaseListener listener);
-
-    public abstract void execute(javax.faces.context.FacesContext context)
-            throws FacesException;
 
-    public abstract javax.faces.event.PhaseListener[] getPhaseListeners();
+    public String gotoFlash2()
+    {
+        return "flash2";
+    }
+    
+    public String gotoFlash3()
+    {
+        return "flash3";
+    }
 
-    public abstract void removePhaseListener(javax.faces.event.PhaseListener listener);
+    public String gotoFlash1()
+    {
+        return "flash1"; 
+    }
 
-    public abstract void render(javax.faces.context.FacesContext context)
-            throws FacesException;
 }
diff --git a/client-window-example/src/main/java/org/apache/myfaces/example/flash/HelloWorldFlashBean.java b/client-window-example/src/main/java/org/apache/myfaces/example/flash/HelloWorldFlashBean.java
new file mode 100644
index 0000000..ba7617a
--- /dev/null
+++ b/client-window-example/src/main/java/org/apache/myfaces/example/flash/HelloWorldFlashBean.java
@@ -0,0 +1,147 @@
+/*
+ * 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.example.flash;
+
+import javax.faces.application.FacesMessage;
+import javax.faces.bean.ManagedBean;
+import javax.faces.bean.RequestScoped;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.context.Flash;
+import javax.faces.event.PhaseEvent;
+
+/**
+ * A typical simple backing bean, that is backed to <code>helloworld.jsp</code>
+ * 
+ */
+@ManagedBean(name="helloWorldFlashBean")
+@RequestScoped
+public class HelloWorldFlashBean {
+
+    //Log log = LogFactory.getLog(HelloWorldFlashBean.class);
+    
+    private int before = 0;
+    
+    private int after = 0;
+    
+    public void beforePhase(PhaseEvent phaseEvent){
+        
+        FacesContext facesContext = FacesContext.getCurrentInstance();      
+        before++;       
+        facesContext.addMessage(null, new FacesMessage("This is the message for phase before "+phaseEvent.getPhaseId().toString()+" : "+before+" "+facesContext.getExternalContext().getFlash().get("lastName")));
+        //log.info("This is the message for phase before "+phaseEvent.getPhaseId().toString()+" : "+before);
+    }
+    
+    public void afterPhase(PhaseEvent phaseEvent){
+
+        FacesContext facesContext = FacesContext.getCurrentInstance();      
+        after++;        
+        facesContext.addMessage(null, new FacesMessage("This is the message for phase after "+phaseEvent.getPhaseId().toString()+" : "+after+" "+facesContext.getExternalContext().getFlash().get("lastName")));
+        //log.info("This is the message for phase after "+phaseEvent.getPhaseId().toString()+" : "+after);
+    }
+
+    //properties
+    private String name;
+    
+    private String lastName;
+    
+    /**
+     * default empty constructor
+     */
+    public HelloWorldFlashBean(){
+    }
+    
+    //-------------------getter & setter
+    public String getName() {
+        return name;
+    }
+    public void setName(String name) {
+        this.name = name;
+    }
+    
+    public String getLastName()
+    {
+        return lastName;
+    }
+
+    public void setLastName(String lastName)
+    {
+        this.lastName = lastName;
+    }
+
+    /**
+     * Method that is backed to a submit button of a form.
+     */
+    public String send(){
+        //do real logic, return a string which will be used for the navigation system of JSF
+        
+        FacesContext facesContext = FacesContext.getCurrentInstance();
+        ExternalContext externalContext = facesContext.getExternalContext();
+        Flash flash = externalContext.getFlash();
+        
+        flash.put("name", getName());
+        flash.setKeepMessages(true);
+        facesContext.addMessage(null, new FacesMessage("var name put on flash scope"));
+        
+        return "success";
+    }
+    
+    public String sendPutNow(){
+        //do real logic, return a string which will be used for the navigation system of JSF
+        
+        FacesContext facesContext = FacesContext.getCurrentInstance();
+        ExternalContext externalContext = facesContext.getExternalContext();
+        Flash flash = externalContext.getFlash();
+    
+        flash.putNow("name", getName());
+        flash.keep("name");
+        flash.setKeepMessages(true);
+        facesContext.addMessage(null, new FacesMessage("var name putNow on flash scope"));
+        
+        return "success";
+    }
+    
+    public String keepRedirect()
+    {
+        FacesContext facesContext = FacesContext.getCurrentInstance();
+        ExternalContext externalContext = facesContext.getExternalContext();
+        Flash flash = externalContext.getFlash();
+        
+        flash.putNow("name", getName());
+        flash.keep("name");
+        
+        return "flashKeep2.xhtml?faces-redirect=true";
+    }
+    
+    public String keepPostback()
+    {
+        FacesContext facesContext = FacesContext.getCurrentInstance();
+        ExternalContext externalContext = facesContext.getExternalContext();
+        Flash flash = externalContext.getFlash();
+        
+        flash.keep("name"); // does not work here anymore
+        
+        return "flashKeep3.xhtml";
+    }
+
+    
+    public String back(){
+        return "back";
+    }
+}
\ No newline at end of file
diff --git a/client-window-example/src/main/java/org/apache/myfaces/example/windowScope/SubKeyMap.java b/client-window-example/src/main/java/org/apache/myfaces/example/windowScope/SubKeyMap.java
new file mode 100644
index 0000000..a449adb
--- /dev/null
+++ b/client-window-example/src/main/java/org/apache/myfaces/example/windowScope/SubKeyMap.java
@@ -0,0 +1,316 @@
+/*
+ * 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.example.windowScope;
+
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * NOTE: Class copied from trinidad to be used on FlashImpl.
+ * 
+ * Map that wraps another to provide an isolated namespace using
+ * a prefix.  This is especially handy for storing properties on
+ * the session in a structured manner without putting them into
+ * a true "Map" - because storing in a Map breaks session failover.
+ * (Session failover won't trigger on mutations of contained objects.)
+ * <p>
+ * Note that there is a potential design flaw;  if you create a SubKeyMap
+ * for "mypackage.foo" and for "mypackage.foo.bar", all the keys in the
+ * latter will actually show up in the former (prefixed by ".bar").  This
+ * "flaw" is actually relied on by PageFlowScopeMap (since it provides
+ * a handy way to clear out all descendents), so don't "fix" it!
+ */
+final class SubKeyMap<V> extends AbstractMap<String, V>
+{
+    public SubKeyMap(Map<String, Object> base, String prefix)
+    {
+        if (base == null)
+        {
+            throw new NullPointerException();
+        }
+        if (prefix == null)
+        {
+            throw new NullPointerException();
+        }
+
+        // Optimize the scenario where we're wrapping another SubKeyMap
+        if (base instanceof SubKeyMap)
+        {
+            _base = ((SubKeyMap) base)._base;
+            _prefix = ((SubKeyMap) base)._prefix + prefix;
+        }
+        else
+        {
+            _base = base;
+            _prefix = prefix;
+        }
+        _keyBuffer = new StringBuilder(32);
+    }
+
+    @Override
+    public boolean isEmpty()
+    {
+        return entrySet().isEmpty();
+    }
+
+    @Override
+    public V get(Object key)
+    {
+        key = _getBaseKey(key);
+        return (V) _base.get(key);
+    }
+
+    @Override
+    public V put(String key, V value)
+    {
+        key = _getBaseKey(key);
+        return (V) _base.put(key, value);
+    }
+
+    @Override
+    public V remove(Object key)
+    {
+        key = _getBaseKey(key);
+        return (V) _base.remove(key);
+    }
+
+    @Override
+    public boolean containsKey(Object key)
+    {
+        if (!(key instanceof String))
+        {
+            return false;
+        }
+
+        return _base.containsKey(_getBaseKey(key));
+    }
+
+    @Override
+    public Set<Map.Entry<String, V>> entrySet()
+    {
+        if (_entrySet == null)
+        {
+            _entrySet = new Entries<V>();
+        }
+        return _entrySet;
+    }
+
+    private String _getBaseKey(Object key)
+    {
+        if (key == null)
+        {
+            throw new NullPointerException();
+        }
+        // Yes, I want a ClassCastException if it's not a String
+        //return _prefix + ((String) key);
+        _keyBuffer.setLength(0);
+        _keyBuffer.append(_prefix);
+        _keyBuffer.append((String) key);
+        return _keyBuffer.toString();
+    }
+
+    private List<String> _gatherKeys()
+    {
+        List<String> list = new ArrayList<String>();
+        for (String key : _base.keySet())
+        {
+            if (key != null && key.startsWith(_prefix))
+            {
+                list.add(key);
+            }
+        }
+
+        return list;
+    }
+
+    //
+    // Set implementation for SubkeyMap.entrySet()
+    //
+    private class Entries<V> extends AbstractSet<Map.Entry<String, V>>
+    {
+        public Entries()
+        {
+        }
+
+        @Override
+        public Iterator<Map.Entry<String, V>> iterator()
+        {
+            // Sadly, if you just try to use a filtering approach
+            // on the iterator, you'll get concurrent modification
+            // exceptions.  Consequently, gather the keys in a list
+            // and iterator over that.
+            List<String> keyList = _gatherKeys();
+            return new EntryIterator<V>(keyList.iterator());
+        }
+
+        @Override
+        public int size()
+        {
+            int size = 0;
+            for (String key : _base.keySet())
+            {
+                if (key != null && key.startsWith(_prefix))
+                {
+                    size++;
+                }
+            }
+
+            return size;
+        }
+
+        @Override
+        public boolean isEmpty()
+        {
+            Iterator<String> keys = _base.keySet().iterator();
+            while (keys.hasNext())
+            {
+                String key = keys.next();
+                // Short-circuit:  the default implementation would always
+                // need to iterate to find the total size.
+                if (key != null && key.startsWith(_prefix))
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        @Override
+        public void clear()
+        {
+            Iterator<String> keys = _base.keySet().iterator();
+            while (keys.hasNext())
+            {
+                String key = keys.next();
+                if (key != null && key.startsWith(_prefix))
+                {
+                    keys.remove();
+                }
+            }
+        }
+    }
+
+    private class EntryIterator<V> implements Iterator<Map.Entry<String, V>>
+    {
+        public EntryIterator(Iterator<String> iterator)
+        {
+            _iterator = iterator;
+        }
+
+        public boolean hasNext()
+        {
+            return _iterator.hasNext();
+        }
+
+        public Map.Entry<String, V> next()
+        {
+            String baseKey = _iterator.next();
+            _currentKey = baseKey;
+            return new Entry<V>(baseKey);
+        }
+
+        public void remove()
+        {
+            if (_currentKey == null)
+            {
+                throw new IllegalStateException();
+            }
+
+            _base.remove(_currentKey);
+
+            _currentKey = null;
+        }
+
+        private Iterator<String> _iterator;
+        private String _currentKey;
+    }
+
+    private class Entry<V> implements Map.Entry<String, V>
+    {
+        public Entry(String baseKey)
+        {
+            _baseKey = baseKey;
+        }
+
+        public String getKey()
+        {
+            if (_key == null)
+            {
+                _key = _baseKey.substring(_prefix.length());
+            }
+            return _key;
+        }
+
+        public V getValue()
+        {
+            return (V) _base.get(_baseKey);
+        }
+
+        public V setValue(V value)
+        {
+            return (V) _base.put(_baseKey, value);
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public boolean equals(Object o)
+        {
+            if (!(o instanceof Map.Entry))
+            {
+                return false;
+            }
+            Map.Entry<String, V> e = (Map.Entry<String, V>) o;
+            return _equals(getKey(), e.getKey())
+                    && _equals(getValue(), e.getValue());
+        }
+
+        @Override
+        public int hashCode()
+        {
+            Object key = getKey();
+            Object value = getValue();
+            return ((key == null) ? 0 : key.hashCode())
+                    ^ ((value == null) ? 0 : value.hashCode());
+        }
+
+        private String _baseKey;
+        private String _key;
+    }
+
+    static private boolean _equals(Object a, Object b)
+    {
+        if (a == null)
+        {
+            return b == null;
+        }
+        return a.equals(b);
+    }
+
+    private final Map<String, Object> _base;
+    private final String _prefix;
+    private Set<Map.Entry<String, V>> _entrySet;
+    private StringBuilder _keyBuffer;
+
+}
diff --git a/client-window-example/src/main/java/org/apache/myfaces/example/windowScope/WindowScope.java b/client-window-example/src/main/java/org/apache/myfaces/example/windowScope/WindowScope.java
new file mode 100644
index 0000000..9b7db01
--- /dev/null
+++ b/client-window-example/src/main/java/org/apache/myfaces/example/windowScope/WindowScope.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2012 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.myfaces.example.windowScope;
+
+import java.util.Map;
+
+/**
+ *
+ * @author lu4242
+ */
+public abstract class WindowScope implements Map<String, Object>
+{
+    
+    
+}
diff --git a/client-window-example/src/main/java/org/apache/myfaces/example/windowScope/WindowScopeELResolver.java b/client-window-example/src/main/java/org/apache/myfaces/example/windowScope/WindowScopeELResolver.java
new file mode 100644
index 0000000..df91837
--- /dev/null
+++ b/client-window-example/src/main/java/org/apache/myfaces/example/windowScope/WindowScopeELResolver.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2012 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.myfaces.example.windowScope;
+
+import java.beans.FeatureDescriptor;
+import java.util.ArrayList;
+import java.util.Iterator;
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.ELResolver;
+import javax.el.PropertyNotFoundException;
+import javax.el.PropertyNotWritableException;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+
+/**
+ *
+ * @author lu4242
+ */
+public class WindowScopeELResolver extends ELResolver
+{
+    public static final String WINDOW = "window";
+
+    @Override
+    public void setValue(final ELContext context, final Object base, final Object property, final Object value)
+    {
+        if (property == null)
+        {
+            throw new PropertyNotFoundException();
+        }
+        if (!(property instanceof String))
+        {
+            return;
+        }
+
+        String strProperty = property.toString();
+
+        if (WINDOW.equals(strProperty))
+        {
+            throw new PropertyNotWritableException();
+        }
+        else if (base instanceof WindowScope)
+        {
+            context.setPropertyResolved(true);
+            try
+            {
+                ((WindowScope) base).put(strProperty, value);
+            }
+            catch (UnsupportedOperationException e)
+            {
+                throw new PropertyNotWritableException(e);
+            }
+        }
+    }
+    
+    @Override
+    public boolean isReadOnly(ELContext context, Object base, Object property)
+            throws NullPointerException, PropertyNotFoundException, ELException
+    {
+
+        if (property == null)
+        {
+            throw new PropertyNotFoundException();
+        }
+        if (!(property instanceof String))
+        {
+            return false;
+        }
+
+        String strProperty = property.toString();
+
+        if (WINDOW.equals(strProperty))
+        {
+            context.setPropertyResolved(true);
+            return true;
+        }
+        else if (base instanceof WindowScope)
+        {
+            context.setPropertyResolved(true);
+        }
+
+        return false;
+    }
+    
+    @Override
+    public Object getValue(ELContext elContext, Object base, Object property)
+            throws NullPointerException, PropertyNotFoundException, ELException
+    {
+
+        if (property == null)
+        {
+            throw new PropertyNotFoundException();
+        }
+        if (!(property instanceof String))
+        {
+            return null;
+        }
+
+        String strProperty = property.toString();
+
+        if (base == null)
+        {
+            if (WINDOW.equals(strProperty))
+            {
+                FacesContext facesContext = facesContext(elContext);
+                if (facesContext == null)
+                {
+                    return null;
+                }
+                ExternalContext externalContext = facesContext.getExternalContext();
+                if (externalContext == null)
+                {
+                    return null;
+                }
+
+                //Access to window object
+                elContext.setPropertyResolved(true);
+                WindowScope window = getScope(facesContext);
+
+                return window;
+            }
+        }
+        else if (base instanceof WindowScope)
+        {
+            FacesContext facesContext = facesContext(elContext);
+            if (facesContext == null)
+            {
+                return null;
+            }
+            ExternalContext externalContext = facesContext.getExternalContext();
+            if (externalContext == null)
+            {
+                return null;
+            }
+            WindowScope window = (WindowScope) base;
+            //Just get the value
+            elContext.setPropertyResolved(true);
+            return window.get(strProperty);
+        }
+        return null;
+    }
+    
+    // get the FacesContext from the ELContext
+    protected FacesContext facesContext(ELContext context)
+    {
+        return (FacesContext) context.getContext(FacesContext.class);
+    }
+
+    protected ExternalContext externalContext(ELContext context)
+    {
+        return facesContext(context).getExternalContext();
+    }
+
+    private WindowScope getScope(final FacesContext facesContext)
+    {
+        return WindowScopeImpl.getCurrentInstance(facesContext.getExternalContext());
+    }
+    
+    @Override
+    public Class<?> getType(ELContext context, Object base, Object property)
+            throws NullPointerException, PropertyNotFoundException, ELException
+    {
+
+        if (property == null)
+        {
+            throw new PropertyNotFoundException();
+        }
+        if (!(property instanceof String))
+        {
+            return null;
+        }
+
+        String strProperty = property.toString();
+
+        if (WINDOW.equals(strProperty))
+        {
+            context.setPropertyResolved(true);
+        }
+        else if (base instanceof WindowScope)
+        {
+            context.setPropertyResolved(true);
+            Object obj = ((WindowScope) base).get(property);
+            return (obj != null) ? obj.getClass() : null;
+        }
+
+        return null;
+    }
+
+    @Override
+    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context,
+            Object base)
+    {
+        ArrayList<FeatureDescriptor> descriptors = new ArrayList<FeatureDescriptor>(1);
+
+        descriptors.add(makeDescriptor(WINDOW,
+                "Represents the current flash scope", Object.class));
+
+        if (base instanceof WindowScope)
+        {
+            Iterator itr = ((WindowScope) base).keySet().iterator();
+            Object key;
+            FeatureDescriptor desc;
+            while (itr.hasNext())
+            {
+                key = itr.next();
+                desc = makeDescriptor(key.toString(), key.toString(), key.getClass());
+                descriptors.add(desc);
+            }
+        }
+        return descriptors.iterator();
+    }
+
+    protected FeatureDescriptor makeDescriptor(String name, String description,
+            Class<?> elResolverType)
+    {
+        FeatureDescriptor fd = new FeatureDescriptor();
+        fd.setValue(ELResolver.RESOLVABLE_AT_DESIGN_TIME, Boolean.TRUE);
+        fd.setValue(ELResolver.TYPE, elResolverType);
+        fd.setName(name);
+        fd.setDisplayName(name);
+        fd.setShortDescription(description);
+        fd.setExpert(false);
+        fd.setHidden(false);
+        fd.setPreferred(true);
+        return fd;
+    }
+
+    @Override
+    public Class<?> getCommonPropertyType(ELContext context, Object base)
+    {
+        if (base == null)
+        {
+            return null;
+        }
+
+        if (base instanceof WindowScope)
+        {
+            return Object.class;
+        }
+        else if (WINDOW.equals(base.toString()))
+        {
+            return Object.class;
+        }
+
+        return null;
+    }
+}
diff --git a/client-window-example/src/main/java/org/apache/myfaces/example/windowScope/WindowScopeImpl.java b/client-window-example/src/main/java/org/apache/myfaces/example/windowScope/WindowScopeImpl.java
new file mode 100644
index 0000000..f42c01a
--- /dev/null
+++ b/client-window-example/src/main/java/org/apache/myfaces/example/windowScope/WindowScopeImpl.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2012 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.myfaces.example.windowScope;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+
+/**
+ *
+ * @author lu4242
+ */
+public class WindowScopeImpl extends WindowScope
+{
+
+    private static final String WINDOW_PREFIX = "oam.Window";
+    
+    /**
+     * Key for the cached render FlashMap instance on the request map.
+     */
+    static final String WINDOW_MAP = WINDOW_PREFIX + ".WINDOWMAP";
+    
+    /**
+     * Key on application map to keep current instance
+     */
+    static final String WINDOW_INSTANCE = WINDOW_PREFIX + ".INSTANCE";
+
+    /**
+     * Session map prefix to flash maps
+     */
+    static final String WINDOW_SESSION_MAP_SUBKEY_PREFIX = WINDOW_PREFIX + ".SCOPE";
+    
+    /**
+     * Token separator.
+     */
+    static final char SEPARATOR_CHAR = '.';
+    
+    public WindowScopeImpl(ExternalContext externalContext)
+    {
+        
+    }
+
+    public int size()
+    {
+        return getActiveWindowScopeMap().size();
+    }
+
+    public boolean isEmpty()
+    {
+        return getActiveWindowScopeMap().isEmpty();
+    }
+
+    public boolean containsKey(Object key)
+    {
+        return getActiveWindowScopeMap().containsKey(key);
+    }
+
+    public boolean containsValue(Object value)
+    {
+        return getActiveWindowScopeMap().containsValue(value);
+    }
+
+    public Object get(Object key)
+    {
+        return getActiveWindowScopeMap().get(key);
+    }
+
+    public Object put(String key, Object value)
+    {
+        return getActiveWindowScopeMap().put(key, value);
+    }
+
+    public Object remove(Object key)
+    {
+        return getActiveWindowScopeMap().remove(key);
+    }
+
+    public void putAll(Map<? extends String, ? extends Object> m)
+    {
+        getActiveWindowScopeMap().putAll(m);
+    }
+
+    public void clear()
+    {
+        getActiveWindowScopeMap().clear();
+    }
+
+    public Set<String> keySet()
+    {
+        return getActiveWindowScopeMap().keySet();
+    }
+
+    public Collection<Object> values()
+    {
+        return getActiveWindowScopeMap().values();
+    }
+
+    public Set<Entry<String, Object>> entrySet()
+    {
+        return getActiveWindowScopeMap().entrySet();
+    }
+    
+    private Map<String, Object> getActiveWindowScopeMap()
+    {
+        FacesContext context = FacesContext.getCurrentInstance();
+        Map<Object, Object> requestMap = context.getAttributes();
+        Map<String, Object> map = (Map<String, Object>) requestMap.get(WINDOW_MAP);
+        if (map == null)
+        {
+            String token = (String) context.getExternalContext().getClientWindow().getId();
+            String fullToken = WINDOW_SESSION_MAP_SUBKEY_PREFIX + SEPARATOR_CHAR + token;
+            map =  _createSubKeyMap(context, fullToken);
+            requestMap.put(WINDOW_MAP, map);
+        }
+        return map;
+    }
+    
+    /**
+     * Create a new subkey-wrapper of the session map with the given prefix.
+     * This wrapper is used to implement the maps for the flash scope.
+     * For more information see the SubKeyMap doc.
+     */
+    private Map<String, Object> _createSubKeyMap(FacesContext context, String prefix)
+    {
+        ExternalContext external = context.getExternalContext();
+        Map<String, Object> sessionMap = external.getSessionMap();
+
+        return new SubKeyMap<Object>(sessionMap, prefix);
+    }
+    
+    public static WindowScope getCurrentInstance(ExternalContext context)
+    {
+        Map<String, Object> applicationMap = context.getApplicationMap();
+        
+        WindowScope flash = (WindowScope) applicationMap.get(WINDOW_INSTANCE);
+        if (flash == null)
+        {
+            // synchronize the ApplicationMap to ensure that only
+            // once instance of FlashImpl is created and stored in it.
+            synchronized (applicationMap)
+            {
+                // check again, because first try was un-synchronized
+                flash = (WindowScope) applicationMap.get(WINDOW_INSTANCE);
+                if (flash == null)
+                {
+                    flash = new WindowScopeImpl(context);
+                    applicationMap.put(WINDOW_INSTANCE, flash);
+                }
+            }
+        }
+
+        return flash;
+    }
+}
diff --git a/client-window-example/src/main/webapp/META-INF/templates/example.xhtml b/client-window-example/src/main/webapp/META-INF/templates/example.xhtml
new file mode 100644
index 0000000..595168b
--- /dev/null
+++ b/client-window-example/src/main/webapp/META-INF/templates/example.xhtml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:h="http://java.sun.com/jsf/html"
+      xmlns:f="http://java.sun.com/jsf/core"
+      xmlns:ui="http://java.sun.com/jsf/facelets">
+<h:head>
+    <title>Hello World</title>
+</h:head>
+<h:body>
+    <h:outputStylesheet name="style.css" library="css"/>
+    <div id="container">
+        <ui:insert name="container"/>
+        <br/>
+        <br/>
+        <h:link outcome="home" value="Index"/>
+    </div>
+</h:body>
+</html>
diff --git a/client-window-example/src/main/webapp/WEB-INF/faces-config.xml b/client-window-example/src/main/webapp/WEB-INF/faces-config.xml
new file mode 100644
index 0000000..4c57112
--- /dev/null
+++ b/client-window-example/src/main/webapp/WEB-INF/faces-config.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+<!--
+ * 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.
+-->
+<faces-config version="2.0"
+              xmlns="http://java.sun.com/xml/ns/javaee"
+              xmlns:xi="http://www.w3.org/2001/XInclude"
+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
+              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
+    
+    <application>
+        <el-resolver>org.apache.myfaces.example.windowScope.WindowScopeELResolver</el-resolver>
+    </application>
+    
+    <!-- navigation rules for helloWorld flash post-redirect-get pattern -->
+    <navigation-rule>
+        <from-view-id>/flashprg1.xhtml</from-view-id>
+        <navigation-case>
+            <from-outcome>success</from-outcome>
+            <to-view-id>/flashprg2.xhtml</to-view-id>
+            <redirect/>
+        </navigation-case>
+    </navigation-rule>
+    <navigation-rule>
+        <from-view-id>/flashprg2.xhtml</from-view-id>
+        <navigation-case>
+            <from-outcome>back</from-outcome>
+            <to-view-id>/flashprg1.xhtml</to-view-id>
+        </navigation-case>
+    </navigation-rule>
+ 
+    <!-- navigation rules for helloWorld flash using putNow/keep method to keep previous name -->
+    <navigation-rule>
+        <from-view-id>/flashhw1.xhtml</from-view-id>
+        <navigation-case>
+            <from-outcome>success</from-outcome>
+            <to-view-id>/flashhw2.xhtml</to-view-id>
+        </navigation-case>
+    </navigation-rule>
+    <navigation-rule>
+        <from-view-id>/flashhw2.xhtml</from-view-id>
+        <navigation-case>
+            <from-outcome>back</from-outcome>
+            <to-view-id>/flashhw1.xhtml</to-view-id>
+        </navigation-case>
+    </navigation-rule>
+
+</faces-config>
+        
\ No newline at end of file
diff --git a/client-window-example/src/main/webapp/WEB-INF/web.xml b/client-window-example/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..75eb376
--- /dev/null
+++ b/client-window-example/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0"?>
+<!--
+ * 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.
+-->
+<web-app xmlns="http://java.sun.com/xml/ns/javaee"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+        version="2.5">
+
+    <description>MyProject web.xml</description>
+
+    <!-- JSF standard parameters -->
+    <context-param>
+        <description>Project stage for the application (new in 2.0). Expects one of
+            the following values: Development, Production, SystemTest, UnitTest
+        </description>
+        <param-name>javax.faces.PROJECT_STAGE</param-name>
+        <param-value>Development</param-value>
+    </context-param>
+    <context-param>
+        <description>
+            If this parameter is set to true and the submitted value of a component is
+            the empty string, the submitted value will be set to null
+        </description>
+        <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
+        <param-value>true</param-value>
+    </context-param>
+    <context-param>
+        <description>Define the state method to be used. There are two different options 
+            defined by the specification: 'client' and 'server' state.</description>
+        <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
+        <param-value>server</param-value>
+    </context-param>
+    <context-param>
+        <param-name>javax.faces.CLIENT_WINDOW_MODE</param-name>
+        <param-value>default</param-value>
+    </context-param>
+
+    <!-- MyFaces specific parameters -->
+    <!-- See http://myfaces.apache.org/docindex.html for documentation 
+         about MyFaces Projects -->
+    <!-- See http://myfaces.apache.org/core21/myfaces-impl/webconfig.html 
+         for an updated list of web config parameters for MyFaces Core 
+         See http://wiki.apache.org/myfaces/Secure_Your_Application
+         for instructions about how to secure your web application -->
+    <context-param>
+        <description>Only applicable if state saving method is "server" (= default).
+            Defines the amount (default = 20) of the latest views are stored in session.</description>
+        <param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</param-name>
+        <param-value>2</param-value>
+    </context-param>
+    
+    <context-param>
+        <param-name>org.apache.myfaces.NUMBER_OF_SEQUENTIAL_VIEWS_IN_SESSION</param-name>
+        <param-value>1</param-value>
+    </context-param>
+    <context-param>
+        <description>Only applicable if state saving method is "server" (= default).
+            If true (default) the state will be serialized to a byte stream before it
+            is written to the session.
+            If false the state will not be serialized to a byte stream.</description>
+        <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
+        <param-value>false</param-value>
+    </context-param>
+    <context-param>
+        <description>Only applicable if state saving method is "server" (= default) and if
+            org.apache.myfaces.SERIALIZE_STATE_IN_SESSION is true (= default)
+            If true (default) the serialized state will be compressed before it
+            is written to the session. If false the state will not be compressed.</description>
+        <param-name>org.apache.myfaces.COMPRESS_STATE_IN_SESSION</param-name>
+        <param-value>false</param-value>
+    </context-param>
+    <context-param>
+        <description>Defines which packages to scan for beans, separated by commas.
+        Useful for when using maven and jetty:run (version 6) or tomcat:run
+        </description>
+        <param-name>org.apache.myfaces.annotation.SCAN_PACKAGES</param-name>
+        <param-value>org.apache.myfaces.example</param-value>
+    </context-param>
+
+    <!-- Faces Servlet -->
+    <servlet>
+        <servlet-name>Faces Servlet</servlet-name>
+        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+
+    <!-- Faces Servlet Mapping -->
+    <servlet-mapping>
+        <servlet-name>Faces Servlet</servlet-name>
+        <url-pattern>*.jsf</url-pattern>
+    </servlet-mapping>
+
+    <!-- Welcome files -->
+    <welcome-file-list>
+        <welcome-file>index.html</welcome-file>
+    </welcome-file-list>
+
+</web-app>
diff --git a/client-window-example/src/main/webapp/flash1.xhtml b/client-window-example/src/main/webapp/flash1.xhtml
new file mode 100644
index 0000000..9a5edab
--- /dev/null
+++ b/client-window-example/src/main/webapp/flash1.xhtml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:c="http://java.sun.com/jsp/jstl/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ >
+<body>
+<ui:composition template="/META-INF/templates/example.xhtml">
+  <ui:define name="container">
+    <h1>Myfaces Examples</h1>
+    <h:form id="mainForm">
+      <h:outputText value="Flash 1"/>
+      <h:panelGrid columns="2">
+        <c:set target="${flash}" property="testProperty1" value="fooValue" />
+        <h:outputLabel value="testProperty1" for="tp1" />
+        <h:outputText id="tp1" value="#{flash.testProperty1}"/>
+        <h:outputLabel value="testProperty2" for="tp2" />
+        <h:outputText id="tp2" value="#{flash.testProperty2}"/>
+        <h:commandButton value="Go to flash2.jsp" action="#{flashBean.gotoFlash2}"></h:commandButton>
+        <h:messages showDetail="true" showSummary="false"/>
+      </h:panelGrid>
+    </h:form>
+  </ui:define>
+</ui:composition>
+</body>
+</html>
diff --git a/client-window-example/src/main/webapp/flash2.xhtml b/client-window-example/src/main/webapp/flash2.xhtml
new file mode 100644
index 0000000..dfab4d4
--- /dev/null
+++ b/client-window-example/src/main/webapp/flash2.xhtml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+  xmlns:c="http://java.sun.com/jsp/jstl/core"
+  xmlns:ui="http://java.sun.com/jsf/facelets"
+ >
+<body>
+<ui:composition template="/META-INF/templates/example.xhtml">
+  <ui:define name="container">
+    <h1>Myfaces Examples</h1>
+    <h:form id="mainForm">
+      <h:outputText value="Flash 2"/>
+      <c:set target="${flash}" property="testProperty2" value="fooValue2" />
+      <h:panelGrid columns="2">
+        <h:outputLabel value="testProperty1" for="tp1" />
+        <h:outputText id="tp1" value="#{flash.testProperty1}"/>
+        <h:outputLabel value="testProperty2" for="tp2" />
+        <h:outputText id="tp2" value="#{flash.testProperty2}"/>
+        <h:commandButton value="Go to flash3.jsp" action="#{flashBean.gotoFlash3}"/>
+        <h:messages showDetail="true" showSummary="false"/>
+      </h:panelGrid>
+    </h:form>
+  </ui:define>
+</ui:composition>
+</body>
+</html>
diff --git a/client-window-example/src/main/webapp/flash3.xhtml b/client-window-example/src/main/webapp/flash3.xhtml
new file mode 100644
index 0000000..4b95136
--- /dev/null
+++ b/client-window-example/src/main/webapp/flash3.xhtml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+  xmlns:c="http://java.sun.com/jsp/jstl/core"
+  xmlns:ui="http://java.sun.com/jsf/facelets"
+ >
+<body>
+<ui:composition template="/META-INF/templates/example.xhtml">
+  <ui:define name="container">
+    <h1>Myfaces Examples</h1>
+    <h:form id="mainForm">
+      <h:outputText value="Flash 3"/>
+      <h:panelGrid columns="2">
+        <h:outputLabel value="testProperty1" for="tp1" />
+        <h:outputText id="tp1" value="#{flash.testProperty1}"/>
+        <h:outputLabel value="testProperty2" for="tp2" />
+        <h:outputText id="tp2" value="#{flash.testProperty2}"/>
+        <h:commandButton value="Go to flash1.jsp" action="#{flashBean.gotoFlash1}"/>
+        <h:messages showDetail="true" showSummary="false"/>
+      </h:panelGrid>
+    </h:form>
+  </ui:define>
+</ui:composition>
+</body>
+</html>
diff --git a/client-window-example/src/main/webapp/flashKeep1.xhtml b/client-window-example/src/main/webapp/flashKeep1.xhtml
new file mode 100644
index 0000000..5fe15b4
--- /dev/null
+++ b/client-window-example/src/main/webapp/flashKeep1.xhtml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+    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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+	xmlns:h="http://java.sun.com/jsf/html"
+	xmlns:f="http://java.sun.com/jsf/core"
+	xmlns:c="http://java.sun.com/jsp/jstl/core"
+        xmlns:ui="http://java.sun.com/jsf/facelets">
+<body>
+<ui:composition template="/META-INF/templates/example.xhtml">
+  <ui:define name="container">
+    <h1>Myfaces Examples</h1>
+    <h:form id="mainForm">
+            <h3><h:outputText value="Flash Keep" /></h3>
+            <h:panelGrid columns="2">
+                <h:outputLabel value="Name" for="name" />
+                <h:inputText id="name" value="#{helloWorldFlashBean.name}" />
+            </h:panelGrid>
+            <h:commandButton action="#{helloWorldFlashBean.keepRedirect}" 
+                    value="Keep over Redirect" />
+    </h:form>
+  </ui:define>
+</ui:composition>
+</body>
+</html>
diff --git a/client-window-example/src/main/webapp/flashKeep2.xhtml b/client-window-example/src/main/webapp/flashKeep2.xhtml
new file mode 100644
index 0000000..e5ac430
--- /dev/null
+++ b/client-window-example/src/main/webapp/flashKeep2.xhtml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+    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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+	xmlns:h="http://java.sun.com/jsf/html"
+	xmlns:f="http://java.sun.com/jsf/core"
+	xmlns:c="http://java.sun.com/jsp/jstl/core"
+        xmlns:ui="http://java.sun.com/jsf/facelets">
+<body>
+<ui:composition template="/META-INF/templates/example.xhtml">
+  <ui:define name="container">
+    <h1>Myfaces Examples</h1>
+    <h:form id="mainForm">
+            <h3><h:outputText value="Flash Keep" /></h3>
+
+            Your name is: #{flash.name} <br/>
+            <h:commandButton action="#{helloWorldFlashBean.keepPostback}" 
+                    value="Do another postback" />
+    </h:form>
+  </ui:define>
+</ui:composition>
+</body>
+</html>
diff --git a/client-window-example/src/main/webapp/flashKeep3.xhtml b/client-window-example/src/main/webapp/flashKeep3.xhtml
new file mode 100644
index 0000000..7015508
--- /dev/null
+++ b/client-window-example/src/main/webapp/flashKeep3.xhtml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+    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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+	xmlns:h="http://java.sun.com/jsf/html"
+	xmlns:f="http://java.sun.com/jsf/core"
+	xmlns:c="http://java.sun.com/jsp/jstl/core"
+        xmlns:ui="http://java.sun.com/jsf/facelets">
+<body>
+<ui:composition template="/META-INF/templates/example.xhtml">
+  <ui:define name="container">
+    <h1>Myfaces Examples</h1>
+    <h:form id="mainForm">
+            <h3><h:outputText value="Flash Keep" /></h3>
+
+            This is now empty: #{flash.name}
+    </h:form>
+  </ui:define>
+</ui:composition>
+</body>
+</html>
diff --git a/client-window-example/src/main/webapp/flashKeepConfirmation.xhtml b/client-window-example/src/main/webapp/flashKeepConfirmation.xhtml
new file mode 100644
index 0000000..02be36d
--- /dev/null
+++ b/client-window-example/src/main/webapp/flashKeepConfirmation.xhtml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+    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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+	xmlns:h="http://java.sun.com/jsf/html"
+	xmlns:f="http://java.sun.com/jsf/core"
+	xmlns:c="http://java.sun.com/jsp/jstl/core"
+        xmlns:ui="http://java.sun.com/jsf/facelets">
+<body>
+<ui:composition template="/META-INF/templates/example.xhtml">
+  <ui:define name="container">
+    <h1>Myfaces Examples</h1>
+    <h:form id="mainForm">
+            <h3><h:outputText value="Flash Keep With Redirect (Confirmation)" /></h3>
+            <h:panelGrid columns="2">
+                <h:outputLabel value="Name" for="name" />
+                <h:outputText id="name" value="#{flash.keep.name}" />
+            </h:panelGrid>
+            <h:commandButton value="Confirm"  
+                     action="flashKeepFinished?faces-redirect=true"/>
+    </h:form>
+  </ui:define>
+</ui:composition>
+</body>
+</html>
diff --git a/client-window-example/src/main/webapp/flashKeepEntry.xhtml b/client-window-example/src/main/webapp/flashKeepEntry.xhtml
new file mode 100644
index 0000000..a5a6087
--- /dev/null
+++ b/client-window-example/src/main/webapp/flashKeepEntry.xhtml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+    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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+	xmlns:h="http://java.sun.com/jsf/html"
+	xmlns:f="http://java.sun.com/jsf/core"
+	xmlns:c="http://java.sun.com/jsp/jstl/core"
+        xmlns:ui="http://java.sun.com/jsf/facelets">
+<body>
+<ui:composition template="/META-INF/templates/example.xhtml">
+  <ui:define name="container">
+    <h1>Myfaces Examples</h1>
+    <h:form id="mainForm">
+            <h3><h:outputText value="Flash Keep With Redirect (Entry)" /></h3>
+            <h:panelGrid columns="2">
+                <h:outputLabel value="Name" for="name" />
+                <h:inputText id="name" value="#{flash.name}" />
+            </h:panelGrid>
+    <h:commandButton value="Submit" 
+            action="flashKeepConfirmation?faces-redirect=true"/>
+    </h:form>
+  </ui:define>
+</ui:composition>
+</body>
+</html>
diff --git a/client-window-example/src/main/webapp/flashKeepFinished.xhtml b/client-window-example/src/main/webapp/flashKeepFinished.xhtml
new file mode 100644
index 0000000..16e3c03
--- /dev/null
+++ b/client-window-example/src/main/webapp/flashKeepFinished.xhtml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+    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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+	xmlns:h="http://java.sun.com/jsf/html"
+	xmlns:f="http://java.sun.com/jsf/core"
+	xmlns:c="http://java.sun.com/jsp/jstl/core"
+        xmlns:ui="http://java.sun.com/jsf/facelets">
+<body>
+<ui:composition template="/META-INF/templates/example.xhtml">
+  <ui:define name="container">
+    <h1>Myfaces Examples</h1>
+    <h:form id="mainForm">
+            <h3><h:outputText value="Flash Keep With Redirect (Finished)" /></h3>
+            <h:panelGrid columns="2">
+                <h:outputLabel value="Name" for="name" />
+                <h:outputText id="name" value="#{flash.keep.name}" />
+            </h:panelGrid>
+    </h:form>
+  </ui:define>
+</ui:composition>
+</body>
+</html>
diff --git a/client-window-example/src/main/webapp/flashg1.xhtml b/client-window-example/src/main/webapp/flashg1.xhtml
new file mode 100644
index 0000000..3be46fc
--- /dev/null
+++ b/client-window-example/src/main/webapp/flashg1.xhtml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+  xmlns:c="http://java.sun.com/jsp/jstl/core"
+  xmlns:ui="http://java.sun.com/jsf/facelets"
+ >
+<body>
+<ui:composition template="/META-INF/templates/example.xhtml">
+  <ui:define name="container">
+    <h1>Myfaces Examples</h1>
+    <c:set target="#{flash}" property="name" value="Michi (from 1)"/>
+    <h:outputText value="#{flash.name}"/>
+    <h:link outcome="flashg2" value="to page2"/>
+  </ui:define>
+</ui:composition>
+</body>
+</html>
diff --git a/client-window-example/src/main/webapp/flashg2.xhtml b/client-window-example/src/main/webapp/flashg2.xhtml
new file mode 100644
index 0000000..6a37aa2
--- /dev/null
+++ b/client-window-example/src/main/webapp/flashg2.xhtml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+  xmlns:c="http://java.sun.com/jsp/jstl/core"
+  xmlns:ui="http://java.sun.com/jsf/facelets"
+ >
+<body>
+<ui:composition template="/META-INF/templates/example.xhtml">
+  <ui:define name="container">
+    <h1>Myfaces Examples</h1>
+    <c:set target="#{flash}" property="name" value="Michi (from 2)"/>
+    <h:outputText value="#{flash.name}"/>
+    <h:link outcome="flashg1" value="to page1"/> 
+  </ui:define>
+</ui:composition>
+</body>
+</html>
diff --git a/client-window-example/src/main/webapp/flashhw1.xhtml b/client-window-example/src/main/webapp/flashhw1.xhtml
new file mode 100644
index 0000000..891a49f
--- /dev/null
+++ b/client-window-example/src/main/webapp/flashhw1.xhtml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ >
+<body>
+<ui:composition template="/META-INF/templates/example.xhtml">
+  <ui:define name="container">
+    <h1>Myfaces Examples</h1>
+    <h:form id="mainForm">
+      <h:panelGrid columns="2">
+        <h:outputLabel for="name" value="Please enter your name" />
+        <h:inputText id="name" value="#{helloWorldFlashBean.name}" required="true"/>
+        <h:outputLabel for="pname" value="Previous name" />
+        <h:outputText id="pname" value="#{flash.name}"/>
+        <h:commandButton value="Press me" action="#{helloWorldFlashBean.sendPutNow}"/>
+        <h:messages showDetail="true" showSummary="false"/>
+      </h:panelGrid>
+    </h:form>
+  </ui:define>
+</ui:composition>
+</body>
+</html>
diff --git a/client-window-example/src/main/webapp/flashhw2.xhtml b/client-window-example/src/main/webapp/flashhw2.xhtml
new file mode 100644
index 0000000..14874ad
--- /dev/null
+++ b/client-window-example/src/main/webapp/flashhw2.xhtml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ >
+<body>
+<ui:composition template="/META-INF/templates/example.xhtml">
+  <ui:define name="container">
+    <h1>Myfaces Examples</h1>
+    <h:form id="mainForm">
+        <h2><h:outputText value="Hello #{helloWorldFlashBean.name}. Flash name should appear next request (press back)"/></h2>
+        <h:messages showDetail="true" showSummary="false"/>
+        <h:commandLink action="back">
+            <h:outputText value="Home"/>
+        </h:commandLink>
+    </h:form>
+  </ui:define>
+</ui:composition>
+</body>
+</html>
\ No newline at end of file
diff --git a/client-window-example/src/main/webapp/flashprg1.xhtml b/client-window-example/src/main/webapp/flashprg1.xhtml
new file mode 100644
index 0000000..95aa0d1
--- /dev/null
+++ b/client-window-example/src/main/webapp/flashprg1.xhtml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ >
+<body>
+<ui:composition template="/META-INF/templates/example.xhtml">
+  <ui:define name="container">
+    <h1>Myfaces Examples</h1>
+    <h:form id="mainForm">
+      <h:panelGrid columns="2">
+        <h:outputLabel for="name" value="Please enter your name" />
+        <h:inputText id="name" value="#{helloWorldFlashBean.name}" required="true"/>
+        <h:commandButton value="Press me" action="#{helloWorldFlashBean.send}"/>
+        <h:messages showDetail="true" showSummary="false"/>
+      </h:panelGrid>
+    </h:form>
+  </ui:define>
+</ui:composition>
+</body>
+</html>
diff --git a/client-window-example/src/main/webapp/flashprg2.xhtml b/client-window-example/src/main/webapp/flashprg2.xhtml
new file mode 100644
index 0000000..22652b5
--- /dev/null
+++ b/client-window-example/src/main/webapp/flashprg2.xhtml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:h="http://java.sun.com/jsf/html"
+ xmlns:f="http://java.sun.com/jsf/core"
+ xmlns:ui="http://java.sun.com/jsf/facelets"
+ >
+<body>
+<ui:composition template="/META-INF/templates/example.xhtml">
+  <ui:define name="container">
+    <h:form id="mainForm">
+        <h2><h:outputText value="Hello #{flash.name}. We hope you enjoy Apache MyFaces"/></h2>
+        <h:messages showDetail="true" showSummary="false"/>
+        <h:commandLink action="#{helloWorldFlashBean.back}">
+            <h:outputText value="Home"/>
+        </h:commandLink>
+    </h:form>
+  </ui:define>
+</ui:composition>
+</body>
+</html>
\ No newline at end of file
diff --git a/client-window-example/src/main/webapp/helloWorld.xhtml b/client-window-example/src/main/webapp/helloWorld.xhtml
new file mode 100644
index 0000000..b3da4ee
--- /dev/null
+++ b/client-window-example/src/main/webapp/helloWorld.xhtml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:h="http://java.sun.com/jsf/html"
+      xmlns:f="http://java.sun.com/jsf/core"
+      xmlns:ui="http://java.sun.com/jsf/facelets">
+<body>
+<ui:composition template="/META-INF/templates/example.xhtml">
+  <ui:define name="container">
+    <h1>MyFaces Hello World</h1>
+    <h:form id="mainForm">
+        <h:panelGrid columns="2">
+            <h:outputLabel for="name" value="Please enter your name"/>
+            <h:inputText id="name" value="#{helloWorld.name}" required="true"/>
+            <h:commandButton value="Press me" action="#{helloWorld.send}"/>
+            <h:messages showDetail="true" showSummary="false"/>
+        </h:panelGrid>
+    </h:form>
+  </ui:define>
+</ui:composition>    
+</body>
+</html>
diff --git a/client-window-example/src/main/webapp/home.xhtml b/client-window-example/src/main/webapp/home.xhtml
new file mode 100644
index 0000000..f4325a2
--- /dev/null
+++ b/client-window-example/src/main/webapp/home.xhtml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:h="http://java.sun.com/jsf/html"
+      xmlns:f="http://java.sun.com/jsf/core"
+      xmlns:cw="http://java.sun.com/jsf/composite/clientWindow">
+<h:head>
+    <title>Hello World</title>
+</h:head>
+<h:body>
+    <h:outputStylesheet name="style.css" library="css"/>
+    <div id="container">
+        <h1>MyFaces Hello World</h1>
+        
+        <h:panelGrid columns="1">
+        
+            <h:link outcome="helloWorld" value="helloWorld"/>
+            
+            <h:panelGroup>
+                <cw:disableClientWindow/>
+                <h:link outcome="helloWorld" value="helloWorld (do not append url param and set target=''blank'')" target="_blank"/>
+                <cw:enableClientWindow/>
+            </h:panelGroup>
+            
+            <h:link outcome="flash1" value="Flash"/>
+            
+            <h:link outcome="flashKeep1" value="Flash Keep"/>
+            
+            <h:link outcome="flashKeepEntry" value="Flash Keep Entry"/>
+            
+            <h:link outcome="flashg1" value="Flash using c:set"/>
+            
+            <h:link outcome="flashhw1" value="HelloWorld using Flash"/>
+            
+            <h:link outcome="flashprg1" value="Flash in POST-REDIRECT-GET"/>
+            
+        </h:panelGrid>
+    </div>
+</h:body>
+</html>
diff --git a/client-window-example/src/main/webapp/index.html b/client-window-example/src/main/webapp/index.html
new file mode 100644
index 0000000..d53f072
--- /dev/null
+++ b/client-window-example/src/main/webapp/index.html
@@ -0,0 +1,24 @@
+<!--
+    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.
+-->
+<html>
+<head>
+    <meta http-equiv="refresh" content="0; URL=home.jsf">
+</head>
+</html>
+        
diff --git a/client-window-example/src/main/webapp/page2.xhtml b/client-window-example/src/main/webapp/page2.xhtml
new file mode 100644
index 0000000..d248aa7
--- /dev/null
+++ b/client-window-example/src/main/webapp/page2.xhtml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:h="http://java.sun.com/jsf/html"
+      xmlns:f="http://java.sun.com/jsf/core"
+      xmlns:ui="http://java.sun.com/jsf/facelets">
+<body>
+<ui:composition template="/META-INF/templates/example.xhtml">
+  <ui:define name="container">
+        <h1>MyFaces Hello World</h1>
+        <h:outputText value="Hello #{helloWorld.name}. We hope you enjoy Apache MyFaces!"/>
+        <br/>
+        <h:link value="Home" outcome="helloWorld"/>
+  </ui:define>
+</ui:composition>
+</body>
+</html>
diff --git a/client-window-example/src/main/webapp/resources/clientWindow/disableClientWindow.xhtml b/client-window-example/src/main/webapp/resources/clientWindow/disableClientWindow.xhtml
new file mode 100644
index 0000000..b662ed4
--- /dev/null
+++ b/client-window-example/src/main/webapp/resources/clientWindow/disableClientWindow.xhtml
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:cc="http://java.sun.com/jsf/composite">
+    <cc:interface componentType="oam.clientWindow.disable">
+    </cc:interface>
+    <cc:implementation>
+    </cc:implementation>
+</html>
\ No newline at end of file
diff --git a/client-window-example/src/main/webapp/resources/clientWindow/enableClientWindow.xhtml b/client-window-example/src/main/webapp/resources/clientWindow/enableClientWindow.xhtml
new file mode 100644
index 0000000..f2cdee9
--- /dev/null
+++ b/client-window-example/src/main/webapp/resources/clientWindow/enableClientWindow.xhtml
@@ -0,0 +1,9 @@
+<?xml version='1.0' encoding='UTF-8' ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:cc="http://java.sun.com/jsf/composite">
+    <cc:interface componentType="oam.clientWindow.enable">
+    </cc:interface>
+    <cc:implementation>
+    </cc:implementation>
+</html>
\ No newline at end of file
diff --git a/api/src/main/java/javax/faces/lifecycle/Lifecycle.java b/client-window-example/src/main/webapp/resources/css/style.css
old mode 100755
new mode 100644
similarity index 50%
copy from api/src/main/java/javax/faces/lifecycle/Lifecycle.java
copy to client-window-example/src/main/webapp/resources/css/style.css
index 128c616..5d1ec09
--- a/api/src/main/java/javax/faces/lifecycle/Lifecycle.java
+++ b/client-window-example/src/main/webapp/resources/css/style.css
@@ -16,27 +16,20 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package javax.faces.lifecycle;
 
-import javax.faces.FacesException;
-
-/**
- * see Javadoc of <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a>
- *
- * @author Manfred Geiler (latest modification by $Author$)
- * @version $Revision$ $Date$
- */
-public abstract class Lifecycle
-{
-    public abstract void addPhaseListener(javax.faces.event.PhaseListener listener);
-
-    public abstract void execute(javax.faces.context.FacesContext context)
-            throws FacesException;
-
-    public abstract javax.faces.event.PhaseListener[] getPhaseListeners();
+body {
+    background-color: rgb(0, 35, 75);
+    font-family: tahoma, arial, helvetica, sans-serif;
+    font-size: 12px;
+}
 
-    public abstract void removePhaseListener(javax.faces.event.PhaseListener listener);
+#container {
+    margin: 10px auto;
+    width: 900px;
+    background-color: white;
+    padding: 3px;
+}
 
-    public abstract void render(javax.faces.context.FacesContext context)
-            throws FacesException;
+h1 {
+    font-size: 20px;
 }
diff --git a/client-window-example/src/test/java/org/apache/myfaces/example/clientWindow/CheckFaceletsFileTestCase.java b/client-window-example/src/test/java/org/apache/myfaces/example/clientWindow/CheckFaceletsFileTestCase.java
new file mode 100644
index 0000000..4e741df
--- /dev/null
+++ b/client-window-example/src/test/java/org/apache/myfaces/example/clientWindow/CheckFaceletsFileTestCase.java
@@ -0,0 +1,159 @@
+/*
+ * 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.example.clientWindow;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.ResponseWriter;
+import org.apache.myfaces.shared.config.MyfacesConfig;
+
+import org.apache.myfaces.view.facelets.FaceletFactory;
+import org.apache.myfaces.view.facelets.FaceletTestCase;
+import org.apache.myfaces.view.facelets.compiler.Compiler;
+import org.apache.myfaces.view.facelets.util.FastWriter;
+import org.junit.Test;
+
+public class CheckFaceletsFileTestCase extends FaceletTestCase
+{
+
+    @Override
+    protected void setUpServletObjects() throws Exception
+    {
+        super.setUpServletObjects();
+        servletContext.addInitParameter("org.apache.myfaces.annotation.SCAN_PACKAGES",
+                "org.apache.myfaces.example");
+        
+    }
+    /**
+     * Check all .xhtml can be parsed by facelets compiler
+     * 
+     * @throws Exception
+     */
+    @Test
+    public void testCanCompileFaceletFiles() throws Exception
+    {
+        Compiler compiler = vdl.createCompiler(facesContext);
+        FaceletFactory factory = vdl.createFaceletFactory(facesContext, compiler);
+        
+        checkFaceletsFiles(factory, "/");
+    }
+
+    private void checkFaceletsFiles(FaceletFactory factory, String pathBase) throws Exception
+    {
+        Set<String> paths = externalContext.getResourcePaths(pathBase);
+        for (String path : paths)
+        {
+            if (path.endsWith(".xhtml"))
+            {
+                factory.getFacelet(getLocalFile(path.substring(1)));
+            }
+            else if (path.endsWith("/"))
+            {
+                checkFaceletsFiles(factory, path);
+            }
+        }
+    }
+
+
+    /**
+     * Check a if a single view can be built.
+     * 
+     * @throws Exception
+     */
+    @Test
+    public void testSingleFaceletsFile() throws Exception {
+        //Step 1: initialize beans
+        
+        //Step 2: build view
+        UIViewRoot root = facesContext.getViewRoot();
+        vdl.buildView(facesContext, root, "helloWorld.xhtml");
+        
+        //Step 3: render view
+        FastWriter fw = new FastWriter();
+        ResponseWriter rw = facesContext.getResponseWriter();
+        rw = rw.cloneWithWriter(fw);
+        facesContext.setResponseWriter(rw);
+        root.encodeAll(facesContext);
+        //System.out.println(fw);
+    }
+    
+    @Test
+    public void testCanBuildViews() throws Exception {
+        //Step 1: initialize beans
+        /*
+        List<String> viewPaths = new ArrayList<String>();
+        
+        Set<String> paths = externalContext.getResourcePaths("/");
+        
+        for (String path : paths)
+        {
+            // Those places are used to hold templates and composite components,
+            // ignore them.
+            if (path.startsWith("/META-INF") ||
+                path.startsWith("/WEB-INF") ||
+                path.startsWith("/resources"))
+            {
+                continue;
+            }
+            else if (path.endsWith(".xhtml")) 
+            {
+                viewPaths.add(path);
+            }
+            else if (path.endsWith("/"))
+            {
+                addViewFacelets(viewPaths, path);
+            }
+        }
+        
+        //Step 2: build view
+        for (String viewPath : viewPaths)
+        {
+            UIViewRoot root = application.getViewHandler().createView(facesContext, viewPath);
+            facesContext.setViewRoot(root);
+            vdl.buildView(facesContext, root, viewPath);
+        }*/
+    }
+    
+    private void addViewFacelets(List<String> viewPaths, String pathBase)
+    {
+        Set<String> paths = externalContext.getResourcePaths(pathBase);
+        for (String path : paths)
+        {
+            if (path.endsWith(".xhtml"))
+            {
+                viewPaths.add(path);
+            }
+            else if (path.endsWith("/"))
+            {
+                addViewFacelets(viewPaths, path);
+            }
+        }
+    }
+
+    
+    @Override
+    protected String getDirectory()
+    {
+        return "webapp";
+    }
+
+}
diff --git a/client-window-example/src/test/resources/webapp/README.txt b/client-window-example/src/test/resources/webapp/README.txt
new file mode 100644
index 0000000..13e8319
--- /dev/null
+++ b/client-window-example/src/test/resources/webapp/README.txt
@@ -0,0 +1 @@
+This folder is just a hard copy of the files on src/main/webapp, to make them available on testing time using junit. Please do not edit anything here or you will lose the changes.
\ No newline at end of file
diff --git a/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImpl.java b/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImpl.java
index 977fabc..0899bbd 100755
--- a/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImpl.java
+++ b/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImpl.java
@@ -38,6 +38,8 @@ import javax.faces.context.FacesContext;
 import javax.faces.context.Flash;
 import javax.faces.context.PartialResponseWriter;
 import javax.faces.context.PartialViewContext;
+import javax.faces.lifecycle.ClientWindow;
+import javax.faces.render.ResponseStateManager;
 import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
@@ -314,13 +316,36 @@ public final class ServletExternalContextImpl extends ServletExternalContextImpl
     {
         checkNull(url, "url");
         checkHttpServletRequest();
-        return ((HttpServletResponse) _servletResponse).encodeURL(url);
+        String encodedUrl = ((HttpServletResponse) _servletResponse).encodeURL(url);
+        encodedUrl = encodeWindowId(encodedUrl);
+        return encodedUrl;
+    }
+    
+    private String encodeWindowId(String encodedUrl)
+    {
+        FacesContext facesContext = FacesContext.getCurrentInstance();
+        if (ClientWindow.isClientWindowUrlQueryParameterEnabled(facesContext))
+        {
+            //TODO: Use StringBuilder or some optimization.
+            ClientWindow window = facesContext.getExternalContext().getClientWindow();
+            if (window != null)
+            {
+                if (!encodedUrl.contains(ResponseStateManager.CLIENT_WINDOW_URL_PARAM))
+                {
+                    encodedUrl = encodedUrl + ( (encodedUrl.indexOf(URL_QUERY_SEPERATOR) != -1) ? 
+                            URL_PARAM_SEPERATOR : URL_QUERY_SEPERATOR ) + 
+                            ResponseStateManager.CLIENT_WINDOW_URL_PARAM +
+                            URL_NAME_VALUE_PAIR_SEPERATOR+ window.getId();
+                }
+            }
+        }
+        return encodedUrl;
     }
 
     @Override
     public String encodeBookmarkableURL(String baseUrl, Map<String,List<String>> parameters)
     {
-        return encodeURL(baseUrl, parameters);
+        return encodeWindowId(encodeURL(baseUrl, parameters));
     }
 
     @Override
@@ -342,13 +367,13 @@ public final class ServletExternalContextImpl extends ServletExternalContextImpl
     {
         checkNull(url, "url");
         checkHttpServletRequest();
-        return ((HttpServletResponse) _servletResponse).encodeURL(url);
+        return encodeWindowId(((HttpServletResponse) _servletResponse).encodeURL(url));
     }
 
     @Override
     public String encodeRedirectURL(String baseUrl, Map<String,List<String>> parameters)
     {
-        return _httpServletResponse.encodeRedirectURL(encodeURL(baseUrl, parameters));
+        return encodeWindowId(_httpServletResponse.encodeRedirectURL(encodeURL(baseUrl, parameters)));
     }
 
     @Override
diff --git a/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImplBase.java b/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImplBase.java
index e5c4446..672da03 100644
--- a/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImplBase.java
+++ b/impl/src/main/java/org/apache/myfaces/context/servlet/ServletExternalContextImplBase.java
@@ -25,6 +25,7 @@ import java.util.Map;
 import java.util.Set;
 
 import javax.faces.context.ExternalContext;
+import javax.faces.lifecycle.ClientWindow;
 import javax.servlet.ServletContext;
 
 import org.apache.myfaces.context.ReleaseableExternalContext;
@@ -46,12 +47,15 @@ public abstract class ServletExternalContextImplBase extends ExternalContext
     private ServletContext _servletContext;
     private Map<String, Object> _applicationMap;
     private Map<String, String> _initParameterMap;
+    private ClientWindow _clientWindow;
+
     
     public ServletExternalContextImplBase(ServletContext servletContext)
     {
         _servletContext = servletContext;
         _applicationMap = null;
         _initParameterMap = null;
+        _clientWindow = null;
     }
     
     public void release()
@@ -59,6 +63,7 @@ public abstract class ServletExternalContextImplBase extends ExternalContext
         _servletContext = null;
         _applicationMap = null;
         _initParameterMap = null;
+        _clientWindow = null;
     }
     
     // ~ Methods which only rely on the ServletContext-------------------------
@@ -159,6 +164,16 @@ public abstract class ServletExternalContextImplBase extends ExternalContext
         return _servletContext.getRealPath(path);
     }
     
+    public ClientWindow getClientWindow()
+    {
+        return _clientWindow;
+    }
+    
+    public void setClientWindow(ClientWindow window)
+    {
+        _clientWindow = window;
+    }
+    
     // ~ Methods which verify some required behavior---------------------------
     
     protected void checkNull(final Object o, final String param)
diff --git a/impl/src/main/java/org/apache/myfaces/lifecycle/CODIClientSideWindow.java b/impl/src/main/java/org/apache/myfaces/lifecycle/CODIClientSideWindow.java
new file mode 100644
index 0000000..fd182b2
--- /dev/null
+++ b/impl/src/main/java/org/apache/myfaces/lifecycle/CODIClientSideWindow.java
@@ -0,0 +1,424 @@
+/*
+ * 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.lifecycle;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import javax.faces.FacesException;
+import javax.faces.application.Resource;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.lifecycle.ClientWindow;
+import javax.faces.render.ResponseStateManager;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ *
+ * @author lu4242
+ */
+public class CODIClientSideWindow extends ClientWindow
+{
+    /**
+     * Key for storing the window-id e.g. in URLs
+     */
+    //private static final String WINDOW_CONTEXT_ID_PARAMETER_KEY = 
+    //        ResponseStateManager.CLIENT_WINDOW_URL_PARAM;
+
+    /**
+     * Value which can be used as "window-id" by external clients which aren't aware of windows.
+     * It deactivates e.g. the redirect for the initial request.
+     */
+    private static final String AUTOMATED_ENTRY_POINT_PARAMETER_KEY = "automatedEntryPoint";    
+    
+    private static final long serialVersionUID = 5293942986187078113L;
+
+    private static final String WINDOW_ID_COOKIE_PREFIX = "jfwid-";
+    private static final String CODI_REQUEST_TOKEN = "mfRid";
+
+    private static final String UNINITIALIZED_WINDOW_ID_VALUE = "uninitializedWindowId";
+    private static final String WINDOW_ID_REPLACE_PATTERN = "$$windowIdValue$$";
+    private static final String NOSCRIPT_URL_REPLACE_PATTERN = "$$noscriptUrl$$";
+    private static final String NOSCRIPT_PARAMETER = "mfDirect";
+
+    private final ClientConfig clientConfig;
+
+    private final WindowContextConfig windowContextConfig;
+    
+    private final TokenGenerator clientWindowTokenGenerator;    
+    
+    private String windowId;
+    
+    private String unparsedWindowHandlerHtml = null;
+
+    /*
+    protected CODIClientSideWindow()
+    {
+        // needed for proxying
+    }*/
+
+    protected CODIClientSideWindow(TokenGenerator clientWindowTokenGenerator,
+            WindowContextConfig windowContextConfig,
+            ClientConfig clientConfig)
+    {
+        this.windowContextConfig = windowContextConfig;
+        this.clientConfig = clientConfig;
+        this.clientWindowTokenGenerator = clientWindowTokenGenerator;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    /*
+    public String restoreWindowId(ExternalContext externalContext)
+    {
+        if (this.clientConfig.isJavaScriptEnabled())
+        {
+            return (String) externalContext.getRequestMap().get(
+                    WINDOW_CONTEXT_ID_PARAMETER_KEY);
+        }
+        else
+        {
+            // fallback
+            //if(!this.useWindowAwareUrlEncoding)
+            //{
+            //    return null;
+            //}
+
+            return externalContext.getRequestParameterMap().get(WINDOW_CONTEXT_ID_PARAMETER_KEY);
+        }
+    }*/
+
+    /**
+     * {@inheritDoc}
+     */
+    //public void beforeLifecycleExecute(FacesContext facesContext)
+    public void decode(FacesContext facesContext)
+    {
+        if (facesContext.isPostback())
+        {
+            // In postback, we can safely ignore the query param, because it is not useful
+            if (getId() == null)
+            {
+                 setId(calculateWindowIdFromPost(facesContext));
+            }
+        }
+
+        if (!isClientSideWindowHandlerRequest(facesContext))
+        {
+            return;
+        }
+        
+        ExternalContext externalContext = facesContext.getExternalContext();
+
+        if (isNoscriptRequest(externalContext))
+        {
+            // the client has JavaScript disabled
+            clientConfig.setJavaScriptEnabled(false);
+            return;
+        }
+
+        String windowId = getWindowIdFromCookie(externalContext);
+        if (windowId == null)
+        {
+            // GET request without windowId - send windowhandlerfilter.html to get the windowId
+            sendWindowHandlerHtml(facesContext, null);
+            facesContext.responseComplete();
+        }
+        else
+        {
+            if (AUTOMATED_ENTRY_POINT_PARAMETER_KEY.equals(windowId) ||
+                (!windowContextConfig.isUnknownWindowIdsAllowed() /*&&
+                 !ConversationUtils.isWindowActive(this.windowContextManager, windowId)*/))
+            {
+                // no or invalid windowId --> create new one
+                // don't use createWindowId() the following call will ensure the max. window context count,...
+                //windowId = this.windowContextManager.getCurrentWindowContext().getId();
+                windowId = createWindowId(facesContext);
+
+                // GET request with NEW windowId - send windowhandlerfilter.html to set and re-get the windowId
+                sendWindowHandlerHtml(facesContext, windowId);
+                facesContext.responseComplete();
+            }
+            else
+            {
+                // we have a valid windowId - set it and continue with the request
+                // TODO only set internally and provide via restoreWindowId()? 
+                //externalContext.getRequestMap().put(WINDOW_CONTEXT_ID_PARAMETER_KEY, windowId);
+                setId(windowId);
+            }
+        }
+    }
+
+    public String calculateWindowIdFromPost(FacesContext context)
+    {
+        //1. If it comes as parameter, it takes precedence over any other choice, because
+        //   no browser is capable to do a POST and create a new window at the same time.
+        String windowId = context.getExternalContext().getRequestParameterMap().get(
+                ResponseStateManager.CLIENT_WINDOW_PARAM);
+        if (windowId != null)
+        {
+            return windowId;
+        }
+        return null;
+    }
+    
+    private boolean isClientSideWindowHandlerRequest(FacesContext facesContext)
+    {
+        // no POST request and javascript enabled
+        // NOTE that for POST-requests the windowId is saved in the state (see WindowContextIdHolderComponent)
+        return !facesContext.isPostback() && clientConfig.isClientSideWindowHandlerRequest(facesContext);
+    }
+
+    private boolean isNoscriptRequest(ExternalContext externalContext)
+    {
+        String noscript = externalContext.getRequestParameterMap().get(NOSCRIPT_PARAMETER);
+
+        return (noscript != null && "true".equals(noscript));
+    }
+
+    private void sendWindowHandlerHtml(FacesContext facesContext, String windowId)
+    {
+        HttpServletResponse httpResponse = (HttpServletResponse) facesContext.getExternalContext().getResponse();
+
+        try
+        {
+            httpResponse.setStatus(HttpServletResponse.SC_OK);
+            httpResponse.setContentType("text/html");
+
+            if (unparsedWindowHandlerHtml == null)
+            {
+                Resource resource = facesContext.getApplication().getResourceHandler().createResource(
+                        "windowhandler.html", "org.apache.myfaces.windowId");
+                
+                unparsedWindowHandlerHtml = convertStreamToString(resource.getInputStream());
+            }
+            
+            String windowHandlerHtml = unparsedWindowHandlerHtml;
+
+            if (windowId == null)
+            {
+                windowId = UNINITIALIZED_WINDOW_ID_VALUE;
+            }
+
+            // set the windowId value in the javascript code
+            windowHandlerHtml = windowHandlerHtml.replace(WINDOW_ID_REPLACE_PATTERN, windowId);
+
+            // set the noscript-URL for users with no JavaScript
+            windowHandlerHtml = windowHandlerHtml.replace(
+                    NOSCRIPT_URL_REPLACE_PATTERN, getNoscriptUrl(facesContext.getExternalContext()));
+
+            OutputStream os = httpResponse.getOutputStream();
+            try
+            {
+                os.write(windowHandlerHtml.getBytes());
+            }
+            finally
+            {
+                os.close();
+            }
+        }
+        catch (IOException ioe)
+        {
+            throw new FacesException(ioe);
+        }
+    }
+    
+    private static String convertStreamToString(InputStream is)
+    {
+        StringBuilder sb = new StringBuilder();
+        try
+        {
+            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+            String line = null;
+            while ((line = reader.readLine()) != null)
+            {
+              sb.append(line + "\n");
+            }
+        }
+        catch (IOException e)
+        {
+            throw new FacesException(e);
+        }
+        finally
+        {
+            if (is != null)
+            {
+                try
+                {
+                    is.close();
+                }
+                catch (IOException e)
+                {
+                    //No op
+                }                
+            }
+        }
+        return sb.toString();
+    }    
+
+    private String getNoscriptUrl(ExternalContext externalContext)
+    {
+        String url = externalContext.getRequestPathInfo();
+        if (url == null)
+        {
+            url = "";
+        }
+
+        // only use the very last part of the url
+        int lastSlash = url.lastIndexOf('/');
+        if (lastSlash != -1)
+        {
+            url = url.substring(lastSlash + 1);
+        }
+
+        // add request parameter
+        url = addParameters(externalContext, url, true, true, true);
+
+        // add noscript parameter
+        if (url.contains("?"))
+        {
+            url = url + "&";
+        }
+        else
+        {
+            url = url + "?";
+        }
+        url = url + NOSCRIPT_PARAMETER + "=true";
+
+        // NOTE that the url could contain data for an XSS attack
+        // like e.g. ?"></a><a href%3D"http://hacker.org/attack.html?a
+        // DO NOT REMOVE THE FOLLOWING LINES!
+        url = url.replace("\"", "");
+        url = url.replace("\'", "");
+
+        return url;
+    }
+
+    /**
+     * Adds the current request-parameters to the given url
+     * @param externalContext current external-context
+     * @param url current url
+     * @param addRequestParameter flag which indicates if the request params should be added or not
+     * @param addPageParameter flag which indicates if the view params should be added or not {@see ViewParameter}
+     * @param encodeValues flag which indicates if parameter values should be encoded or not
+     * @return url with request-parameters
+     */
+    public static String addParameters(ExternalContext externalContext, String url,
+                                       boolean addRequestParameter, boolean addPageParameter, boolean encodeValues)
+    {
+        StringBuilder finalUrl = new StringBuilder(url);
+        boolean existingParameters = url.contains("?");
+        boolean urlContainsWindowId = url.contains(ResponseStateManager.CLIENT_WINDOW_URL_PARAM + "=");
+
+        /* TODO: implement me
+        for(RequestParameter requestParam :
+                getParameters(externalContext, true, addRequestParameter, addPageParameter))
+        {
+            String key = requestParam.getKey();
+
+            //TODO eval if we should also filter the other params
+            if(WindowContextManager.WINDOW_CONTEXT_ID_PARAMETER_KEY.equals(key) && urlContainsWindowId)
+            {
+                continue;
+            }
+
+            for(String parameterValue : requestParam.getValues())
+            {
+                if(!url.contains(key + "=" + parameterValue) &&
+                        !url.contains(key + "=" + encodeURLParameterValue(parameterValue, externalContext)))
+                {
+                    if(!existingParameters)
+                    {
+                        finalUrl.append("?");
+                        existingParameters = true;
+                    }
+                    else
+                    {
+                        finalUrl.append("&");
+                    }
+                    finalUrl.append(key);
+                    finalUrl.append("=");
+
+                    if(encodeValues)
+                    {
+                        finalUrl.append(encodeURLParameterValue(parameterValue, externalContext));
+                    }
+                    else
+                    {
+                        finalUrl.append(parameterValue);
+                    }
+                }
+            }
+        }
+        */
+        return finalUrl.toString();
+    }
+    
+    protected String createWindowId(FacesContext context)
+    {
+        String windowId = clientWindowTokenGenerator._getNextToken();
+        setId(windowId);
+        return windowId;
+    }
+    
+    private String getWindowIdFromCookie(ExternalContext externalContext)
+    {
+        String cookieName = WINDOW_ID_COOKIE_PREFIX + getRequestToken(externalContext);
+        Cookie cookie = (Cookie) externalContext.getRequestCookieMap().get(cookieName);
+
+        if (cookie != null)
+        {
+            // manually blast the cookie away, otherwise it pollutes the
+            // cookie storage in some browsers. E.g. Firefox doesn't
+            // cleanup properly, even if the max-age is reached.
+            cookie.setMaxAge(0);
+
+            return cookie.getValue();
+        }
+
+        return null;
+    }
+
+    private String getRequestToken(ExternalContext externalContext)
+    {
+        String requestToken = externalContext.getRequestParameterMap().get(CODI_REQUEST_TOKEN);
+        if (requestToken != null)
+        {
+            return requestToken;
+        }
+
+        return "";
+    }
+
+    @Override
+    public String getId()
+    {
+        return windowId;
+    }
+    
+    public void setId(String id)
+    {
+        windowId = id;
+    }
+    
+}
diff --git a/impl/src/main/java/org/apache/myfaces/lifecycle/ClientConfig.java b/impl/src/main/java/org/apache/myfaces/lifecycle/ClientConfig.java
new file mode 100644
index 0000000..e9d491f
--- /dev/null
+++ b/impl/src/main/java/org/apache/myfaces/lifecycle/ClientConfig.java
@@ -0,0 +1,241 @@
+/*
+ * 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.lifecycle;
+
+
+import javax.faces.context.FacesContext;
+import java.io.Serializable;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Map;
+
+/**
+ * Contains information about whether the user has
+ * JavaScript enabled on his client, etc.
+ * It also contains the windowhandler html which gets sent to
+ * the browser to detect the current windowId.
+ *
+ * This allows the 'customisation' of this html file to e.g.
+ * adopt the background colour to avoid screen flickering.
+ *
+ * Please note that all subclasses of ClientConfig should also
+ * be &#064;SessionScoped as well!
+ */
+public class ClientConfig implements Serializable
+{
+    private static final long serialVersionUID = 581351549574404793L;
+
+    /** We will set a cookie with this very name if a noscript link got clicked by the user */
+    public static final String COOKIE_NAME_NOSCRIPT_ENABLED = "mfNoScriptEnabled";
+
+    private volatile Boolean javaScriptEnabled = null;
+
+    protected String windowHandlerHtml;
+
+    /** lazily initiated via {@link #getUserAgent(javax.faces.context.FacesContext)} */
+    private volatile String userAgent = null;
+
+    /**
+     * The location of the default windowhandler resource
+     */
+    //private static final String DEFAULT_WINDOW_HANDLER_HTML_FILE = "static/windowhandler.html";
+
+    /**
+     * Defaults to <code>true</code>.
+     * @return if the user has JavaScript enabled
+     */
+    public boolean isJavaScriptEnabled()
+    {
+        if (javaScriptEnabled == null)
+        {
+            synchronized(this)
+            {
+                // double lock checking idiom on volatile variable works since java5
+                if (javaScriptEnabled == null)
+                {
+                    // no info means that it is default -> true
+                    javaScriptEnabled = Boolean.TRUE;
+
+                    FacesContext facesContext = FacesContext.getCurrentInstance();
+                    if (facesContext != null)
+                    {
+                        Cookie cookie = (Cookie) facesContext.getExternalContext().
+                                getRequestCookieMap().get(COOKIE_NAME_NOSCRIPT_ENABLED);
+                        if (cookie!= null)
+                        {
+                            javaScriptEnabled = Boolean.parseBoolean((String) cookie.getValue());
+                        }
+                    }
+                }
+            }
+        }
+        return javaScriptEnabled;
+    }
+
+    /**
+     * Set it to <code>false</code> if you don't like to use the
+     * JavaScript based client side windowhandler. In this case
+     * the request will be returned directly.
+     * @param javaScriptEnabled
+     */
+    public void setJavaScriptEnabled(boolean javaScriptEnabled)
+    {
+        this.javaScriptEnabled = javaScriptEnabled;
+
+        // and now also store this information inside a cookie!
+        FacesContext facesContext = FacesContext.getCurrentInstance();
+        if (facesContext != null)
+        {
+            Object r = facesContext.getExternalContext().getResponse();
+            if (r instanceof HttpServletResponse)
+            {
+                Cookie cookie = new Cookie(COOKIE_NAME_NOSCRIPT_ENABLED, "" + javaScriptEnabled);
+                cookie.setPath("/"); // for all the server
+                HttpServletResponse response = (HttpServletResponse) r;
+                response.addCookie(cookie);
+            }
+        }
+    }
+
+    /**
+     * For branding the whole windowhandler page - e.g. not only change the
+     * background color, add some images and empty menu structure
+     * or the language of the message text - you can just copy the content of the
+     * {@link #DEFAULT_WINDOW_HANDLER_HTML_FILE} and adopt it to your needs.
+     *
+     * The reason for this is to minimize visual side effects on browsers who do
+     * not properly support html5 localstorage.
+     *
+     * @return the location of the <i>windowhandler.html</i> resource
+     *         which should be sent to the users browser.
+     */
+    /*
+    public String getWindowHandlerResourceLocation()
+    {
+        return DEFAULT_WINDOW_HANDLER_HTML_FILE;
+    }*/
+
+    /**
+     * This might return different windowhandlers based on user settings like
+     * his language, an affiliation, etc
+     * @return a String containing the whole windowhandler.html file.
+     * @throws IOException
+     */
+    /*
+    public String getWindowHandlerHtml() throws IOException
+    {
+        if (FacesContext.getCurrentInstance().isProjectStage(ProjectStage.Development) 
+                && windowHandlerHtml != null)
+        {
+            // use cached windowHandlerHtml except in Development
+            return windowHandlerHtml;
+        }
+
+        InputStream is = ClassUtils.getContextClassLoader().getResourceAsStream(
+                getWindowHandlerResourceLocation());
+        StringBuffer sb = new StringBuffer();
+        try
+        {
+            byte[] buf = new byte[16 * 1024];
+            int bytesRead;
+            while ((bytesRead = is.read(buf)) != -1)
+            {
+                String sbuf = new String(buf, 0, bytesRead);
+                sb.append(sbuf);
+            }
+        }
+        finally
+        {
+            is.close();
+        }
+
+        windowHandlerHtml = sb.toString();
+
+        return windowHandlerHtml;
+    }*/
+
+
+    /**
+     * This information will get stored as it cannot
+     * change during the session anyway.
+     * @return the UserAgent of the request.
+     */
+    public String getUserAgent(FacesContext facesContext)
+    {
+        if (userAgent == null)
+        {
+            synchronized (this)
+            {
+                if (userAgent == null)
+                {
+                    Map<String, String[]> requestHeaders =
+                            facesContext.getExternalContext().getRequestHeaderValuesMap();
+
+                    if (requestHeaders != null &&
+                            requestHeaders.containsKey("User-Agent"))
+                    {
+                        String[] userAgents = requestHeaders.get("User-Agent");
+                        userAgent = userAgents.length > 0 ? userAgents[0] : null;
+                    }
+                }
+            }
+        }
+
+        return userAgent;
+    }
+
+    /**
+     * Users can overload this method to define in which scenarios a request should result
+     * in an 'intercepted' page with proper windowId detection. This can e.g. contain
+     * blacklisting some userAgents.
+     * By default the following User-Agents will be served directly:
+     * <ul>
+     *     <li>.*bot.*</li>
+     *     <li>.*Bot.*</li>
+     *     <li>.*Slurp.*</li>
+     *     <li>.*Crawler.*</li>
+     * </ul>
+     * @return <code>true</code> if the Request should get 'intercepted' and the intermediate
+     *        windowhandler.html page should get rendered first. By returning <code>false</code>
+     *        the requested page will get rendered intermediately.
+     * @see #getUserAgent(javax.faces.context.FacesContext) for determining the UserAgent
+     */
+    public boolean isClientSideWindowHandlerRequest(FacesContext facesContext)
+    {
+        if (!isJavaScriptEnabled())
+        {
+            return false;
+        }
+
+        String userAgent = getUserAgent(facesContext);
+
+        if (userAgent != null &&
+            ( userAgent.indexOf("bot")     >= 0 || // Googlebot, etc
+              userAgent.indexOf("Bot")     >= 0 || // BingBot, etc
+              userAgent.indexOf("Slurp")   >= 0 || // Yahoo Slurp
+              userAgent.indexOf("Crawler") >= 0    // various other Crawlers
+            ) )
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+}
diff --git a/impl/src/main/java/org/apache/myfaces/lifecycle/LifecycleImpl.java b/impl/src/main/java/org/apache/myfaces/lifecycle/LifecycleImpl.java
index c4289bd..80a63e9 100755
--- a/impl/src/main/java/org/apache/myfaces/lifecycle/LifecycleImpl.java
+++ b/impl/src/main/java/org/apache/myfaces/lifecycle/LifecycleImpl.java
@@ -31,9 +31,11 @@ import javax.faces.event.ExceptionQueuedEvent;
 import javax.faces.event.ExceptionQueuedEventContext;
 import javax.faces.event.PhaseId;
 import javax.faces.event.PhaseListener;
+import javax.faces.lifecycle.ClientWindow;
 import javax.faces.lifecycle.Lifecycle;
 
 import org.apache.myfaces.config.FacesConfigurator;
+import org.apache.myfaces.shared.util.WebConfigParamUtils;
 import org.apache.myfaces.shared_impl.webapp.webxml.WebXml;
 import org.apache.myfaces.util.DebugUtils;
 
@@ -88,6 +90,15 @@ public class LifecycleImpl extends Lifecycle
      * Replaced by _phaseListenerList CopyOnWriteArrayList
      */
     //private PhaseListener[] _phaseListenerArray = null;
+    
+    private String windowMode;
+    private TokenGenerator windowTokenGenerator;
+    private ClientConfig clientConfig;
+    private WindowContextConfig windowContextConfig;
+    
+    private static final String WINDOW_MODE_NONE = "none";
+    private static final String WINDOW_MODE_URL = "url";
+    private static final String WINDOW_MODE_CLIENT = "client";
 
     public LifecycleImpl()
     {
@@ -96,6 +107,49 @@ public class LifecycleImpl extends Lifecycle
                 new ProcessValidationsExecutor(), new UpdateModelValuesExecutor(), new InvokeApplicationExecutor() };
 
         renderExecutor = new RenderResponseExecutor();
+        windowTokenGenerator = new TokenGenerator();
+        clientConfig = new ClientConfig();
+        windowContextConfig = new WindowContextConfig();
+    }
+    
+    private String getWindowMode(FacesContext context)
+    {
+        if (windowMode == null)
+        {
+            windowMode = WebConfigParamUtils.getStringInitParameter(
+                    context.getExternalContext(), 
+                    ClientWindow.CLIENT_WINDOW_MODE_PARAM_NAME, WINDOW_MODE_NONE);
+        }
+        return windowMode;
+    }
+
+    @Override
+    public void attachWindow(FacesContext facesContext)
+    {
+        if (WINDOW_MODE_NONE.equals(getWindowMode(facesContext)))
+        {
+            //No need to do anything
+            return;
+        }
+        else
+        {
+            ClientWindow clientWindow = facesContext.getExternalContext().getClientWindow();
+            if (clientWindow == null)
+            {
+                if (WINDOW_MODE_URL.equals(getWindowMode(facesContext)))
+                {
+                    clientWindow = new UrlClientWindow(windowTokenGenerator);
+                }
+                else
+                {
+                    //clientWindow = new DefaultClientWindow(windowTokenGenerator);
+                    clientWindow = new CODIClientSideWindow(windowTokenGenerator,
+                            windowContextConfig, clientConfig);
+                }
+                clientWindow.decode(facesContext);
+                facesContext.getExternalContext().setClientWindow(clientWindow);
+            }
+        }
     }
 
     @Override
diff --git a/impl/src/main/java/org/apache/myfaces/lifecycle/TokenGenerator.java b/impl/src/main/java/org/apache/myfaces/lifecycle/TokenGenerator.java
new file mode 100644
index 0000000..8e30cd1
--- /dev/null
+++ b/impl/src/main/java/org/apache/myfaces/lifecycle/TokenGenerator.java
@@ -0,0 +1,75 @@
+/*
+ * 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.lifecycle;
+
+import java.math.BigInteger;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ *
+ * @author lu4242
+ */
+class TokenGenerator
+{
+    private final AtomicLong _count;
+    
+    public TokenGenerator()
+    {
+        _count = new AtomicLong(_getSeed());
+    }
+    
+    private static long _getSeed()
+    {
+        SecureRandom rng;
+        try
+        {
+            // try SHA1 first
+            rng = SecureRandom.getInstance("SHA1PRNG");
+        }
+        catch (NoSuchAlgorithmException e)
+        {
+            // SHA1 not present, so try the default (which could potentially not be
+            // cryptographically secure)
+            rng = new SecureRandom();
+        }
+
+        // use 48 bits for strength and fill them in
+        byte[] randomBytes = new byte[6];
+        rng.nextBytes(randomBytes);
+
+        // convert to a long
+        return new BigInteger(randomBytes).longValue();
+    }
+    
+    /**
+     * Get the next token to be assigned to this request
+     * 
+     * @return
+     */
+    String _getNextToken()
+    {
+        // atomically increment the value
+        long nextToken = _count.incrementAndGet();
+
+        // convert using base 36 because it is a fast efficient subset of base-64
+        return Long.toString(nextToken, 36);
+    }
+}
diff --git a/impl/src/main/java/org/apache/myfaces/lifecycle/UrlClientWindow.java b/impl/src/main/java/org/apache/myfaces/lifecycle/UrlClientWindow.java
new file mode 100644
index 0000000..1d4984e
--- /dev/null
+++ b/impl/src/main/java/org/apache/myfaces/lifecycle/UrlClientWindow.java
@@ -0,0 +1,87 @@
+/*
+ * 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.lifecycle;
+
+import javax.faces.context.FacesContext;
+import javax.faces.lifecycle.ClientWindow;
+import javax.faces.render.ResponseStateManager;
+
+/**
+ *
+ * @author lu4242
+ */
+public class UrlClientWindow extends ClientWindow
+{
+    private String windowId;
+
+    private TokenGenerator tokenGenerator;
+    
+    public UrlClientWindow(TokenGenerator tokenGenerator)
+    {
+        this.tokenGenerator = tokenGenerator;
+    }
+        
+    @Override
+    public void decode(FacesContext context)
+    {
+        String windowId = calculateWindowId(context);
+
+        if (windowId != null)
+        {
+            // Store the current windowId.
+            setId(windowId);
+        }
+        else
+        {
+            //Generate a new windowId
+            setId(tokenGenerator._getNextToken());
+        }
+    }
+    
+    protected String calculateWindowId(FacesContext context)
+    {
+        //1. If it comes as parameter, it takes precedence over any other choice, because
+        //   no browser is capable to do a POST and create a new window at the same time.
+        String windowId = context.getExternalContext().getRequestParameterMap().get(
+                ResponseStateManager.CLIENT_WINDOW_PARAM);
+        if (windowId != null)
+        {
+            return windowId;
+        }
+        windowId = context.getExternalContext().getRequestParameterMap().get(
+                ResponseStateManager.CLIENT_WINDOW_URL_PARAM);
+        if (windowId != null)
+        {
+            return windowId;
+        }
+        return null;
+    }
+
+    @Override
+    public String getId()
+    {
+        return windowId;
+    }
+    
+    public void setId(String id)
+    {
+        windowId = id;
+    }
+    
+}
diff --git a/impl/src/main/java/org/apache/myfaces/lifecycle/WindowContextConfig.java b/impl/src/main/java/org/apache/myfaces/lifecycle/WindowContextConfig.java
new file mode 100644
index 0000000..211c1a0
--- /dev/null
+++ b/impl/src/main/java/org/apache/myfaces/lifecycle/WindowContextConfig.java
@@ -0,0 +1,152 @@
+/*
+ * 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.lifecycle;
+
+/**
+ * Configuration for the {@link org.apache.myfaces.extensions.cdi.core.api.scope.conversation.WindowContext}
+ * - it's customizable via the @Alternative or @Specializes mechanism of CDI.
+ */
+public class WindowContextConfig
+{
+    private static final long serialVersionUID = 8159770064249255686L;
+
+    protected WindowContextConfig()
+    {
+    }
+
+    /**
+     * Specifies if it is allowed to use URL params for forwarding the current window-id.
+     * (deactivate it e.g. for higher security - in this case it's required to use a window id provided by a
+     * component lib or a server-side window-handler)
+     * 
+     * @return true if it is allowed to add the window-id as URL parameter
+     */
+    public boolean isUrlParameterSupported()
+    {
+        return true;
+    }
+
+    /**
+     * Allows to restrict window-ids.
+     * <p>With the default window handler (esp. for JSF 1.2), URLs have to contain the window-id.
+     * If users bookmark these links, they could open 2-n tabs (with the bookmark) which have the same window-id.
+     * It is only possible to prevent it if the ClientSideWindowHandler is used.
+     * </p>
+     *
+     * <p><b>ATTENTION:</b> Since CODI-1.0.6 this is set to <code>true</code> as defalt!</p>
+     *
+     * <p>
+     * This must be enabled to
+     * <ul>
+     *     <li>allow <i>target</i> attributes in a href</li>
+     *     <li>support multiple webapps in an EAR scenario. Since each webapp has it's own session,
+     *     they would otherwise trash their windowIds each time you link from one webapp to another one</li>
+     *     <li>play nicely with other frameworks which use the window.name for browser tab detection</li>
+     * </ul>
+     * </p>
+     * @return <code>true</code> to allow all windowIds already present in window.name.
+     *         <code>false</code> to only allow window-ids which are generated by CODI
+     */
+    public boolean isUnknownWindowIdsAllowed()
+    {
+        return true;
+    }
+
+    /**
+     * if set to <code>true</code> CODI will add a windowId=xxx parameter
+     * while encoding each action URL.
+     * @return true if the window-id should be added, false otherwise
+     */
+    public boolean isAddWindowIdToActionUrlsEnabled()
+    {
+        return false;
+    }
+
+    /**
+     * Specifies the time for the timeout for a window. After a timeout is detected all beans which are only linked
+     * to the window will be destroyed.
+     *
+     * @return the time for the timeout for a window
+     */
+    public int getWindowContextTimeoutInMinutes()
+    {
+        return 60;
+    }
+
+    /**
+     * Restricts the number of active windows.
+     *
+     * @return limit for active windows
+     */
+    public int getMaxWindowContextCount()
+    {
+        return 64;
+    }
+
+    /**
+     * Allows to activate the cleanup of empty window contexts to avoid cleanup e.g.
+     * of the eldest window context instances if the max. count is reached.
+     *
+     * @return true for activating it, false otherwise
+     */
+    public boolean isCloseEmptyWindowContextsEnabled()
+    {
+        return false;
+    }
+
+    /**
+     * Allows to restore the window-context before the component tree gets built.
+     * 
+     * @return true for activating it, false otherwise
+     */
+    public boolean isEagerWindowContextDetectionEnabled()
+    {
+        return true;
+    }
+
+    /*
+     * event config
+     */
+
+    /**
+     * Specifies if the
+     * {@link org.apache.myfaces.extensions.cdi.core.api.scope.conversation.event.CreateWindowContextEvent}
+     * will be fired.
+     *
+     * @return true if the event should be fired, false otherwise
+     */
+    public boolean isCreateWindowContextEventEnabled()
+    {
+        return false;
+    }
+
+    /**
+     * Specifies if the
+     * {@link org.apache.myfaces.extensions.cdi.core.api.scope.conversation.event.CloseWindowContextEvent}
+     * will be fired.
+     *
+     * @return true if the event should be fired, false otherwise
+     */
+    public boolean isCloseWindowContextEventEnabled()
+    {
+        return false;
+    }
+
+    //boolean isResetWindowContextEventEnable();
+}
diff --git a/impl/src/main/java/org/apache/myfaces/renderkit/ServerSideStateCacheImpl.java b/impl/src/main/java/org/apache/myfaces/renderkit/ServerSideStateCacheImpl.java
index 5d5593d..e07e7fa 100644
--- a/impl/src/main/java/org/apache/myfaces/renderkit/ServerSideStateCacheImpl.java
+++ b/impl/src/main/java/org/apache/myfaces/renderkit/ServerSideStateCacheImpl.java
@@ -43,10 +43,12 @@ import javax.faces.application.ProjectStage;
 
 import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
+import javax.faces.lifecycle.ClientWindow;
 import org.apache.commons.codec.DecoderException;
 import org.apache.commons.codec.binary.Hex;
 
 import org.apache.commons.collections.map.AbstractReferenceMap;
+import org.apache.commons.collections.map.LRUMap;
 import org.apache.commons.collections.map.ReferenceMap;
 import org.apache.myfaces.application.StateCache;
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
@@ -305,7 +307,16 @@ class ServerSideStateCacheImpl extends StateCache<Object, Object>
             
             if (key == null )
             {
-                if (isUseFlashScopePurgeViewsInSession(context.getExternalContext()) && 
+                // Check if clientWindow is enabled and if the last view key is stored
+                // into session, so we can use it to chain the precedence in GET-GET
+                // cases.
+                ClientWindow clientWindow = context.getExternalContext().getClientWindow();
+                if (clientWindow != null)
+                {
+                    key = (SerializedViewKey) viewCollection.
+                            getLastWindowKey(context, clientWindow.getId());
+                }
+                else if (isUseFlashScopePurgeViewsInSession(context.getExternalContext()) && 
                     Boolean.TRUE.equals(context.getExternalContext().getRequestMap()
                             .get("oam.Flash.REDIRECT.PREVIOUSREQUEST")))
                 {
@@ -319,6 +330,13 @@ class ServerSideStateCacheImpl extends StateCache<Object, Object>
                 context, context.getViewRoot().getViewId(), getNextViewSequence(context));
         viewCollection.add(context, serializeView(context, serializedView), nextKey, key);
 
+        ClientWindow clientWindow = context.getExternalContext().getClientWindow();
+        if (clientWindow != null)
+        {
+            //Update the last key generated for the current windowId in session map
+            viewCollection.putLastWindowKey(context, clientWindow.getId(), nextKey);
+        }
+        
         // replace the value to notify the container about the change
         sessionMap.put(SERIALIZED_VIEW_SESSION_ATTR, viewCollection);
     }
@@ -599,6 +617,8 @@ class ServerSideStateCacheImpl extends StateCache<Object, Object>
         
         private final Map<SerializedViewKey, SerializedViewKey> _precedence = 
             new HashMap<SerializedViewKey, SerializedViewKey>();
+        
+        private Map<String, SerializedViewKey> _lastWindowKeys = null;
 
         // old views will be hold as soft references which will be removed by
         // the garbage collector if free memory is low
@@ -744,6 +764,29 @@ class ServerSideStateCacheImpl extends StateCache<Object, Object>
             }
             return views;
         }
+        
+        public synchronized void putLastWindowKey(FacesContext context, String id, SerializedViewKey key)
+        {
+            if (_lastWindowKeys == null)
+            {
+                Integer i = getNumberOfSequentialViewsInSession(context);
+                int j = getNumberOfViewsInSession(context);
+                if (i != null && i.intValue() > 0)
+                {
+                    _lastWindowKeys = new LRUMap((j / i.intValue()) + 1);
+                }
+            }
+            _lastWindowKeys.put(id, key);
+        }
+        
+        public SerializedViewKey getLastWindowKey(FacesContext context, String id)
+        {
+            if (_lastWindowKeys != null)
+            {
+                return _lastWindowKeys.get(id);
+            }
+            return null;
+        }
 
         /**
          * @return old serialized views map
diff --git a/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlResponseStateManager.java b/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlResponseStateManager.java
index ad941da..845aa95 100755
--- a/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlResponseStateManager.java
+++ b/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlResponseStateManager.java
@@ -19,12 +19,15 @@
 package org.apache.myfaces.renderkit.html;
 
 import java.io.IOException;
+import java.util.concurrent.atomic.AtomicLong;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import javax.faces.component.UINamingContainer;
 
 import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
+import javax.faces.lifecycle.ClientWindow;
 import javax.faces.render.RenderKitFactory;
 import javax.faces.render.ResponseStateManager;
 
@@ -73,6 +76,8 @@ public class HtmlResponseStateManager extends MyfacesResponseStateManager
     
     private StateCacheFactory _stateCacheFactory;
     
+    private AtomicLong _counter = new AtomicLong();
+    
     public HtmlResponseStateManager()
     {
         _stateCacheFactory = new StateCacheFactoryImpl();
@@ -139,6 +144,32 @@ public class HtmlResponseStateManager extends MyfacesResponseStateManager
 
         // renderKitId field
         writeRenderKitIdField(facesContext, responseWriter);
+        
+        // windowId field
+        writeWindowIdField(facesContext, responseWriter);
+    }
+    
+    private void writeWindowIdField(FacesContext facesContext, ResponseWriter responseWriter) throws IOException
+    {
+        ClientWindow clientWindow = facesContext.getExternalContext().getClientWindow();
+        if (clientWindow != null)
+        {
+            responseWriter.startElement(HTML.INPUT_ELEM, null);
+            responseWriter.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
+            StringBuilder sb = new StringBuilder();
+            char sepChar = UINamingContainer.getSeparatorChar(facesContext);
+            sb.append(facesContext.getViewRoot().getContainerClientId(facesContext));
+            sb.append(sepChar);
+            sb.append(ResponseStateManager.CLIENT_WINDOW_PARAM);
+            sb.append(sepChar);
+            // A counter is enough, because only uniqueness of UIViewRoot 
+            // per page is needed
+            sb.append(_counter.incrementAndGet());
+            responseWriter.writeAttribute(HTML.ID_ATTR, sb.toString(), null);
+            responseWriter.writeAttribute(HTML.NAME_ATTR, ResponseStateManager.CLIENT_WINDOW_PARAM, null);
+            responseWriter.writeAttribute(HTML.VALUE_ATTR, clientWindow.getId(), null);
+            responseWriter.endElement(HTML.INPUT_ELEM);
+        }
     }
     
     @Override
diff --git a/impl/src/main/java/org/apache/myfaces/view/facelets/util/Classpath.java b/impl/src/main/java/org/apache/myfaces/view/facelets/util/Classpath.java
index 895b047..b2f5ee4 100644
--- a/impl/src/main/java/org/apache/myfaces/view/facelets/util/Classpath.java
+++ b/impl/src/main/java/org/apache/myfaces/view/facelets/util/Classpath.java
@@ -38,6 +38,8 @@ import java.util.zip.ZipInputStream;
 import org.apache.myfaces.shared.util.ClassUtils;
 import java.nio.ByteBuffer;
 import java.nio.charset.Charset;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 /**
  * @author Jacob Hookom
  * @author Roland Huss
@@ -120,7 +122,23 @@ public final class Classpath
 
     private static boolean _searchDir(Set<URL> result, File dir, String suffix) throws IOException
     {
-        if (dir.exists() && dir.isDirectory())
+        boolean dirExists = false;
+        if (System.getSecurityManager() != null)
+        {
+            final File finalDir = dir;
+            dirExists = (Boolean) AccessController.doPrivileged(new PrivilegedAction()
+            {
+                public Object run() 
+                {
+                    return finalDir.exists();
+                }
+            });
+        }  
+        else
+        {
+            dirExists = dir.exists();
+        }
+        if (dirExists && dir.isDirectory())
         {
             for (File file : dir.listFiles())
             {
diff --git a/impl/src/main/resources/META-INF/resources/org.apache.myfaces.windowId/windowhandler.html b/impl/src/main/resources/META-INF/resources/org.apache.myfaces.windowId/windowhandler.html
new file mode 100644
index 0000000..6469f29
--- /dev/null
+++ b/impl/src/main/resources/META-INF/resources/org.apache.myfaces.windowId/windowhandler.html
@@ -0,0 +1,215 @@
+<!DOCTYPE html
+  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--
+ 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.
+-->
+<html>
+
+<head>
+    <title>Loading...</title>
+</head>
+<body>
+<div id="message" style="position:absolute;left:40%;top:40%">
+    Your browser does not support JavaScript.
+    Click <a href="$$noscriptUrl$$">here</a> to continue without JavaScript.
+</div>
+</body>
+
+
+<script type="text/javascript" >
+function isHtml5() {
+    try {
+        return !!localStorage.getItem;
+    } catch(e) {
+        return false;
+    }
+}
+function unstringify(serialized) {
+    if (JSON) {
+        return JSON.parse(serialized);
+    }
+    return serialized.split("|||");
+}
+function getOldBody() {
+    if (window.name.length != null) {
+        return localStorage.getItem(window.name + '_body');
+    }
+}
+function getOldBodyAttrs() {
+    if (window.name.length != null) {
+        return localStorage.getItem(window.name + '_bodyAttrs');
+    }
+}
+function getOldCss() {
+    if (window.name.length != null) {
+        return unstringify(localStorage.getItem(window.name + '_css'));
+    }
+}
+
+function addCss(url) {
+    var newSS = document.createElement("style");
+
+    newSS.setAttribute("rel", "stylesheet");
+    newSS.setAttribute("type", "text/css");
+    newSS.appendChild(document.createTextNode("@import url(" +url + ");"));
+    document.getElementsByTagName("head")[0].appendChild(newSS);
+}
+
+function loadCss(clean)
+{
+    if (!isHtml5()) {
+        // only do this stuff on html browsers
+        return;
+    }
+
+    var oldCss  = getOldCss();
+
+    if (window.name && oldCss)
+    {
+        for (i=0; oldCss && i< oldCss.length; i++) {
+            addCss(oldCss[i]);
+        }
+
+        if (clean) {
+            localStorage.removeItem(window.name + '_css');
+        }
+    }
+
+}
+
+function replaceContent() {
+    if (!isHtml5()) {
+        // only do this stuff on html browsers
+        document.getElementById('message').textContent = "Loading...";
+        return;
+    }
+    loadCss(false);
+
+    var oldBody = getOldBody();
+
+    if (window.name && oldBody) {
+        document.body.innerHTML = oldBody;
+
+        //X TODO should restore all attribs of the body tag
+        document.body.setAttribute("class", getOldBodyAttrs());
+        document.body.setAttribute("style", " cursor: wait !important;");
+
+        localStorage.removeItem(window.name + '_body');
+        localStorage.removeItem(window.name + '_bodyAttrs');
+
+        // overlay the doc with an un-clickable full-size div
+        var newDiv = document.createElement("div");
+        newDiv.setAttribute("style", "position:absolute; z-index:1000; background-color:transparent; top:0; left:0; width:100%; height: 100%");
+        newDiv.setAttribute("class", "fulldiv");
+        document.body.appendChild(newDiv);
+    }
+    else {
+        document.getElementById('message').textContent = "Loading...";
+    }
+}
+
+function setUrlParam(baseUrl, paramName, paramValue) {
+    var query = baseUrl;
+    var vars = query.split(/&|\?/g);
+    var newQuery = "";
+    var iParam = 0;
+    var paramFound = false;
+    for (var i=0; vars != null && i < vars.length; i++) {
+        var pair = vars[i].split("=");
+        if (pair.length == 1) {
+            newQuery = pair[0];
+        }
+        else {
+            if (pair[0] != paramName) {
+                var amp = iParam++ > 0 ? "&" : "?";
+                newQuery =  newQuery + amp + pair[0] + "=" + pair[1];
+            }
+            else {
+                paramFound = true;
+                var amp = iParam++ > 0 ? "&" : "?";
+                newQuery =  newQuery + amp + paramName + "=" + paramValue;
+            }
+        }
+    }
+
+    if (!paramFound) {
+        var amp = iParam++ > 0 ? "&" : "?";
+        newQuery =  newQuery + amp + paramName + "=" + paramValue;
+    }
+    return newQuery;
+}
+
+function scrollToOldPosition() {
+    if (isHtml5()) {
+        var x = localStorage.getItem(window.name + '_x');
+        var y = localStorage.getItem(window.name + '_y');
+        window.scrollTo(x, y);
+
+        var x = localStorage.removeItem(window.name + '_x');
+        var y = localStorage.removeItem(window.name + '_y');
+    }
+}
+
+replaceContent();
+
+
+window.onload = function() {
+
+    loadCss(true);
+    //X scrollToOldPosition();
+
+    // this will be replaced in the phase listener
+    var windowId = '$$windowIdValue$$';
+
+    if (windowId == 'uninitializedWindowId')
+    {
+        windowId = window.name
+    }
+
+    if (!windowId || windowId.length < 3)
+    {
+        // request a new windowId
+        windowId = 'automatedEntryPoint';
+    }
+
+    window.name = windowId;
+
+    /* used to debug the intermediate page
+    if (!confirm('reload?')) {
+        return true;
+    }
+    */
+
+    // 3 seconds expiry time
+    var expdt = new Date();
+    expdt.setTime(expdt.getTime()+(3*1000));
+    var expires = "; expires="+expdt.toGMTString();
+
+    var requestToken = Math.floor(Math.random()*1001);
+    var newUrl = setUrlParam(window.location.href, "mfRid", requestToken);
+    newUrl = setUrlParam(newUrl, "jfwid", windowId);
+
+    document.cookie = 'jfwid-' + requestToken + '=' + windowId + expires+"; path=/";
+
+    window.location = newUrl;
+}
+</script>
+
+</html>
+
diff --git a/pom.xml b/pom.xml
index e265007..14cb177 100644
--- a/pom.xml
+++ b/pom.xml
@@ -56,6 +56,7 @@
         <module>shared</module>
         <module>impl</module>
         <module>bundle</module>
+        <module>client-window-example</module>
     </modules>
 
     <build>
diff --git a/shared/src/main/java/org/apache/myfaces/shared/context/flash/FlashImpl.java b/shared/src/main/java/org/apache/myfaces/shared/context/flash/FlashImpl.java
index 2993230..00701d1 100644
--- a/shared/src/main/java/org/apache/myfaces/shared/context/flash/FlashImpl.java
+++ b/shared/src/main/java/org/apache/myfaces/shared/context/flash/FlashImpl.java
@@ -40,6 +40,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.logging.Logger;
+import javax.faces.lifecycle.ClientWindow;
 
 /**
  * Implementation of Flash object
@@ -731,18 +732,27 @@ public class FlashImpl extends Flash
     private void _saveRenderFlashMapTokenForNextRequest(ExternalContext externalContext)
     {
         String tokenValue = (String) externalContext.getRequestMap().get(FLASH_RENDER_MAP_TOKEN);
-        
-        HttpServletResponse httpResponse = ExternalContextUtils.getHttpServletResponse(externalContext);
-        if (httpResponse != null)
+        ClientWindow clientWindow = externalContext.getClientWindow();
+        if (clientWindow != null)
         {
-            Cookie cookie = _createFlashCookie(FLASH_RENDER_MAP_TOKEN, tokenValue, externalContext);
-            httpResponse.addCookie(cookie);
+            //Use HttpSession or PortletSession object
+            Map<String, Object> sessionMap = externalContext.getSessionMap();
+            sessionMap.put(FLASH_RENDER_MAP_TOKEN+SEPARATOR_CHAR+clientWindow.getId(), tokenValue);
         }
         else
         {
-            //Use HttpSession or PortletSession object
-            Map<String, Object> sessionMap = externalContext.getSessionMap();
-            sessionMap.put(FLASH_RENDER_MAP_TOKEN, tokenValue);
+            HttpServletResponse httpResponse = ExternalContextUtils.getHttpServletResponse(externalContext);
+            if (httpResponse != null)
+            {
+                Cookie cookie = _createFlashCookie(FLASH_RENDER_MAP_TOKEN, tokenValue, externalContext);
+                httpResponse.addCookie(cookie);
+            }
+            else
+            {
+                //Use HttpSession or PortletSession object
+                Map<String, Object> sessionMap = externalContext.getSessionMap();
+                sessionMap.put(FLASH_RENDER_MAP_TOKEN, tokenValue);
+            }
         }
     }
     
@@ -757,21 +767,31 @@ public class FlashImpl extends Flash
     private String _getRenderFlashMapTokenFromPreviousRequest(ExternalContext externalContext)
     {
         String tokenValue = null;
-        HttpServletResponse httpResponse = ExternalContextUtils.getHttpServletResponse(externalContext);
-        if (httpResponse != null)
+        ClientWindow clientWindow = externalContext.getClientWindow();
+        if (clientWindow != null)
         {
-            //Use a cookie
-            Cookie cookie = (Cookie) externalContext.getRequestCookieMap().get(FLASH_RENDER_MAP_TOKEN);
-            if (cookie != null)
-            {
-                tokenValue = cookie.getValue();
-            }
+            Map<String, Object> sessionMap = externalContext.getSessionMap();
+            tokenValue = (String) sessionMap.get(FLASH_RENDER_MAP_TOKEN+
+                    SEPARATOR_CHAR+clientWindow.getId());
         }
         else
         {
-            //Use HttpSession or PortletSession object
-            Map<String, Object> sessionMap = externalContext.getSessionMap();
-            tokenValue = (String) sessionMap.get(FLASH_RENDER_MAP_TOKEN);
+            HttpServletResponse httpResponse = ExternalContextUtils.getHttpServletResponse(externalContext);
+            if (httpResponse != null)
+            {
+                //Use a cookie
+                Cookie cookie = (Cookie) externalContext.getRequestCookieMap().get(FLASH_RENDER_MAP_TOKEN);
+                if (cookie != null)
+                {
+                    tokenValue = cookie.getValue();
+                }
+            }
+            else
+            {
+                //Use HttpSession or PortletSession object
+                Map<String, Object> sessionMap = externalContext.getSessionMap();
+                tokenValue = (String) sessionMap.get(FLASH_RENDER_MAP_TOKEN);
+            }
         }
         return tokenValue;
     }

-- 
To stop receiving notification emails like this one, please contact
deki@apache.org.