[maven-release-plugin] copy for tag trinidad-1.2.15
diff --git a/pom.xml b/pom.xml
index b5277d8..cf2824d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,6 +17,29 @@
     specific language governing permissions and limitations
     under the License.
 -->
+
+<!--
+This pom file has been optimized for Maven3.  Usage of the various targets/tasks is below.
+
+Build:
+  mvn3 [install]
+  mvn3 clean install
+ 
+Prepare Release
+  mvn3 release:prepare -DprepareRelease=true
+  
+Perform Release
+  mvn3 release:perform -DperformRelease=true
+
+Change Version Number (http://maven.apache.org/plugins/maven-release-plugin/examples/update-versions.html)
+  mvn3 release:update-versions
+  mvn3 release:update-versions -DautoVersionSubmodules=true
+
+Create A Branch (http://maven.apache.org/plugins/maven-release-plugin/examples/branch.html)
+  mvn3 release:branch -DbranchName=my-branch
+  mvn3 release:branch -DbranchName=my-branch -DupdateBranchVersions=true -DupdateWorkingCopyVersions=false
+-->
+
 <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>
 
@@ -28,7 +51,7 @@
   <parent>
     <groupId>org.apache.myfaces</groupId>
     <artifactId>myfaces</artifactId>
-    <version>10</version>
+    <version>16</version>
   </parent>
 
   <groupId>org.apache.myfaces.trinidad</groupId>
@@ -51,6 +74,7 @@
     <jsf-facelets.version>1.1.14</jsf-facelets.version>
     <portlet-bridge.version>1.0.0-beta</portlet-bridge.version>
     <commons-lang.version>2.4</commons-lang.version>
+    <commons-codec.version>1.3</commons-codec.version>
     <pluto-embedded.version>1.0.1</pluto-embedded.version>
     
     <!-- Testing -->
@@ -67,6 +91,18 @@
     
     <!-- Other -->
     <jdev.release>11.1.1.0.0</jdev.release>
+    <!-- Site deployment -->
+    <siteModule.path>trinidad-1.2</siteModule.path>
+    <site.mainDirectory>${user.home}/myfaces-site/checkout</site.mainDirectory>
+    <siteContent.path>${user.home}/myfaces-site/site/${siteModule.path}</siteContent.path>
+    <!-- it's a default location for performance reason (not checkout the content all the time)
+         you can override this value in your settings. -->
+    <scmCheckout.path>\${site.mainDirectory}/${siteModule.path}</scmCheckout.path>
+    <siteDeploy.url>file://${user.home}/myfaces-site/site/${siteModule.path}</siteDeploy.url>
+    <siteScmPublish.url>scm:svn:https://svn.apache.org/repos/asf/myfaces/site/publish/</siteScmPublish.url>
+    
+	<checkstyle.skip>true</checkstyle.skip>
+	
   </properties>
 
   <issueManagement>
@@ -173,6 +209,7 @@
     </pluginRepository>
   </pluginRepositories>
 
+  <!--
   <distributionManagement>
     <site>
       <id>apache-site</id>
@@ -180,6 +217,14 @@
       <url>scp://minotaur.apache.org/www/myfaces.apache.org/trinidad</url>
     </site>
   </distributionManagement>
+  -->
+  <distributionManagement>
+    <site>
+      <id>myfaces-local-staging</id>
+      <name>Apache Website</name>
+      <url>scp://localhost/${user.home}/myfaces-site/${siteModule.path}</url>
+    </site>
+  </distributionManagement>  
 
   <dependencyManagement>
     <dependencies>
@@ -282,6 +327,12 @@
       </dependency>
 
       <dependency>
+        <groupId>commons-codec</groupId>
+        <artifactId>commons-codec</artifactId>
+        <version>${commons-codec.version}</version>
+      </dependency>
+
+	  <dependency>
         <groupId>org.apache.myfaces.trinidad</groupId>
         <artifactId>trinidad-build</artifactId>
         <version>${project.version}</version>
@@ -357,11 +408,21 @@
   </modules>
 
   <build>
+  
+    <!-- Since Maven 3.0, this is required to add scpexe as protocol for deploy. -->
+    <extensions>
+      <extension>
+        <groupId>org.apache.maven.wagon</groupId>
+        <artifactId>wagon-ssh-external</artifactId>
+        <version>1.0-beta-7</version>
+      </extension>
+    </extensions>
+        
     <pluginManagement>
       <plugins>
         <plugin>
           <artifactId>maven-site-plugin</artifactId>
-          <!--version>3.0-beta-3</version-->
+          <version>3.3</version>
           <inherited>true</inherited>
           <dependencies>
             <dependency>
@@ -371,12 +432,50 @@
             </dependency>
           </dependencies>
           <configuration>
+            <stagingRepositoryId>myfaces-local-staging</stagingRepositoryId>
+            <stagingSiteURL>${siteDeploy.url}</stagingSiteURL>
             <outputEncoding>UTF-8</outputEncoding>
+            <reportPlugins>
+              <!--plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>findbugs-maven-plugin</artifactId>
+                <version>2.0</version>
+                <configuration>
+                  <threshold>Low</threshold>
+                </configuration>
+              </plugin-->
+
+              <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>rat-maven-plugin</artifactId>
+              </plugin>
+
+              <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-project-info-reports-plugin</artifactId>
+                <version>2.0.1</version>
+              </plugin>
+
+              <!--plugin>
+                <artifactId>maven-pmd-plugin</artifactId>
+                <version>2.3</version>
+                <configuration>
+                  <rulesets>
+                    <ruleset>/rulesets/basic.xml</ruleset>
+                    <ruleset>/rulesets/unusedcode.xml</ruleset>
+                  </rulesets>
+                  <linkXref>true</linkXref>
+                  <minimumTokens>100</minimumTokens>
+                  <targetJdk>${jdk.version}</targetJdk>
+                </configuration>
+              </plugin -->
+            </reportPlugins>
           </configuration>
         </plugin>
 
         <plugin>
           <artifactId>maven-surefire-plugin</artifactId>
+          <version>2.17</version>
           <inherited>true</inherited>
           <configuration>
             <!-- set the forkMode to "always" to validate new tests,
@@ -459,6 +558,7 @@
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-pmd-plugin</artifactId>
           <inherited>true</inherited>
+          <version>2.6</version>
           <configuration>
             <targetJdk>${jdk.version}</targetJdk>
           </configuration>
@@ -523,11 +623,61 @@
             <jdkLevel>5.0</jdkLevel>
           </configuration>
         </plugin>
-        
+		<!-- Begin dependency fix for .md5 and .sha1 -->
+		<plugin>
+		  <groupId>org.apache.maven.plugins</groupId>
+		  <artifactId>maven-release-plugin</artifactId>
+		  <version>2.5.3</version>
+		</plugin>
+		<plugin>
+		  <groupId>org.apache.maven.plugins</groupId>
+		  <artifactId>maven-gpg-plugin</artifactId>
+		  <version>1.6</version>
+		</plugin>
+		<plugin>
+		  <groupId>org.apache.maven.plugins</groupId>
+		  <artifactId>maven-deploy-plugin</artifactId>
+		  <version>2.8.2</version>
+		</plugin>
+		<!-- End -->		
+		
       </plugins>
     </pluginManagement>
     
     <plugins>
+      <!--
+        Trinidad must now be built with a minimum of Maven 3.0 and Java 5.0 because
+        of some oddities with the checkstyle plugin 
+      -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-enforcer-plugin</artifactId>
+        <version>1.0.1</version>
+        <executions>
+          <execution>
+            <id>enforce-maven</id>
+            <goals>
+              <goal>enforce</goal>
+            </goals>
+            <configuration>
+              <rules>
+                <requireJavaVersion>
+                  <message>Apache MyFaces Trinidad 1.2 needs to be compiled with Java 5</message>
+                  <version>1.5</version>
+                </requireJavaVersion>
+                <requireMavenVersion>
+                  <!-- Require AT LEAST Maven 3.0 or higher -->
+                  <version>[${maven.min-version},)</version>
+                </requireMavenVersion>
+                <requireJavaVersion>
+                  <message>Apache MyFaces Trinidad 2 needs to be compiled with at least JDK ${jdk.min-version}</message>                
+                  <version>[${jdk.min-version},)</version>
+                </requireJavaVersion>
+              </rules>    
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
 
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
@@ -585,6 +735,20 @@
           </execution>
         </executions>
       </plugin>
+
+      
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-scm-publish-plugin</artifactId>
+        <version>1.0-beta-2</version>
+        <configuration>
+        <pubScmUrl>${siteScmPublish.url}</pubScmUrl>
+        <tryUpdate>true</tryUpdate>
+        <checkoutDirectory>${scmCheckout.path}</checkoutDirectory>
+        <content>\${siteContent.path}</content>
+        </configuration>
+      </plugin>
+
     </plugins>
   </build>
 
@@ -663,19 +827,94 @@
       NOTE that for the maven lifecycle invoked by the release plugin, -Papache-release will
       be added automatically because of the config in apache-parent-7.
     -->
+    <!--
     <profile>
       <id>apache-release</id>
 
       <modules>
         <module>trinidad-assembly</module>
       </modules>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.rat</groupId>
+            <artifactId>apache-rat-plugin</artifactId>
+            <executions>
+              <execution>
+                <phase>verify</phase>
+                <goals>
+                  <goal>check</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build> 
     </profile>
+    -->
+    
+        <profile>
+            <id>prepare-release</id>
+            <activation>
+                <property>
+                    <name>prepareRelease</name>
+                </property>
+            </activation>
+            <modules>
+                <module>trinidad-assembly</module>
+            </modules>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-release-plugin</artifactId>
+                        <configuration>
+                            <arguments>-DprepareRelease</arguments>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>perform-release</id>
+            <activation>
+                <property>
+                    <name>performRelease</name>
+                    <value>true</value>
+                </property>
+            </activation>
+            <modules>
+                <module>trinidad-assembly</module>
+            </modules>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-release-plugin</artifactId>
+                        <configuration>
+                            <arguments>-Papache-release -DperformRelease</arguments>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
 
     <profile>
-      <id>partial-lifecycle</id>
-      <modules>
-        <module>trinidad-partial-lifecycle</module>
-      </modules>
+      <id>enableRat</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.rat</groupId>
+            <artifactId>apache-rat-plugin</artifactId>
+            <executions>
+              <execution>
+                <phase>verify</phase>
+                <goals>
+                  <goal>check</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
     </profile>
 
     <!--
diff --git a/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/CollectionModel.java b/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/CollectionModel.java
index bfb83e1..9a51f90 100644
--- a/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/CollectionModel.java
+++ b/trinidad-api/src/main/java/org/apache/myfaces/trinidad/model/CollectionModel.java
@@ -143,11 +143,9 @@
   }
 
   /**
-   * Gets the rowData at the given row key.
-   * This method makes the given row current and calls
-   * {@link #getRowData()}.
-   * Finally, the row that was current before this method was called
-   * is made current again.
+   * Returns the rowData for the given rowKey without changing model currency.  
+   * Implementations may choose to implement this behavior by saving and restoring the currency.
+   *
    * @see CollectionModel#getRowData()
    * @param rowKey the row key of the row to get data from.
    * @return the data for the given row. 
diff --git a/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ExternalContextUtils.java b/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ExternalContextUtils.java
index 51673b3..6cfc1b7 100644
--- a/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ExternalContextUtils.java
+++ b/trinidad-api/src/main/java/org/apache/myfaces/trinidad/util/ExternalContextUtils.java
@@ -317,6 +317,49 @@
   }
 
   /**
+   * Returns the scheme of the current request, or "unknown" if
+   * the request scheme cannot be determined.
+   *
+   * @param ec the current external context
+   * @return A string containing the current request scheme, or "unknown".
+   */
+  public static String getRequestScheme(ExternalContext ec)
+  { 
+    if (isPortlet(ec))
+    {
+      return _getPortletRequestScheme(ec);
+    }
+
+    return _getServletRequestScheme(ec);
+  }
+
+  private static String _getPortletRequestScheme(ExternalContext ec)
+  {
+    try
+    {
+      return (String) _runMethod(ec.getContext(), "getScheme");
+    }
+    catch (Exception e)
+    {
+      _LOG.severe(e);
+    }
+
+    return _SCHEME_UNKNOWN;
+  }
+
+  private static String _getServletRequestScheme(ExternalContext ec)
+  {
+    Object request = ec.getRequest();
+
+    if (request instanceof ServletRequest)
+    {
+      return ((ServletRequest)request).getScheme();
+    }
+            
+    return _SCHEME_UNKNOWN;
+  }
+
+  /**
    * Returns the character encoding or <code>null</code> if there isn't any
    *
    * @param ec the current external context
@@ -586,6 +629,10 @@
   private static final TrinidadLogger _LOG = TrinidadLogger
                                                .createTrinidadLogger(ExternalContextUtils.class);
 
+  // getRequestScheme() return value in the event that we cannot
+  // determine the request scheme.
+  private static final String _SCHEME_UNKNOWN = "unknown";
+
   // =-= Scott O'Bryan =-=
   // Performance enhancement. These will be needed anyway, let's not get them every time.
   private static final Class<?> _PORTLET_ACTION_REQUEST_CLASS;
diff --git a/trinidad-assembly/pom.xml b/trinidad-assembly/pom.xml
index c6f2518..4989860 100644
--- a/trinidad-assembly/pom.xml
+++ b/trinidad-assembly/pom.xml
@@ -35,28 +35,6 @@
   <build>
     <plugins>
       <plugin>
-        <artifactId>maven-assembly-plugin</artifactId>
-        <version>2.2</version>
-        <executions>
-          <execution>
-            <id>make_assembly_trinidad</id>
-            <configuration>
-              <descriptors>
-                <descriptor>src/main/assembly/dep.xml</descriptor>
-              </descriptors>
-              <appendAssemblyId>true</appendAssemblyId>  <!-- adds "-bin" and "-src" -->
-              <tarLongFileMode>gnu</tarLongFileMode>
-            </configuration>
-            <phase>package</phase>
-            <goals>
-              <goal>single</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-
-      <!-- todo: what does this do and how is it activated? -->      
-      <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>dependency-maven-plugin</artifactId>
         <executions>
@@ -116,7 +94,6 @@
 
       <plugin>
         <artifactId>maven-assembly-plugin</artifactId>
-        <version>2.2</version>
         <executions>
           <execution>
             <id>make_assembly_trinidad</id>
@@ -124,8 +101,11 @@
               <descriptors>
                 <descriptor>src/main/assembly/dep.xml</descriptor>
               </descriptors>
-              <appendAssemblyId>true</appendAssemblyId>  <!-- adds "-bin" and "-src" -->
+              <finalName>trinidad-assembly-${project.version}-dist</finalName>
+              <appendAssemblyId>false</appendAssemblyId>  <!-- adds "-bin" and "-src" -->
               <tarLongFileMode>gnu</tarLongFileMode>
+              <outputDirectory>target/assembly/out</outputDirectory>
+              <workDirectory>target/assembly/work</workDirectory>              
             </configuration>
             <phase>package</phase>
             <goals>
@@ -134,6 +114,35 @@
           </execution>
         </executions>
       </plugin>
+      
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <version>1.5</version>
+        <executions>
+          <execution>
+            <id>attach-artifacts</id>
+            <phase>package</phase>
+            <goals>
+              <goal>attach-artifact</goal>
+            </goals>
+            <configuration>
+              <artifacts>
+                <artifact>
+                  <file>target/assembly/out/trinidad-assembly-${project.version}-dist.zip</file>
+                  <type>zip</type>
+                  <classifier>dist</classifier>
+                </artifact>
+                <artifact>
+                  <file>target/assembly/out/trinidad-assembly-${project.version}-dist.tar.gz</file>
+                  <type>tar.gz</type>
+                  <classifier>dist</classifier>
+                </artifact>
+              </artifacts>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
 
diff --git a/trinidad-examples/pom.xml b/trinidad-examples/pom.xml
index d7322a1..a194437 100644
--- a/trinidad-examples/pom.xml
+++ b/trinidad-examples/pom.xml
@@ -89,14 +89,67 @@
       
        mvn release:prepare -Papache-releae
      -->
+     <!--
     <profile>
      <id>apache-release</id>
-
      <modules>
        <module>trinidad-example-assembly</module>
      </modules>      
     </profile>
+    -->
+        <profile>
+            <id>prepare-release</id>
+            <activation>
+                <property>
+                    <name>prepareRelease</name>
+                </property>
+            </activation>
+            <modules>
+                <module>trinidad-example-assembly</module>
+            </modules>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-release-plugin</artifactId>
+                        <configuration>
+                            <arguments>-DprepareRelease</arguments>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>perform-release</id>
+            <activation>
+                <property>
+                    <name>performRelease</name>
+                    <value>true</value>
+                </property>
+            </activation>
+            <modules>
+                <module>trinidad-example-assembly</module>
+            </modules>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-release-plugin</artifactId>
+                        <configuration>
+                            <arguments>-Papache-release -DperformRelease</arguments>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+
     
+    <!--
+      This profile activates MyFaces as the release to use for these demos.  By default
+      MyFaces is used when these examples are run in Jetty and/or used with the -PincludeJSF
+      flag.  To invoke this profile, simply do not include a -Djsf= property on your maven
+      command line.  Execute this profile like this:
+      
+      mvn -PjettyConfig jetty:run
+    -->    
     <profile>
       <id>jettyConfig</id>
       <dependencyManagement>
diff --git a/trinidad-examples/trinidad-example-assembly/pom.xml b/trinidad-examples/trinidad-example-assembly/pom.xml
index 143bf7f..38e163d 100644
--- a/trinidad-examples/trinidad-example-assembly/pom.xml
+++ b/trinidad-examples/trinidad-example-assembly/pom.xml
@@ -28,6 +28,7 @@
     <groupId>org.apache.myfaces.trinidad</groupId>
     <artifactId>trinidad</artifactId>
     <version>1.2.15</version>
+    <relativePath>../../pom.xml</relativePath>
   </parent>
 
   <artifactId>trinidad-example-assembly</artifactId>
@@ -111,6 +112,35 @@
           </execution>
         </executions>
       </plugin>
+      
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>build-helper-maven-plugin</artifactId>
+        <version>1.5</version>
+        <executions>
+          <execution>
+            <id>attach-artifacts</id>
+            <phase>package</phase>
+            <goals>
+              <goal>attach-artifact</goal>
+            </goals>
+            <configuration>
+              <artifacts>
+                <artifact>
+                  <file>target/trinidad-example-assembly-${project.version}-example.zip</file>
+                  <type>zip</type>
+                  <classifier>example</classifier>
+                </artifact>
+                <artifact>
+                  <file>target/trinidad-example-assembly-${project.version}-example.tar.gz</file>
+                  <type>tar.gz</type>
+                  <classifier>example</classifier>
+                </artifact>
+              </artifacts>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
 
   </build>
diff --git a/trinidad-impl/pom.xml b/trinidad-impl/pom.xml
index a082cf5..ca4c054 100644
--- a/trinidad-impl/pom.xml
+++ b/trinidad-impl/pom.xml
@@ -75,6 +75,12 @@
       <groupId>org.apache.myfaces.trinidad</groupId>
       <artifactId>trinidad-api</artifactId>
     </dependency>
+    
+     <dependency> 	 
+       <groupId>commons-codec</groupId> 	 
+       <artifactId>commons-codec</artifactId>
+       <scope>compile</scope> 	 
+     </dependency>
 
     <dependency>
       <groupId>com.sun.facelets</groupId>
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/CoreResponseStateManager.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/CoreResponseStateManager.java
index cc8ce8d..92777b5 100644
--- a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/CoreResponseStateManager.java
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/CoreResponseStateManager.java
@@ -19,6 +19,7 @@
 package org.apache.myfaces.trinidadinternal.renderkit.core;
 
 import javax.faces.application.StateManager;
+import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 import javax.faces.render.ResponseStateManager;
@@ -47,6 +48,7 @@
 import org.apache.myfaces.trinidad.util.Base64OutputStream;
 import org.apache.myfaces.trinidad.util.ClassLoaderUtils;
 import org.apache.myfaces.trinidadinternal.util.ObjectInputStreamResolveClass;
+import org.apache.myfaces.trinidadinternal.util.StateUtils;
 
 /**
  * ResponseStateManager implementation for the Core RenderKit.
@@ -78,7 +80,7 @@
     // out twice
     //    rw.writeAttribute("id", VIEW_STATE_PARAM, null);
 
-    String s = encodeSerializedViewAsString(serializedView);
+    String s = encodeSerializedViewAsString(context, serializedView);
     rw.writeAttribute("value", s, null);
 
     rw.endElement("input");
@@ -95,13 +97,16 @@
   }
 
 
-  protected String encodeSerializedViewAsString(
+  protected String encodeSerializedViewAsString(FacesContext context,
     StateManager.SerializedView serializedView) throws IOException
   {
     if ((serializedView.getState() == null) &&
         (serializedView.getStructure() instanceof String))
-      return _TOKEN_PREFIX + serializedView.getStructure();
+      return _TOKEN_PREFIX + StateUtils.construct(serializedView.getStructure(), context.getExternalContext());
 
+    return StateUtils.construct(
+            new Object[]{serializedView.getStructure(),serializedView.getState()}, context.getExternalContext());    
+    /*
     StringWriter sw = new StringWriter();
     BufferedWriter bw = new BufferedWriter(sw);
     Base64OutputStream b64_out = new Base64OutputStream(bw);
@@ -120,7 +125,7 @@
     String retVal = sw.toString();
 
     assert(!retVal.startsWith(_TOKEN_PREFIX));
-    return retVal;
+    return retVal;*/
   }
 
   @Override
@@ -154,9 +159,10 @@
   private Object[] _restoreSerializedView(
      FacesContext context)
   {
-    Map<String, Object> requestMap = 
-      context.getExternalContext().getRequestMap();
+    ExternalContext external = context.getExternalContext();
     
+    Map<String, Object> requestMap = external.getRequestMap();
+
     Object[] view = (Object[]) requestMap.get(_CACHED_SERIALIZED_VIEW);
     if (view == null)
     {
@@ -172,37 +178,43 @@
       if (stateString.startsWith(_TOKEN_PREFIX))
       {
         String tokenString = stateString.substring(_TOKEN_PREFIX.length());
-        view = new Object[]{tokenString, null};
+        view = new Object[]{StateUtils.reconstruct(tokenString, context.getExternalContext()), null};
       }
       // Nope, let's look for a regular state field
       else
       {
-        StringReader sr = new StringReader(stateString);
-        BufferedReader br = new BufferedReader(sr);
-        Base64InputStream b64_in = new Base64InputStream(br);
+        if (stateString != null)
+        {
+          view = (Object[]) StateUtils.reconstruct(stateString, context.getExternalContext());
+          /*
+          StringReader sr = new StringReader(stateString);
+          BufferedReader br = new BufferedReader(sr);
+          Base64InputStream b64_in = new Base64InputStream(br);
 
 
-        try
-        {
-          ObjectInputStream ois;
-          ois = new ObjectInputStreamResolveClass( new GZIPInputStream( b64_in, _BUFFER_SIZE ));
+          try
+          {
+            ObjectInputStream ois;
+            ois = new ObjectInputStreamResolveClass( new GZIPInputStream( b64_in, _BUFFER_SIZE ));
 
-          Object structure = ois.readObject();
-          Object state = ois.readObject();
-          ois.close();
-          view = new Object[]{structure, state};
-        }
-        catch (OptionalDataException ode)
-        {
-          _LOG.severe(ode);
-        }
-        catch (ClassNotFoundException cnfe)
-        {
-          _LOG.severe(cnfe);
-        }
-        catch (IOException ioe)
-        {
-          _LOG.severe(ioe);
+            Object structure = ois.readObject();
+            Object state = ois.readObject();
+            ois.close();
+            view = new Object[]{structure, state};
+          }
+          catch (OptionalDataException ode)
+          {
+            _LOG.severe(ode);
+          }
+          catch (ClassNotFoundException cnfe)
+          {
+            _LOG.severe(cnfe);
+          }
+          catch (IOException ioe)
+          {
+            _LOG.severe(ioe);
+          }
+          */
         }
       }
 
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/StyleContextImpl.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/StyleContextImpl.java
index c74f34e..bd2246f 100644
--- a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/StyleContextImpl.java
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/StyleContextImpl.java
@@ -24,6 +24,7 @@
 import java.util.Map;
 import java.util.concurrent.ConcurrentMap;
 
+import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
 
 import org.apache.myfaces.trinidad.context.AccessibilityProfile;
@@ -33,6 +34,7 @@
 import org.apache.myfaces.trinidad.skin.Icon;
 import org.apache.myfaces.trinidad.skin.Skin;
 import org.apache.myfaces.trinidad.style.Styles;
+import org.apache.myfaces.trinidad.util.ExternalContextUtils;
 import org.apache.myfaces.trinidadinternal.agent.TrinidadAgent;
 import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.HtmlRenderer;
 import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.StyleSheetRenderer;
@@ -175,6 +177,24 @@
   {
     return CoreRenderKit.OUTPUT_MODE_PORTLET.equals(_arc.getOutputMode());
   }
+  
+  @Override
+  public boolean isRequestSecure()
+  {
+    if (_isRequestSecure == null) 
+    {
+      String scheme = _getRequestScheme();
+      _isRequestSecure =  "https".equals(scheme);
+    }
+    return _isRequestSecure;
+  }
+
+  static private String _getRequestScheme()
+  {
+    FacesContext context = FacesContext.getCurrentInstance();
+    ExternalContext external = context.getExternalContext();
+    return ExternalContextUtils.getRequestScheme(external);
+  }
 
   /**
    *
@@ -286,6 +306,8 @@
   private StyleProvider _styleProvider;
   private Styles _styles;
   private Boolean  _isDisableStyleCompression;
+  private Boolean _isRequestSecure;
+
   static private final String _SKIN_ID_PARAM =
     "org.apache.myfaces.trinidad.skin.id";
 
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/SelectRangeChoiceBarRenderer.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/SelectRangeChoiceBarRenderer.java
index bdc2471..c88cce1 100644
--- a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/SelectRangeChoiceBarRenderer.java
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/SelectRangeChoiceBarRenderer.java
@@ -375,6 +375,11 @@
         // make sure the next range exists in the data model.
         hasNextRecords = isRowAvailable(component, (int)nextValue-1);
       }
+      
+      if (!hasNextRecords)
+      {
+        nextRecords = 0;
+      }
 
       boolean showBackButton = hasBackRecords || showDisabledNavigation;
       boolean showNextButton = hasNextRecords || showDisabledNavigation;
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleContext.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleContext.java
index 8f5107a..b8a5750 100644
--- a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleContext.java
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/StyleContext.java
@@ -54,4 +54,9 @@
   public boolean isPortletMode();
   public boolean isDisableStyleCompression();
   public boolean isDirty();
+  
+  /**
+   * @return true if the current request is secure (an https request), false otherwise
+   */
+  public boolean isRequestSecure();
 }
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/cache/FileSystemStyleCache.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/cache/FileSystemStyleCache.java
index 84c5571..08df19a 100644
--- a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/cache/FileSystemStyleCache.java
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/cache/FileSystemStyleCache.java
@@ -268,6 +268,12 @@
 
       buffer.append(_PORTLET);
     }
+    
+    if (context.isRequestSecure())
+    {
+      buffer.append(_NAME_SEPARATOR);
+      buffer.append(_SECURE);
+    }
 
     buffer.append(_CSS_EXTENSION);
 
@@ -1084,7 +1090,8 @@
        agent.getAgentOS(),
        !context.isDisableStyleCompression(),
        accProfile,
-       context.isPortletMode());
+       context.isPortletMode(),
+       context.isRequestSecure());
     }
 
     @Override
@@ -1097,7 +1104,8 @@
                        (_browser.ordinal() << 2)   ^
                        (_platform << 8)            ^
                        (_short ? 1 : 0)            ^
-                       (_portlet ? 1:0);
+                       ((_portlet ? 1:0) << 1)     ^
+                       ((_secureRequest ? 1: 0) << 3);
 
         if (_locale != null)     _hashCode ^= _locale.hashCode();
         if (_accProfile != null) _hashCode ^= _accProfile.hashCode();
@@ -1124,7 +1132,8 @@
              (_portlet == key._portlet)         &&
              (_direction == key._direction)     &&
              (_browser == key._browser)         &&
-             (_platform == key._platform))
+             (_platform == key._platform)       &&
+             (_secureRequest == key._secureRequest))
         {
           // now check the optional objects
           if ((_version == null) || _version.equals(key._version))
@@ -1144,7 +1153,8 @@
       int platform,
       boolean useShort,
       AccessibilityProfile accessibilityProfile,
-      boolean portlet
+      boolean portlet,
+      boolean secure
       )
     {
       // Make sure direction is non-null
@@ -1162,6 +1172,7 @@
       _short = useShort;
       _accProfile = accessibilityProfile;
       _portlet     = portlet;
+      _secureRequest = secure;
     }
 
     //is immutable, we should cache this, will make things faster in the long run
@@ -1176,6 +1187,7 @@
     private boolean        _short;  // Do we use short style classes?
     private AccessibilityProfile _accProfile;
     private boolean        _portlet; //kind of a hack but tells whether this was created in portal mode
+    private boolean        _secureRequest;
   }
 
   /**
@@ -1214,6 +1226,7 @@
       System.arraycopy(styleSheets, 0, _styleSheets, 0, styleSheets.length);
       _short = true;
       _portlet = context.isPortletMode();
+      _secureRequest = context.isRequestSecure();
     }
 
     @Override
@@ -1228,6 +1241,7 @@
 
         if ((_short != key._short) ||
             (_portlet != key._portlet) ||
+            (_secureRequest != key._secureRequest) ||
             (_styleSheets.length != key._styleSheets.length))
           return false;
 
@@ -1254,7 +1268,8 @@
       {
         _hashCode = Arrays.hashCode(_styleSheets) ^
                     (_short ? 1 : 0)              ^
-                    (_portlet ? 1 : 0);
+                    (_portlet ? 1 : 0)            ^
+                    ((_secureRequest ? 1: 0) << 3);
         _noHash = false;
       }
 
@@ -1268,6 +1283,7 @@
     private StyleSheetNode[] _styleSheets;
     private boolean _portlet;
     private boolean _short;   // Do we use short style classes?
+    private boolean _secureRequest;
   }
 
 
@@ -1585,6 +1601,7 @@
   private static final char _NAME_SEPARATOR = '-';
   private static final String _COMPRESSED = "cmp";
   private static final String _PORTLET = "prtl";
+  private static final String _SECURE = "s";
 
   /** Extension for CSS files */
   private static final String _CSS_EXTENSION = ".css";
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/ClassLoaderUtils.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/ClassLoaderUtils.java
new file mode 100644
index 0000000..3d8c3bb
--- /dev/null
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/ClassLoaderUtils.java
@@ -0,0 +1,394 @@
+/*
+ * 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.trinidadinternal.util;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.IOException;
+
+import java.io.InputStreamReader;
+
+import java.net.URL;
+
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.faces.FacesException;
+
+/**
+ * Utility methods for accessing classes and resources using an appropriate
+ * class loader.
+ *
+ * @version $Revision$ $Date$
+ */
+public final class ClassLoaderUtils
+{
+  // Utility class only, no instances
+  private ClassLoaderUtils()
+  {
+  }
+  
+  /**
+   * Loads the class with the specified name.  For Java 2 callers, the
+   * current thread's context class loader is preferred, falling back on the
+   * system class loader of the caller when the current thread's context is not
+   * set, or the caller is pre Java 2.
+   *
+   * @param     name  the name of the class
+   * @return    the resulting <code>Class</code> object
+   * @exception ClassNotFoundException if the class was not found
+   */
+  public static Class<?> loadClass(
+    String name) throws ClassNotFoundException
+  {
+    return loadClass(name, null);
+  }
+
+  /**
+   * Locates the resource with the specified name.  For Java 2 callers, the
+   * current thread's context class loader is preferred, falling back on the
+   * system class loader of the caller when the current thread's context is not
+   * set, or the caller is pre Java 2.
+   *
+   * @param     name  the name of the resource
+   * @return    the resulting <code>URL</code> object
+   */
+  public static URL getResource(
+    String name)
+  {
+    return getResource(name, null);
+  }
+
+  /**
+   * Locates the stream resource with the specified name.  For Java 2 callers,
+   * the current thread's context class loader is preferred, falling back on
+   * the system class loader of the caller when the current thread's context is
+   * not set, or the caller is pre Java 2.
+   *
+   * @param     name  the name of the resource
+   * @return    the resulting <code>InputStream</code> object
+   */
+  public static InputStream getResourceAsStream(
+    String name)
+  {
+    return getResourceAsStream(name, null);
+  }
+
+  /**
+   * Loads the class with the specified name.  For Java 2 callers, the
+   * current thread's context class loader is preferred, falling back on the
+   * class loader of the caller when the current thread's context is not set,
+   * or the caller is pre Java 2.  If the callerClassLoader is null, then
+   * fall back on the system class loader.
+   *
+   * @param     name  the name of the class
+   * @param     callerClassLoader  the calling class loader context
+   * @return    the resulting <code>Class</code> object
+   * @exception ClassNotFoundException if the class was not found
+   */
+  public static Class<?> loadClass(
+    String      name,
+    ClassLoader callerClassLoader) throws ClassNotFoundException
+  {
+    Class<?> clazz = null;
+
+    try
+    {
+      ClassLoader loader = getContextClassLoader();
+
+      if (loader != null)
+      {
+          clazz = loader.loadClass(name);
+      }
+    }
+    catch (ClassNotFoundException e)
+    {
+      // treat as though loader not set
+    }
+
+    if (clazz == null)
+    {
+      if (callerClassLoader != null)
+      {
+          clazz = callerClassLoader.loadClass(name);
+      }
+      else
+      {
+          clazz = Class.forName(name);
+      }
+    }
+
+    return clazz;
+  }
+
+  /**
+   * Locates the resource with the specified name.  For Java 2 callers, the
+   * current thread's context class loader is preferred, falling back on the
+   * class loader of the caller when the current thread's context is not set,
+   * or the caller is pre Java 2.  If the callerClassLoader is null, then
+   * fall back on the system class loader.
+   *
+   * @param     name  the name of the resource
+   * @param     callerClassLoader  the calling class loader context
+   * @return    the resulting <code>URL</code> object
+   */
+  public static URL getResource(
+    String      name,
+    ClassLoader callerClassLoader)
+  {
+    _checkResourceName(name);
+
+    URL url = null;
+
+    ClassLoader loader = getContextClassLoader();
+
+    if (loader != null)
+    {
+        url = loader.getResource(name);
+    }
+
+    if (url == null)
+    {
+      if (callerClassLoader != null)
+      {
+          url = callerClassLoader.getResource(name);
+      }
+      else
+      {
+          url = ClassLoader.getSystemResource(name);
+      }
+    }
+
+    return url;
+  }
+
+  /**
+   * Locates the resource stream with the specified name.  For Java 2 callers,
+   * the current thread's context class loader is preferred, falling back on
+   * the class loader of the caller when the current thread's context is not
+   * set, or the caller is pre Java 2.  If the callerClassLoader is null, then
+   * fall back on the system class loader.
+   *
+   * @param     name  the name of the resource
+   * @param     callerClassLoader  the calling class loader context
+   * @return    the resulting <code>InputStream</code> object
+   */
+  public static InputStream getResourceAsStream(
+    String      name,
+    ClassLoader callerClassLoader)
+  {
+    _checkResourceName(name);
+
+    InputStream stream = null;
+
+    ClassLoader loader = getContextClassLoader();
+
+    if (loader != null)
+    {
+        stream = loader.getResourceAsStream(name);
+    }
+
+    if (stream == null)
+    {
+      if (callerClassLoader != null)
+      {
+          stream = callerClassLoader.getResourceAsStream(name);
+      }
+      else
+      {
+          stream = ClassLoader.getSystemResourceAsStream(name);
+      }
+    }
+
+    return stream;
+  }
+
+  /**
+   * Dynamically accesses the current context class loader. 
+   * Includes a check for priviledges against java2 security 
+   * to ensure no security related exceptions are encountered. 
+   * Returns null if there is no per-thread context class loader.
+   */
+  public static ClassLoader getContextClassLoader()
+  {
+      if (System.getSecurityManager() != null) 
+      {
+          try 
+          {
+              ClassLoader cl = AccessController.doPrivileged(new PrivilegedExceptionAction<ClassLoader>()
+                      {
+                          public ClassLoader run() throws PrivilegedActionException
+                          {
+                              return Thread.currentThread().getContextClassLoader();
+                          }
+                      });
+              return cl;
+          }
+          catch (PrivilegedActionException pae)
+          {
+              throw new FacesException(pae);
+          }
+      }
+      else
+      {
+          return Thread.currentThread().getContextClassLoader();
+      }
+  }
+
+  /**
+   * Instantiate a service from a file in /META-INF/services.
+   * <P>
+   * The following is an excerpt from the JAR File specification:
+   * A service provider identifies itself by placing a provider-configuration file 
+   * in the resource directory META-INF/services. 
+   * The file's name should consist of the fully-qualified name of the abstract service class. 
+   * The file should contain a newline-separated list of unique concrete provider-class names. 
+   * Space and tab characters, as well as blank lines, are ignored. The comment character is '#' (0x23); 
+   * on each line all characters following the first comment character are ignored. 
+   * The file must be encoded in UTF-8. 
+   * 
+   * @param service the classname of the abstract service class.
+   * eg: javax.servlet.Filter
+   */
+  @SuppressWarnings("unchecked")
+  public static <T> List<T> getServices(String service)
+  {
+    String serviceUri ="META-INF/services/" + service;
+    ClassLoader loader = Thread.currentThread().getContextClassLoader();
+    try
+    {
+      Enumeration<URL> urls = loader.getResources(serviceUri);
+      if (urls.hasMoreElements())
+      {
+        List<T> services = new ArrayList<T>(1);
+        Set<String> keys = new HashSet<String>(20);
+        do
+        {
+          URL url = urls.nextElement();
+          
+          if (_LOG.isLoggable(Level.FINEST))
+          {
+            _LOG.finest("Processing: " + url);
+          }
+          try
+          {
+            BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
+            try
+            {
+              while(true)
+              {
+                String line = in.readLine();
+                if (line == null)
+                {
+                    break;
+                }
+                
+                String className = _parseLine(line);
+                
+                if(className!=null && keys.add(className))
+                {
+                  T instance = (T) _getClass(loader, className);
+                  services.add(instance);
+                }                
+              }
+            }
+            finally
+            {
+              in.close();
+            }
+          }
+          catch (Exception e)
+          {
+            if (_LOG.isLoggable(Level.WARNING))
+            {
+              _LOG.log(Level.WARNING, "Error parsing URL: " + url, e);
+            }
+          }
+        } 
+        while(urls.hasMoreElements());
+        
+        if (services.size() == 1)
+        {
+            return Collections.singletonList(services.get(0));
+        }
+        
+        return Collections.unmodifiableList(services);
+      }
+    }
+    catch (IOException e)
+    {
+      if (_LOG.isLoggable(Level.SEVERE))
+      {
+        _LOG.log(Level.SEVERE, "Error loading Resource: " + serviceUri, e);
+      }
+    }
+
+    return Collections.emptyList();
+  }
+  
+  private static String _parseLine(String line)
+  {
+    // Eliminate any comments
+    int hashIndex = line.indexOf('#');
+    if (hashIndex >= 0)
+    {
+        line = line.substring(0, hashIndex);
+    }
+
+    // and any whitespace
+    line = line.trim();
+    if (line.length() > 0)
+    {
+      return line;
+    }
+    
+    return null;
+  }
+  
+  private static Object _getClass(ClassLoader loader, String className)
+    throws ClassNotFoundException, InstantiationException,
+           IllegalAccessException
+  {
+    Class<?> clazz = loader.loadClass(className);
+    return clazz.newInstance();
+  }
+
+  private static void _checkResourceName(String name)
+  {
+    if ((name != null) && name.startsWith("/"))
+    {
+      if (_LOG.isLoggable(Level.WARNING))
+      {
+        _LOG.log(Level.WARNING, "Resource name not portable: " +name);
+      }
+    }
+  }
+
+  private static final Logger _LOG = Logger.getLogger(ClassLoaderUtils.class.getName());
+}
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/ClassUtils.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/ClassUtils.java
new file mode 100755
index 0000000..25a7b77
--- /dev/null
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/ClassUtils.java
@@ -0,0 +1,661 @@
+/*
+ * 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.trinidadinternal.util;
+
+import javax.el.ExpressionFactory;
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+public final class ClassUtils
+{
+    //~ Static fields/initializers -----------------------------------------------------------------
+
+    //private static final Log log                  = LogFactory.getLog(ClassUtils.class);
+    private static final Logger log                  = Logger.getLogger(ClassUtils.class.getName());
+
+    public static final Class BOOLEAN_ARRAY_CLASS = boolean[].class;
+    public static final Class BYTE_ARRAY_CLASS    = byte[].class;
+    public static final Class CHAR_ARRAY_CLASS    = char[].class;
+    public static final Class SHORT_ARRAY_CLASS   = short[].class;
+    public static final Class INT_ARRAY_CLASS     = int[].class;
+    public static final Class LONG_ARRAY_CLASS    = long[].class;
+    public static final Class FLOAT_ARRAY_CLASS   = float[].class;
+    public static final Class DOUBLE_ARRAY_CLASS  = double[].class;
+    public static final Class OBJECT_ARRAY_CLASS  = Object[].class;
+    public static final Class BOOLEAN_OBJECT_ARRAY_CLASS = Boolean[].class;
+    public static final Class BYTE_OBJECT_ARRAY_CLASS = Byte[].class;
+    public static final Class CHARACTER_OBJECT_ARRAY_CLASS = Character[].class;
+    public static final Class SHORT_OBJECT_ARRAY_CLASS = Short[].class;
+    public static final Class INTEGER_OBJECT_ARRAY_CLASS = Integer[].class;
+    public static final Class LONG_OBJECT_ARRAY_CLASS = Long[].class;
+    public static final Class FLOAT_OBJECT_ARRAY_CLASS = Float[].class;
+    public static final Class DOUBLE_OBJECT_ARRAY_CLASS = Double[].class;
+    public static final Class STRING_OBJECT_ARRAY_CLASS = String[].class;
+
+    //public static ClassLoaderExtension [] classLoadingExtensions = new ClassLoaderExtension[0];
+
+
+
+    public static final Map COMMON_TYPES = new HashMap(64);
+    static
+    {
+        COMMON_TYPES.put("byte", Byte.TYPE);
+        COMMON_TYPES.put("char", Character.TYPE);
+        COMMON_TYPES.put("double", Double.TYPE);
+        COMMON_TYPES.put("float", Float.TYPE);
+        COMMON_TYPES.put("int", Integer.TYPE);
+        COMMON_TYPES.put("long", Long.TYPE);
+        COMMON_TYPES.put("short", Short.TYPE);
+        COMMON_TYPES.put("boolean", Boolean.TYPE);
+        COMMON_TYPES.put("void", Void.TYPE);
+        COMMON_TYPES.put("java.lang.Object", Object.class);
+        COMMON_TYPES.put("java.lang.Boolean", Boolean.class);
+        COMMON_TYPES.put("java.lang.Byte", Byte.class);
+        COMMON_TYPES.put("java.lang.Character", Character.class);
+        COMMON_TYPES.put("java.lang.Short", Short.class);
+        COMMON_TYPES.put("java.lang.Integer", Integer.class);
+        COMMON_TYPES.put("java.lang.Long", Long.class);
+        COMMON_TYPES.put("java.lang.Float", Float.class);
+        COMMON_TYPES.put("java.lang.Double", Double.class);
+        COMMON_TYPES.put("java.lang.String", String.class);
+
+        COMMON_TYPES.put("byte[]", BYTE_ARRAY_CLASS);
+        COMMON_TYPES.put("char[]", CHAR_ARRAY_CLASS);
+        COMMON_TYPES.put("double[]", DOUBLE_ARRAY_CLASS);
+        COMMON_TYPES.put("float[]", FLOAT_ARRAY_CLASS);
+        COMMON_TYPES.put("int[]", INT_ARRAY_CLASS);
+        COMMON_TYPES.put("long[]", LONG_ARRAY_CLASS);
+        COMMON_TYPES.put("short[]", SHORT_ARRAY_CLASS);
+        COMMON_TYPES.put("boolean[]", BOOLEAN_ARRAY_CLASS);
+        COMMON_TYPES.put("java.lang.Object[]", OBJECT_ARRAY_CLASS);
+        COMMON_TYPES.put("java.lang.Boolean[]", BOOLEAN_OBJECT_ARRAY_CLASS);
+        COMMON_TYPES.put("java.lang.Byte[]", BYTE_OBJECT_ARRAY_CLASS);
+        COMMON_TYPES.put("java.lang.Character[]", CHARACTER_OBJECT_ARRAY_CLASS);
+        COMMON_TYPES.put("java.lang.Short[]", SHORT_OBJECT_ARRAY_CLASS);
+        COMMON_TYPES.put("java.lang.Integer[]", INTEGER_OBJECT_ARRAY_CLASS);
+        COMMON_TYPES.put("java.lang.Long[]", LONG_OBJECT_ARRAY_CLASS);
+        COMMON_TYPES.put("java.lang.Float[]", FLOAT_OBJECT_ARRAY_CLASS);
+        COMMON_TYPES.put("java.lang.Double[]", DOUBLE_OBJECT_ARRAY_CLASS);
+        COMMON_TYPES.put("java.lang.String[]", STRING_OBJECT_ARRAY_CLASS);
+        // array of void is not a valid type
+    }
+
+    /** utility class, do not instantiate */
+    private ClassUtils()
+    {
+        // utility class, disable instantiation
+    }
+
+    //~ Methods ------------------------------------------------------------------------------------
+
+    /*
+    public synchronized static void addClassLoadingExtension(ClassLoaderExtension extension, boolean top)
+    {
+      /**
+       * now at the first look this looks somewhat strange
+       * but to get the best performance access we assign new native
+       * arrays to our static variable
+       * 
+       * we have to synchronized nevertheless because if two threads try to register
+       * loaders at the same time none of them should get lost
+       */
+       /*
+        ClassLoaderExtension [] retVal = new ClassLoaderExtension[classLoadingExtensions.length+1];
+        ArrayList extensions = new ArrayList(classLoadingExtensions.length+1);
+
+        if(!top)
+        {
+            extensions.addAll(Arrays.asList(classLoadingExtensions));
+        }
+        extensions.add(extension);
+        if(top)
+        {
+            extensions.addAll(Arrays.asList(classLoadingExtensions));
+        }    
+
+        classLoadingExtensions = (ClassLoaderExtension []) extensions.toArray(retVal);
+    }*/
+
+    /**
+     * Tries a Class.loadClass with the context class loader of the current thread first and
+     * automatically falls back to the ClassUtils class loader (i.e. the loader of the
+     * myfaces.jar lib) if necessary.
+     *
+     * @param type fully qualified name of a non-primitive non-array class
+     * @return the corresponding Class
+     * @throws NullPointerException if type is null
+     * @throws ClassNotFoundException
+     */
+    public static Class classForName(String type)
+        throws ClassNotFoundException
+    {
+        //we now assign the array to safekeep the reference on
+        // the local variable stack, that way
+        //we can avoid synchronisation calls
+        /*
+        ClassLoaderExtension [] loaderPlugins = classLoadingExtensions;
+
+        int plugins = loaderPlugins.length;
+        for(int cnt = 0; cnt < loaderPlugins.length; cnt ++)
+        {
+            ClassLoaderExtension extension = loaderPlugins[cnt];
+            Class retVal = extension.forName(type);
+            if(retVal != null)
+            {
+                return retVal;
+            }
+        }
+        */
+
+        if (type == null)
+        {
+            throw new NullPointerException("type");
+        }
+        try
+        {
+            // Try WebApp ClassLoader first
+            return Class.forName(type,
+                                 false, // do not initialize for faster startup
+                                 getContextClassLoader());
+        }
+        catch (ClassNotFoundException ignore)
+        {
+            // fallback: Try ClassLoader for ClassUtils (i.e. the myfaces.jar lib)
+            return Class.forName(type,
+                                 false, // do not initialize for faster startup
+                                 ClassUtils.class.getClassLoader());
+        }
+    }
+
+
+    /**
+     * Same as {@link #classForName(String)}, but throws a RuntimeException
+     * (FacesException) instead of a ClassNotFoundException.
+     *
+     * @return the corresponding Class
+     * @throws NullPointerException if type is null
+     * @throws FacesException if class not found
+     */
+    public static Class simpleClassForName(String type)
+    {
+        try
+        {
+            return classForName(type);
+        }
+        catch (ClassNotFoundException e)
+        {
+            log.log(Level.SEVERE, "Class " + type + " not found", e);
+            throw new FacesException(e);
+        }
+    }
+
+
+    /**
+     * Similar as {@link #classForName(String)}, but also supports primitive types
+     * and arrays as specified for the JavaType element in the JavaServer Faces Config DTD.
+     *
+     * @param type fully qualified class name or name of a primitive type, both optionally
+     *             followed by "[]" to indicate an array type
+     * @return the corresponding Class
+     * @throws NullPointerException if type is null
+     * @throws ClassNotFoundException
+     */
+    public static Class javaTypeToClass(String type)
+        throws ClassNotFoundException
+    {
+        if (type == null)
+        {
+            throw new NullPointerException("type");
+        }
+
+        // try common types and arrays of common types first
+        Class clazz = (Class) COMMON_TYPES.get(type);
+        if (clazz != null)
+        {
+            return clazz;
+        }
+
+        int len = type.length();
+        if (len > 2 && type.charAt(len - 1) == ']' && type.charAt(len - 2) == '[')
+        {
+            String componentType = type.substring(0, len - 2);
+            Class componentTypeClass = classForName(componentType);
+            return Array.newInstance(componentTypeClass, 0).getClass();
+        }
+
+        return classForName(type);
+        
+    }
+
+    /**
+     * This method is similar to shared ClassUtils.javaTypeToClass,
+     * but the default package for the type is java.lang
+     *
+     * @param type
+     * @return
+     * @throws ClassNotFoundException
+     */
+    public static Class javaDefaultTypeToClass(String type)
+            throws ClassNotFoundException
+    {
+        if (type == null)
+        {
+            throw new NullPointerException("type");
+        }
+
+        // try common types and arrays of common types first
+        Class clazz = (Class) ClassUtils.COMMON_TYPES.get(type);
+        if (clazz != null)
+        {
+            return clazz;
+        }
+
+        int len = type.length();
+        if (len > 2 && type.charAt(len - 1) == ']' && type.charAt(len - 2) == '[')
+        {
+            String componentType = type.substring(0, len - 2);
+            Class componentTypeClass = ClassUtils.classForName(componentType);
+            return Array.newInstance(componentTypeClass, 0).getClass();
+        }
+
+        if (type.indexOf('.') == -1)
+        {
+            type = "java.lang." + type;
+        }
+        return ClassUtils.classForName(type);
+    }
+
+    /**
+     * Same as {@link #javaTypeToClass(String)}, but throws a RuntimeException
+     * (FacesException) instead of a ClassNotFoundException.
+     *
+     * @return the corresponding Class
+     * @throws NullPointerException if type is null
+     * @throws FacesException if class not found
+     */
+    public static Class simpleJavaTypeToClass(String type)
+    {
+        try
+        {
+            return javaTypeToClass(type);
+        }
+        catch (ClassNotFoundException e)
+        {
+            log.log(Level.SEVERE, "Class " + type + " not found", e);
+            throw new FacesException(e);
+        }
+    }
+
+    public static URL getResource(String resource)
+    {
+        URL url = getContextClassLoader().getResource(resource);
+        if (url == null)
+        {
+            url = ClassUtils.class.getClassLoader().getResource(resource);
+        }
+        return url;
+    }
+
+    public static InputStream getResourceAsStream(String resource)
+    {
+        InputStream stream = getContextClassLoader()
+                                .getResourceAsStream(resource);
+        if (stream == null)
+        {
+            // fallback
+            stream = ClassUtils.class.getClassLoader().getResourceAsStream(resource);
+        }
+        return stream;
+    }
+
+    /**
+     * @param resource       Name of resource(s) to find in classpath
+     * @param defaultObject  The default object to use to determine the class loader 
+     *                       (if none associated with current thread.)
+     * @return Iterator over URL Objects
+     */
+    public static Iterator getResources(String resource, Object defaultObject)
+    {
+        try
+        {
+            Enumeration resources = getCurrentLoader(defaultObject).getResources(resource);
+            List lst = new ArrayList();
+            while (resources.hasMoreElements())
+            {
+                lst.add(resources.nextElement());
+            }
+            return lst.iterator();
+        }
+        catch (IOException e)
+        {
+            log.log(Level.SEVERE, e.getMessage(), e);
+            throw new FacesException(e);
+        }
+    }
+
+
+    public static Object newInstance(String type)
+        throws FacesException
+    {
+        if (type == null)
+        {
+            return null;
+        }
+        return newInstance(simpleClassForName(type));
+    }
+
+    public static Object newInstance(String type, Class expectedType) throws FacesException
+    {
+        return newInstance(type, expectedType == null ? null : new Class[] {expectedType});
+    }
+
+    public static Object newInstance(String type, Class[] expectedTypes)
+    {
+        if (type == null)
+        {
+            return null;
+        }
+        
+        Class clazzForName = simpleClassForName(type);
+        
+        if(expectedTypes != null)
+        {
+            for (int i = 0, size = expectedTypes.length; i < size; i++)
+            {
+                if (!expectedTypes[i].isAssignableFrom(clazzForName))
+                {
+                    throw new FacesException("'" + type + "' does not implement expected type '" + expectedTypes[i]
+                            + "'");
+                }
+            }
+        }
+        
+        return newInstance(clazzForName);
+    }
+
+    public static <T> T newInstance(Class<T> clazz)
+        throws FacesException
+    {
+        try
+        {
+            return clazz.newInstance();
+        }
+        catch(NoClassDefFoundError e)
+        {
+            log.log(Level.SEVERE, "Class : "+clazz.getName()+" not found.",e);
+            throw new FacesException(e);
+        }
+        catch (InstantiationException e)
+        {
+            log.log(Level.SEVERE, e.getMessage(), e);
+            throw new FacesException(e);
+        }
+        catch (IllegalAccessException e)
+        {
+            log.log(Level.SEVERE, e.getMessage(), e);
+            throw new FacesException(e);
+        }
+    }
+
+    public static <T> T newInstance(Class<T> clazz,
+                                    Class<?>[] constructorArgClasses,
+                                    Object... constructorArgs) throws NoSuchMethodException
+    {
+        if (constructorArgs.length == 0)
+        {
+            // no args given - use normal newInstance()
+            return newInstance(clazz);
+        }
+
+        // try to get a fitting constructor (throws NoSuchMethodException)
+        Constructor constructor = clazz.getConstructor(constructorArgClasses);
+
+        try
+        {
+            // actually create instance
+            return (T) constructor.newInstance(constructorArgs);
+        }
+        catch (Exception e)
+        {
+            throw new FacesException(e);
+        }
+    }
+
+    public static Object convertToType(Object value, Class desiredClass)
+    {
+        if (value == null)
+        {
+            return null;
+        }
+
+        try
+        {
+            ExpressionFactory expFactory = FacesContext.getCurrentInstance().getApplication().getExpressionFactory();
+            return expFactory.coerceToType(value, desiredClass);
+        }
+        catch (Exception e)
+        {
+            String message = "Cannot coerce " + value.getClass().getName()
+                             + " to " + desiredClass.getName();
+            log.log(Level.SEVERE, message, e);
+            throw new FacesException(message, e);
+        }
+    }
+
+    /**
+     * Gets the ClassLoader associated with the current thread.  Returns the class loader associated with
+     * the specified default object if no context loader is associated with the current thread.
+     *
+     * @param defaultObject The default object to use to determine the class loader 
+     *        (if none associated with current thread.)
+     * @return ClassLoader
+     */
+    protected static ClassLoader getCurrentLoader(Object defaultObject)
+    {
+        ClassLoader loader = getContextClassLoader();
+        if(loader == null)
+        {
+            loader = defaultObject.getClass().getClassLoader();
+        }
+        return loader;
+    }
+    
+    /**
+     * Gets the ClassLoader associated with the current thread.  Includes a check for priviledges 
+     * against java2 security to ensure no security related exceptions are encountered. 
+     *
+     * @since 3.0.6
+     * @return ClassLoader
+     */
+    public static ClassLoader getContextClassLoader()
+    {
+        // call into the same method on ClassLoaderUtils.  no need for duplicate code maintenance. 
+        return ClassLoaderUtils.getContextClassLoader();
+    }
+    
+    /**
+     * Creates ApplicationObjects like NavigationHandler or StateManager and creates 
+     * the right wrapping chain of the ApplicationObjects known as the decorator pattern. 
+     * @param <T>
+     * @param interfaceClass The class from which the implementation has to inherit from.
+     * @param classNamesIterator All the class names of the actual ApplicationObject implementations
+     *                           from the faces-config.xml.
+     * @param defaultObject The default implementation for the given ApplicationObject.
+     * @return
+     */    
+    public static <T> T buildApplicationObject(Class<T> interfaceClass, 
+            Collection<String> classNamesIterator, T defaultObject)
+    {
+        return buildApplicationObject(interfaceClass, null, null, classNamesIterator, defaultObject);
+    }
+
+    /**
+     * Creates ApplicationObjects like NavigationHandler or StateManager and creates 
+     * the right wrapping chain of the ApplicationObjects known as the decorator pattern. 
+     * @param <T>
+     * @param interfaceClass The class from which the implementation has to inherit from.
+     * @param extendedInterfaceClass A subclass of interfaceClass which specifies a more
+     *                               detailed implementation.
+     * @param extendedInterfaceWrapperClass A wrapper class for the case that you have an ApplicationObject
+     *                                      which only implements the interfaceClass but not the 
+     *                                      extendedInterfaceClass.
+     * @param classNamesIterator All the class names of the actual ApplicationObject implementations
+     *                           from the faces-config.xml.
+     * @param defaultObject The default implementation for the given ApplicationObject.
+     * @return
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T buildApplicationObject(Class<T> interfaceClass, Class<? extends T> extendedInterfaceClass,
+            Class<? extends T> extendedInterfaceWrapperClass,
+            Collection<String> classNamesIterator, T defaultObject)
+    {
+        T current = defaultObject;
+        
+
+        for (String implClassName : classNamesIterator)
+        {
+            Class<? extends T> implClass = ClassUtils.simpleClassForName(implClassName);
+
+            // check, if class is of expected interface type
+            if (!interfaceClass.isAssignableFrom(implClass))
+            {
+                throw new IllegalArgumentException("Class " + implClassName + " is no " + interfaceClass.getName());
+            }
+
+            if (current == null)
+            {
+                // nothing to decorate
+                current = (T) ClassUtils.newInstance(implClass);
+            }
+            else
+            {
+                // let's check if class supports the decorator pattern
+                T newCurrent = null;
+                try
+                {
+                    Constructor<? extends T> delegationConstructor = null;
+                    
+                    // first, if there is a extendedInterfaceClass,
+                    // try to find a constructor that uses that
+                    if (extendedInterfaceClass != null 
+                            && extendedInterfaceClass.isAssignableFrom(current.getClass()))
+                    {
+                        try
+                        {
+                            delegationConstructor = 
+                                    implClass.getConstructor(new Class[] {extendedInterfaceClass});
+                        }
+                        catch (NoSuchMethodException mnfe)
+                        {
+                            // just eat it
+                        }
+                    }
+                    if (delegationConstructor == null)
+                    {
+                        // try to find the constructor with the "normal" interfaceClass
+                        delegationConstructor = 
+                                implClass.getConstructor(new Class[] {interfaceClass});
+                    }
+                    // impl class supports decorator pattern at this point
+                    try
+                    {
+                        // create new decorator wrapping current
+                        newCurrent = delegationConstructor.newInstance(new Object[] { current });
+                    }
+                    catch (InstantiationException e)
+                    {
+                        log.log(Level.SEVERE, e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                    catch (IllegalAccessException e)
+                    {
+                        log.log(Level.SEVERE, e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                    catch (InvocationTargetException e)
+                    {
+                        log.log(Level.SEVERE, e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                }
+                catch (NoSuchMethodException e)
+                {
+                    // no decorator pattern support
+                    newCurrent = (T) ClassUtils.newInstance(implClass);
+                }
+                
+                // now we have a new current object (newCurrent)
+                // --> find out if it is assignable from extendedInterfaceClass
+                // and if not, wrap it in a backwards compatible wrapper (if available)
+                if (extendedInterfaceWrapperClass != null
+                        && !extendedInterfaceClass.isAssignableFrom(newCurrent.getClass()))
+                {
+                    try
+                    {
+                        Constructor<? extends T> wrapperConstructor
+                                = extendedInterfaceWrapperClass.getConstructor(
+                                        new Class[] {interfaceClass, extendedInterfaceClass});
+                        newCurrent = wrapperConstructor.newInstance(new Object[] {newCurrent, current});
+                    }
+                    catch (NoSuchMethodException e)
+                    {
+                        log.log(Level.SEVERE, e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                    catch (InstantiationException e)
+                    {
+                        log.log(Level.SEVERE, e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                    catch (IllegalAccessException e)
+                    {
+                        log.log(Level.SEVERE, e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                    catch (InvocationTargetException e)
+                    {
+                        log.log(Level.SEVERE, e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                }
+                
+                current = newCurrent;
+            }
+        }
+
+        return current;
+    }
+}
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/MyFacesObjectInputStream.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/MyFacesObjectInputStream.java
new file mode 100644
index 0000000..4c30568
--- /dev/null
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/MyFacesObjectInputStream.java
@@ -0,0 +1,86 @@
+/*
+ * 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.trinidadinternal.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+import java.lang.reflect.Proxy;
+
+/**
+ * Tried to deploy v0.4.2 on JBoss 3.2.1 and had a classloading problem again.
+ * The problem seemed to be with JspInfo, line 98. We are using an
+ * ObjectInputStream Class, which then cannot find the classes to deserialize
+ * the input stream.  The solution appears to be to subclass ObjectInputStream
+ * (eg. CustomInputStream), and specify a different class-loading mechanism.
+ */
+public class MyFacesObjectInputStream
+    extends ObjectInputStream
+{
+    public MyFacesObjectInputStream(InputStream in) throws IOException
+    {
+        super(in);
+    }
+
+    protected Class resolveClass(ObjectStreamClass desc)
+        throws ClassNotFoundException, IOException
+    {
+        try
+        {
+            return ClassUtils.classForName(desc.getName());
+        }
+        catch (ClassNotFoundException e)
+        {
+            return super.resolveClass(desc);
+        }
+    }
+
+    protected Class resolveProxyClass(String[] interfaces) 
+            throws IOException, ClassNotFoundException
+    {
+        // Only option that would match the current code would be to
+        // expand ClassLoaderExtension to handle 'getProxyClass', which
+        // would break all existing ClassLoaderExtension implementations
+        Class[] cinterfaces = new Class[interfaces.length];
+        for (int i = 0; i < interfaces.length; i++)
+        {
+            cinterfaces[i] = ClassUtils.classForName(interfaces[i]);
+        }
+
+        try
+        {
+            // Try WebApp ClassLoader first
+            return Proxy.getProxyClass(ClassUtils.getContextClassLoader(), cinterfaces);
+        }
+        catch (Exception ex)
+        {
+            // fallback: Try ClassLoader for MyFacesObjectInputStream (i.e. the myfaces.jar lib)
+            try
+            {
+                return Proxy.getProxyClass(
+                        MyFacesObjectInputStream.class.getClassLoader(), cinterfaces);
+            }
+            catch (IllegalArgumentException e)
+            {
+                throw new ClassNotFoundException(e.toString(), e);
+            }
+        }
+    }
+}
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/StateUtils.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/StateUtils.java
new file mode 100644
index 0000000..41ab582
--- /dev/null
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/StateUtils.java
@@ -0,0 +1,1072 @@
+/*
+ * 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.trinidadinternal.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.AccessController;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Random;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import javax.faces.FacesException;
+import javax.faces.application.ViewExpiredException;
+import javax.faces.context.ExternalContext;
+import javax.servlet.ServletContext;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.myfaces.trinidadinternal.util.serial.DefaultSerialFactory;
+import org.apache.myfaces.trinidadinternal.util.serial.SerialFactory;
+
+/**
+ * <p>This Class exposes a handful of methods related to encryption,
+ * compression and serialization of the view state.</p>
+ * 
+ * <ul>
+ * <li>ISO-8859-1 is the character set used.</li>
+ * <li>GZIP is used for all compression/decompression.</li>
+ * <li>Base64 is used for all encoding and decoding.</li>
+ * <li>DES is the default encryption algorithm</li>
+ * <li>ECB is the default mode</li>
+ * <li>PKCS5Padding is the default padding</li>
+ * <li>HmacSHA1 is the default MAC algorithm</li>
+ * <li>The default algorithm can be overridden using the
+ * <i>org.apache.myfaces.ALGORITHM</i> parameter</li>
+ * <li>The default mode and padding can be overridden using the
+ * <i>org.apache.myfaces.ALGORITHM.PARAMETERS</i> parameter</li>
+ * <li>This class has not been tested with modes other than ECB and CBC</li>
+ * <li>An initialization vector can be specified via the
+ * <i>org.apache.myfaces.ALGORITHM.IV</i> parameter</li>
+ * <li>The default MAC algorithm can be overridden using the
+ * <i>org.apache.myfaces.MAC_ALGORITHM</i> parameter</li>
+ * </ul>
+ *
+ * <p>The secret is interpretted as base 64 encoded.  In other
+ * words, if your secret is "76543210", you would put "NzY1NDMyMTA=" in
+ * the deployment descriptor.  This is needed so that key values are not
+ * limited to just values composed of printable characters.</p>
+ *
+ * <p>If you are using CBC mode encryption, you <b>must</b> specify an
+ * initialization vector.</p>
+ *
+ * <p>If you are using the AES algorithm and getting a SecurityException
+ * complaining about keysize, you most likely need to get the unlimited
+ * strength jurisdiction policy files from a place like
+ * http://java.sun.com/j2se/1.4.2/download.html .</p>
+ *
+ * @see org.apache.myfaces.webapp.StartupServletContextListener
+ */
+public final class StateUtils
+{
+
+    //private static final Log log = LogFactory.getLog(StateUtils.class);
+    private static final Logger log = Logger.getLogger(StateUtils.class.getName());
+
+    public static final String ZIP_CHARSET = "ISO-8859-1";
+
+    public static final String DEFAULT_ALGORITHM = "DES";
+    public static final String DEFAULT_ALGORITHM_PARAMS = "ECB/PKCS5Padding";
+
+    public static final String INIT_PREFIX = "org.apache.myfaces.";
+    
+    /**
+     * Indicate if the view state is encrypted or not. By default, encryption is enabled.
+     */
+    //@JSFWebConfigParam(name="org.apache.myfaces.USE_ENCRYPTION",since="1.1",
+    //        defaultValue="true",expectedValues="true,false",group="state")
+    public static final String USE_ENCRYPTION = INIT_PREFIX + "USE_ENCRYPTION";
+    
+    /**
+     * Defines the secret (Base64 encoded) used to initialize the secret key
+     * for encryption algorithm. See MyFaces wiki/web site documentation 
+     * for instructions on how to configure an application for 
+     * different encryption strengths.
+     */
+    //@JSFWebConfigParam(name="org.apache.myfaces.SECRET",since="1.1",group="state")
+    public static final String INIT_SECRET = INIT_PREFIX + "SECRET";
+    
+    /**
+     * Indicate the encryption algorithm used for encrypt the view state.
+     */
+    //@JSFWebConfigParam(name="org.apache.myfaces.ALGORITHM",since="1.1",
+    //        defaultValue="DES",group="state",tags="performance")
+    public static final String INIT_ALGORITHM = INIT_PREFIX + "ALGORITHM";
+
+    /**
+     * If is set to "false", the secret key used for encryption algorithm is not cached. This is used
+     * when the returned SecretKey for encryption algorithm is not thread safe. 
+     */
+    //@JSFWebConfigParam(name="org.apache.myfaces.SECRET.CACHE",since="1.1",group="state")
+    public static final String INIT_SECRET_KEY_CACHE = INIT_SECRET + ".CACHE";
+    
+    /**
+     * Defines the initialization vector (Base64 encoded) used for the encryption algorithm
+     */
+    //@JSFWebConfigParam(name="org.apache.myfaces.ALGORITHM.IV",since="1.1",group="state")
+    public static final String INIT_ALGORITHM_IV = INIT_ALGORITHM + ".IV";
+    
+    /**
+     * Defines the default mode and padding used for the encryption algorithm
+     */
+    //@JSFWebConfigParam(name="org.apache.myfaces.ALGORITHM.PARAMETERS",since="1.1",
+    //        defaultValue="ECB/PKCS5Padding",group="state")
+    public static final String INIT_ALGORITHM_PARAM = INIT_ALGORITHM + ".PARAMETERS";
+    
+    /**
+     * Defines the factory class name using for serialize/deserialize the view state returned 
+     * by state manager into a byte array. The expected class must implement
+     * org.apache.myfaces.shared.util.serial.SerialFactory interface.
+     */
+    //@JSFWebConfigParam(name="org.apache.myfaces.trinidad.SERIAL_FACTORY", 
+    //                   since="1.1",group="state",tags="performance")
+    public static final String SERIAL_FACTORY = INIT_PREFIX + "trinidad.SERIAL_FACTORY";
+    
+    /**
+     * Indicate if the view state should be compressed before encrypted(optional) and encoded
+     */
+    //@JSFWebConfigParam(name="org.apache.myfaces.COMPRESS_STATE_IN_CLIENT",since="1.1",defaultValue="false",
+    //        expectedValues="true,false",group="state",tags="performance")
+    public static final String COMPRESS_STATE_IN_CLIENT = INIT_PREFIX + "COMPRESS_STATE_IN_CLIENT";
+
+    public static final String DEFAULT_MAC_ALGORITHM = "HmacSHA1";
+
+    /**
+     * Indicate the algorithm used to calculate the Message Authentication Code that is
+     * added to the view state.
+     */
+    //@JSFWebConfigParam(name="org.apache.myfaces.MAC_ALGORITHM",defaultValue="HmacSHA1",
+    //        group="state",tags="performance")
+    public static final String INIT_MAC_ALGORITHM = "org.apache.myfaces.MAC_ALGORITHM";
+    
+    /**
+     * Define the initialization code that are used to initialize the secret key used
+     * on the Message Authentication Code algorithm
+     */
+    //@JSFWebConfigParam(name="org.apache.myfaces.MAC_SECRET",group="state")
+    public static final String INIT_MAC_SECRET = "org.apache.myfaces.MAC_SECRET";
+
+    /**
+     * If is set to "false", the secret key used for MAC algorithm is not cached. This is used
+     * when the returned SecretKey for mac algorithm is not thread safe. 
+     */
+    //@JSFWebConfigParam(name="org.apache.myfaces.MAC_SECRET.CACHE",group="state")
+    public static final String INIT_MAC_SECRET_KEY_CACHE = "org.apache.myfaces.MAC_SECRET.CACHE";
+    
+    /** Utility class, do not instatiate */
+    private StateUtils()
+    {
+        //nope
+    }
+
+    private static void testConfiguration(ExternalContext ctx)
+    {
+
+        String algorithmParams = ctx.getInitParameter(INIT_ALGORITHM_PARAM);
+        
+        if (algorithmParams == null)
+        {
+            algorithmParams = ctx.getInitParameter(INIT_ALGORITHM_PARAM.toLowerCase());
+        }
+        String iv = ctx.getInitParameter(INIT_ALGORITHM_IV);
+        
+        if (iv == null)
+        {
+            iv = ctx.getInitParameter(INIT_ALGORITHM_IV.toLowerCase());
+        }
+        
+        if (algorithmParams != null && algorithmParams.startsWith("CBC") )
+        {
+            if(iv == null)
+            {
+                throw new FacesException(INIT_ALGORITHM_PARAM +
+                        " parameter has been set with CBC mode," +
+                        " but no initialization vector has been set " +
+                        " with " + INIT_ALGORITHM_IV);
+            }
+        }
+
+    }
+    
+    public static boolean enableCompression(ExternalContext ctx)
+    {
+        if(ctx == null)
+        {
+            throw new NullPointerException("ExternalContext ctx");
+        }
+    
+        return "true".equals(ctx.getInitParameter(COMPRESS_STATE_IN_CLIENT));
+    }
+    
+    public static boolean isSecure(ExternalContext ctx)
+    {
+        
+        if(ctx == null)
+        {
+            throw new NullPointerException("ExternalContext ctx");
+        }
+        
+        return ! "false".equals(ctx.getInitParameter(USE_ENCRYPTION));
+    }
+
+    /**
+     * This fires during the Render Response phase, saving state.
+     */
+
+    public static final String construct(Object object, ExternalContext ctx)
+    {
+        byte[] bytes = getAsByteArray(object, ctx);
+        if( enableCompression(ctx) )
+        {
+            bytes = compress(bytes);
+        }
+        if(isSecure(ctx))
+        {
+            bytes = encrypt(bytes, ctx);
+        }
+        bytes = encode(bytes);
+        try
+        {
+            return new String(bytes, ZIP_CHARSET);
+        }
+        catch (UnsupportedEncodingException e)
+        {
+            throw new FacesException(e);
+        }
+    }
+
+    /**
+     * Performs serialization with the serialization provider created by the 
+     * SerialFactory.  
+     * 
+     * @param object
+     * @param ctx
+     * @return
+     */
+    
+    public static final byte[] getAsByteArray(Object object, ExternalContext ctx)
+    {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        
+        // get the Factory that was instantiated @ startup
+        SerialFactory serialFactory = (SerialFactory) ctx.getApplicationMap().get(SERIAL_FACTORY);
+        
+        if(serialFactory == null)
+        {
+            // throw new NullPointerException("serialFactory");
+            serialFactory = new DefaultSerialFactory();
+            ctx.getApplicationMap().put(SERIAL_FACTORY, serialFactory);
+        }
+        
+        try
+        {
+            ObjectOutputStream writer = serialFactory.getObjectOutputStream(outputStream);
+            writer.writeObject(object);
+            byte[] bytes = outputStream.toByteArray();
+            writer.close();
+            outputStream.close();
+            writer = null;
+            outputStream = null;
+            return bytes;
+        }
+        catch (IOException e)
+        {
+            throw new FacesException(e);
+        }
+    }
+
+    public static byte[] encrypt(byte[] insecure, ExternalContext ctx)
+    {
+
+        if (ctx == null)
+        {
+            throw new NullPointerException("ExternalContext ctx");
+        }
+
+        testConfiguration(ctx);
+        
+        SecretKey secretKey = (SecretKey) getSecret(ctx);
+        String algorithm = findAlgorithm(ctx);
+        String algorithmParams = findAlgorithmParams(ctx);
+        byte[] iv = findInitializationVector(ctx);
+        
+        SecretKey macSecretKey = (SecretKey) getMacSecret(ctx);
+        String macAlgorithm = findMacAlgorithm(ctx);
+                
+        try
+        {
+            // keep local to avoid threading issue
+            Mac mac = Mac.getInstance(macAlgorithm);
+            mac.init(macSecretKey);
+            Cipher cipher = Cipher.getInstance(algorithm + "/" + algorithmParams);
+            if (iv != null)
+            {
+                IvParameterSpec ivSpec = new IvParameterSpec(iv);
+                cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
+            }
+            else
+            {
+                cipher.init(Cipher.ENCRYPT_MODE, secretKey);
+            }
+            if (log.isLoggable(Level.FINE))
+            {
+                log.fine("encrypting w/ " + algorithm + "/" + algorithmParams);
+            }
+            
+            //EtM Composition Approach
+            int macLenght = mac.getMacLength();
+            byte[] secure = new byte[cipher.getOutputSize(insecure.length)+ macLenght];
+            int secureCount = cipher.doFinal(insecure,0,insecure.length,secure);
+            mac.update(secure, 0, secureCount);
+            mac.doFinal(secure, secureCount);
+                        
+            return secure;
+        }
+        catch (Exception e)
+        {
+            throw new FacesException(e);
+        }
+    }
+
+    public static final byte[] compress(byte[] bytes)
+    {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try
+        {
+            GZIPOutputStream gzip = new GZIPOutputStream(baos);
+            gzip.write(bytes, 0, bytes.length);
+            gzip.finish();
+            byte[] fewerBytes = baos.toByteArray();
+            gzip.close();
+            baos.close();
+            gzip = null;
+            baos = null;
+            return fewerBytes;
+        }
+        catch (IOException e)
+        {
+            throw new FacesException(e);
+        }
+    }
+
+    public static final byte[] encode(byte[] bytes)
+    {
+          return new Base64().encode(bytes);
+    }
+
+    /**
+     * This fires during the Restore View phase, restoring state.
+     */
+    public static final Object reconstruct(String string, ExternalContext ctx)
+    {
+        byte[] bytes;
+        try
+        {
+            if(log.isLoggable(Level.FINE))
+            {
+                log.fine("Processing state : " + string);
+            }
+
+            bytes = string.getBytes(ZIP_CHARSET);
+            bytes = decode(bytes);
+            if(isSecure(ctx))
+            {
+                bytes = decrypt(bytes, ctx);
+            }
+            if( enableCompression(ctx) )
+            {
+                bytes = decompress(bytes);
+            }
+            return getAsObject(bytes, ctx);
+        }
+        catch (Throwable e)
+        {
+            if (log.isLoggable(Level.FINE))
+            {
+                log.log(Level.FINE, "View State cannot be reconstructed", e);
+            }
+            return null;
+        }
+    }
+
+    public static final byte[] decode(byte[] bytes)
+    {
+          return new Base64().decode(bytes);
+    }
+
+    public static final byte[] decompress(byte[] bytes)
+    {
+        if(bytes == null)
+        {
+            throw new NullPointerException("byte[] bytes");
+        }
+        
+        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        byte[] buffer = new byte[bytes.length];
+        int length;
+
+        try
+        {
+            GZIPInputStream gis = new GZIPInputStream(bais);
+            while ((length = gis.read(buffer)) != -1)
+            {
+                baos.write(buffer, 0, length);
+            }
+
+            byte[] moreBytes = baos.toByteArray();
+            baos.close();
+            bais.close();
+            gis.close();
+            baos = null;
+            bais = null;
+            gis = null;
+            return moreBytes;
+        }
+        catch (IOException e)
+        {
+            throw new FacesException(e);
+        }
+    }
+    
+    public static byte[] decrypt(byte[] secure, ExternalContext ctx)
+    {
+        if (ctx == null)
+        {
+            throw new NullPointerException("ExternalContext ctx");
+        }
+
+        testConfiguration(ctx);
+                
+        SecretKey secretKey = (SecretKey) getSecret(ctx);
+        String algorithm = findAlgorithm(ctx);
+        String algorithmParams = findAlgorithmParams(ctx);
+        byte[] iv = findInitializationVector(ctx);
+        
+        SecretKey macSecretKey = (SecretKey) getMacSecret(ctx);
+        String macAlgorithm = findMacAlgorithm(ctx);
+
+        try
+        {
+            // keep local to avoid threading issue
+            Mac mac = Mac.getInstance(macAlgorithm);
+            mac.init(macSecretKey);
+            Cipher cipher = Cipher.getInstance(algorithm + "/"
+                    + algorithmParams);
+            if (iv != null)
+            {
+                IvParameterSpec ivSpec = new IvParameterSpec(iv);
+                cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
+            }
+            else
+            {
+                cipher.init(Cipher.DECRYPT_MODE, secretKey);
+            }
+            if (log.isLoggable(Level.FINE))
+            {
+                log.fine("decrypting w/ " + algorithm + "/" + algorithmParams);
+            }
+
+            //EtM Composition Approach
+            int macLenght = mac.getMacLength();
+            mac.update(secure, 0, secure.length-macLenght);
+            byte[] signedDigestHash = mac.doFinal();
+
+            boolean isMacEqual = true;
+            for (int i = 0; i < signedDigestHash.length; i++)
+            {
+                if (signedDigestHash[i] != secure[secure.length-macLenght+i])
+                {
+                    isMacEqual = false;
+                    // MYFACES-2934 Must compare *ALL* bytes of the hash, 
+                    // otherwise a side-channel timing attack is theorically possible
+                    // but with a very very low probability, because the
+                    // comparison time is too small to be measured compared to
+                    // the overall request time and in real life applications,
+                    // there are too many uncertainties involved.
+                    //break;
+                }
+            }
+            if (!isMacEqual)
+            {
+                throw new ViewExpiredException();
+            }
+            
+            return cipher.doFinal(secure, 0, secure.length-macLenght);
+        }
+        catch (Exception e)
+        {
+            throw new FacesException(e);
+        }
+    }
+
+    /**
+     * Performs deserialization with the serialization provider created from the
+     * SerialFactory.
+     * 
+     * @param bytes
+     * @param ctx
+     * @return
+     */
+    
+    public static final Object getAsObject(byte[] bytes, ExternalContext ctx)
+    {
+        ByteArrayInputStream input = null;
+
+        try
+        {
+            input = new ByteArrayInputStream(bytes);
+
+            // get the Factory that was instantiated @ startup
+            SerialFactory serialFactory = (SerialFactory) ctx.getApplicationMap().get(SERIAL_FACTORY);
+            
+            if(serialFactory == null)
+            {
+                throw new NullPointerException("serialFactory");
+            }
+            
+            ObjectInputStream s = null;
+            Exception pendingException = null;
+            try
+            {
+                s = serialFactory.getObjectInputStream(input); 
+                Object object = null;
+                if (System.getSecurityManager() != null)
+                {
+                    final ObjectInputStream ois = s;
+                    object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>()
+                    {
+                        //Put IOException and ClassNotFoundException as "checked" exceptions,
+                        //so AccessController wrap them in a PrivilegedActionException
+                        public Object run() throws PrivilegedActionException, 
+                                                   IOException, ClassNotFoundException
+                        {
+                            return ois.readObject();
+                        }
+                    });
+                    // Since s has the same instance as ois,
+                    // we don't need to close it here, rather
+                    // close it on the finally block related to s
+                    // and avoid duplicate close exceptions
+                    // finally
+                    // {
+                    //    ois.close();
+                    // }
+                }
+                else
+                {
+                    object = s.readObject();
+                }
+                return object;
+            }
+            catch (Exception e)
+            {
+                pendingException = e;
+                throw new FacesException(e);
+            }
+            finally
+            {
+                if (s != null)
+                {
+                    try
+                    {
+                        s.close();
+                    }
+                    catch (IOException e)
+                    {
+                        // If a previous exception is thrown 
+                        // ignore this, but if not, wrap it in a
+                        // FacesException and throw it. In this way
+                        // we preserve the original semantic of this
+                        // method, but we handle correctly the case
+                        // when we close a stream. Obviously, the 
+                        // information about this exception is lost,
+                        // but note that the interesting information 
+                        // is always on pendingException, since we
+                        // only do a readObject() on the outer try block.
+                        if (pendingException == null)
+                        {
+                            throw new FacesException(e);
+                        }                        
+                    }
+                    finally
+                    {
+                        s = null;
+                    }
+                }
+            }
+        }
+        finally
+        {
+            if (input != null)
+            {
+                try
+                {
+                    input.close();
+                }
+                catch (IOException e)
+                {
+                    //ignore it, because ByteArrayInputStream.close has
+                    //no effect, but it is better to call close and preserve
+                    //semantic from previous code.
+                }
+                finally
+                {
+                    input = null;
+                }
+            }
+        }
+    }
+
+    /**
+     * Utility method for generating base 64 encoded strings.
+     * 
+     * @param args
+     * @throws UnsupportedEncodingException
+     */
+    public static void main (String[] args) throws UnsupportedEncodingException
+    {
+        byte[] bytes = encode(args[0].getBytes(ZIP_CHARSET));
+          System.out.println(new String(bytes, ZIP_CHARSET));
+    }
+
+    private static byte[] findInitializationVector(ExternalContext ctx)
+    {
+        
+        byte[] iv = null;
+        String ivString = ctx.getInitParameter(INIT_ALGORITHM_IV);
+        
+        if(ivString == null)
+        {
+            ivString = ctx.getInitParameter(INIT_ALGORITHM_IV.toLowerCase());
+        }
+        
+        if (ivString != null)
+        {
+            iv = new Base64().decode(ivString.getBytes());
+        }
+        
+        return iv;
+    }
+
+    private static String findAlgorithmParams(ExternalContext ctx)
+    {
+        
+        String algorithmParams = ctx.getInitParameter(INIT_ALGORITHM_PARAM);
+        
+        if (algorithmParams == null)
+        {
+            algorithmParams = ctx.getInitParameter(INIT_ALGORITHM_PARAM.toLowerCase());
+        }
+        
+        if (algorithmParams == null)
+        {
+            algorithmParams = DEFAULT_ALGORITHM_PARAMS;
+        }
+        
+        if (log.isLoggable(Level.FINE))
+        {
+            log.fine("Using algorithm paramaters " + algorithmParams);
+        }
+        
+        return algorithmParams;
+    }
+
+    private static String findAlgorithm(ExternalContext ctx)
+    {
+        
+        String algorithm = ctx.getInitParameter(INIT_ALGORITHM);
+        
+        if (algorithm == null)
+        {
+            algorithm = ctx.getInitParameter(INIT_ALGORITHM.toLowerCase());
+        }
+
+        return findAlgorithm( algorithm );
+    }
+    
+    private static String findAlgorithm(ServletContext ctx)
+    {
+
+        String algorithm = ctx.getInitParameter(INIT_ALGORITHM);
+        
+        if (algorithm == null)
+        {
+            algorithm = ctx.getInitParameter(INIT_ALGORITHM.toLowerCase());
+        }
+
+        return findAlgorithm( algorithm );
+    }
+    
+    private static String findAlgorithm(String initParam)
+    {
+        
+        if (initParam == null)
+        {
+            initParam = DEFAULT_ALGORITHM;
+        }
+        
+        if (log.isLoggable(Level.FINE))
+        {
+            log.fine("Using algorithm " + initParam);
+        }
+        
+        return initParam;
+        
+    }
+
+    /**
+     * Does nothing if the user has disabled the SecretKey cache. This is
+     * useful when dealing with a JCA provider whose SecretKey 
+     * implementation is not thread safe.
+     * 
+     * Instantiates a SecretKey instance based upon what the user has 
+     * specified in the deployment descriptor.  The SecretKey is then 
+     * stored in application scope where it can be used for all requests.
+     */
+    
+    public static void initSecret(ServletContext ctx)
+    {
+        
+        if(ctx == null)
+        {
+            throw new NullPointerException("ServletContext ctx");
+        }
+        
+        if (log.isLoggable(Level.FINE))
+        {
+            log.fine("Storing SecretKey @ " + INIT_SECRET_KEY_CACHE);
+        }
+
+        // Create and store SecretKey on application scope
+        String cache = ctx.getInitParameter(INIT_SECRET_KEY_CACHE);
+        
+        if(cache == null)
+        {
+            cache = ctx.getInitParameter(INIT_SECRET_KEY_CACHE.toLowerCase());
+        }
+        
+        if (!"false".equals(cache))
+        {
+            String algorithm = findAlgorithm(ctx);
+            // you want to create this as few times as possible
+            ctx.setAttribute(INIT_SECRET_KEY_CACHE, new SecretKeySpec(
+                    findSecret(ctx, algorithm), algorithm));
+        }
+
+        if (log.isLoggable(Level.FINE))
+        {
+            log.fine("Storing SecretKey @ " + INIT_MAC_SECRET_KEY_CACHE);
+        }
+        
+        String macCache = ctx.getInitParameter(INIT_MAC_SECRET_KEY_CACHE);
+        
+        if(macCache == null)
+        {
+            macCache = ctx.getInitParameter(INIT_MAC_SECRET_KEY_CACHE.toLowerCase());
+        }
+        
+        if (!"false".equals(macCache))
+        {
+            String macAlgorithm = findMacAlgorithm(ctx);
+            // init mac secret and algorithm 
+            ctx.setAttribute(INIT_MAC_SECRET_KEY_CACHE, new SecretKeySpec(
+                    findMacSecret(ctx, macAlgorithm), macAlgorithm));
+        }
+    }
+    
+    private static SecretKey getSecret(ExternalContext ctx)
+    {
+        Object secretKey = (SecretKey) ctx.getApplicationMap().get(INIT_SECRET_KEY_CACHE);
+        
+        if (secretKey == null)
+        {
+            String cache = ctx.getInitParameter(INIT_SECRET_KEY_CACHE);
+            
+            if(cache == null)
+            {
+                cache = ctx.getInitParameter(INIT_SECRET_KEY_CACHE.toLowerCase());
+            }
+            
+            if ("false".equals(cache))
+            {
+                // No cache is used. This option is activated
+                String secret = ctx.getInitParameter(INIT_SECRET);
+                
+                if (secret == null)
+                {
+                    secret = ctx.getInitParameter(INIT_SECRET.toLowerCase());
+                }
+
+                if (secret == null)
+                {
+                    throw new NullPointerException("Could not find secret using key '" + INIT_SECRET + "'");
+                }
+                
+                String algorithm = findAlgorithm(ctx);
+                
+                secretKey = new SecretKeySpec(findSecret(ctx, algorithm), algorithm);
+            }
+            else
+            {
+                throw new NullPointerException("Could not find SecretKey in application scope using key '" 
+                        + INIT_SECRET_KEY_CACHE + "'");
+            }
+        }
+        
+        if( ! ( secretKey instanceof SecretKey ) )
+        {
+            throw new ClassCastException("Did not find an instance of SecretKey "
+                    + "in application scope using the key '" + INIT_SECRET_KEY_CACHE + "'");
+        }
+
+        
+        return (SecretKey) secretKey;
+    }
+
+    private static byte[] findSecret(ExternalContext ctx, String algorithm)
+    {
+        String secret = ctx.getInitParameter(INIT_SECRET);
+        
+        if (secret == null)
+        {
+            secret = ctx.getInitParameter(INIT_SECRET.toLowerCase());
+        }
+        
+        return findSecret(secret, algorithm);
+    }    
+    
+    private static byte[] findSecret(ServletContext ctx, String algorithm)
+    {
+        String secret = ctx.getInitParameter(INIT_SECRET);
+        
+        if (secret == null)
+        {
+            secret = ctx.getInitParameter(INIT_SECRET.toLowerCase());
+        }
+        
+        return findSecret(secret, algorithm);
+    }
+    
+    private static byte[] findSecret(String secret, String algorithm)
+    {
+        byte[] bytes = null;
+        
+        if(secret == null)
+        {
+            try
+            {
+                KeyGenerator kg = KeyGenerator.getInstance(algorithm);
+                bytes = kg.generateKey().getEncoded();
+                
+                if(log.isLoggable(Level.FINE))
+                {
+                    log.fine("generated random password of length " + bytes.length);
+                }
+            }
+            catch (NoSuchAlgorithmException e)
+            {
+                // Generate random password length 8, 
+                int length = 8;
+                bytes = new byte[length];
+                new Random().nextBytes(bytes);
+                
+                if(log.isLoggable(Level.FINE))
+                {
+                    log.fine("generated random password of length " + length);
+                }
+            }
+        }
+        else 
+        {
+            bytes = new Base64().decode(secret.getBytes());
+        }
+        
+        return bytes;
+    }
+
+    private static String findMacAlgorithm(ExternalContext ctx)
+    {
+        
+        String algorithm = ctx.getInitParameter(INIT_MAC_ALGORITHM);
+        
+        if (algorithm == null)
+        {
+            algorithm = ctx.getInitParameter(INIT_MAC_ALGORITHM.toLowerCase());
+        }
+
+        return findMacAlgorithm( algorithm );
+
+    }
+    
+    private static String findMacAlgorithm(ServletContext ctx)
+    {
+
+        String algorithm = ctx.getInitParameter(INIT_MAC_ALGORITHM);
+        
+        if (algorithm == null)
+        {
+            algorithm = ctx.getInitParameter(INIT_MAC_ALGORITHM.toLowerCase());
+        }
+
+        return findMacAlgorithm( algorithm );
+        
+    }
+    
+    private static String findMacAlgorithm(String initParam)
+    {
+        
+        if (initParam == null)
+        {
+            initParam = DEFAULT_MAC_ALGORITHM;
+        }
+        
+        if (log.isLoggable(Level.FINE))
+        {
+            log.fine("Using algorithm " + initParam);
+        }
+        
+        return initParam;
+        
+    }
+    
+    private static SecretKey getMacSecret(ExternalContext ctx)
+    {
+        Object secretKey = (SecretKey) ctx.getApplicationMap().get(INIT_MAC_SECRET_KEY_CACHE);
+        
+        if (secretKey == null)
+        {
+            String cache = ctx.getInitParameter(INIT_MAC_SECRET_KEY_CACHE);
+            
+            if(cache == null)
+            {
+                cache = ctx.getInitParameter(INIT_MAC_SECRET_KEY_CACHE.toLowerCase());
+            }
+            
+            if ("false".equals(cache))
+            {
+                // No cache is used. This option is activated
+                String secret = ctx.getInitParameter(INIT_MAC_SECRET);
+                
+                if (secret == null)
+                {
+                    secret = ctx.getInitParameter(INIT_MAC_SECRET.toLowerCase());
+                }
+                
+                if (secret == null)
+                {
+                    throw new NullPointerException("Could not find secret using key '" + INIT_MAC_SECRET + "'");
+                }
+                
+                String macAlgorithm = findMacAlgorithm(ctx);
+
+                secretKey = new SecretKeySpec(findMacSecret(ctx, macAlgorithm), macAlgorithm);
+            }
+            else
+            {
+                throw new NullPointerException("Could not find SecretKey in application scope using key '" 
+                        + INIT_MAC_SECRET_KEY_CACHE + "'");
+            }
+        }
+        
+        if( ! ( secretKey instanceof SecretKey ) )
+        {
+            throw new ClassCastException("Did not find an instance of SecretKey "
+                    + "in application scope using the key '" + INIT_MAC_SECRET_KEY_CACHE + "'");
+        }
+
+        
+        return (SecretKey) secretKey;
+    }
+
+    private static byte[] findMacSecret(ExternalContext ctx, String algorithm)
+    {
+        String secret = ctx.getInitParameter(INIT_MAC_SECRET);
+        
+        if (secret == null)
+        {
+            secret = ctx.getInitParameter(INIT_MAC_SECRET.toLowerCase());
+        }
+ 
+        return findMacSecret(secret, algorithm);
+    }    
+    
+    private static byte[] findMacSecret(ServletContext ctx, String algorithm)
+    {
+        String secret = ctx.getInitParameter(INIT_MAC_SECRET);
+        
+        if (secret == null)
+        {
+            secret = ctx.getInitParameter(INIT_MAC_SECRET.toLowerCase());
+        }
+        
+        return findMacSecret(secret, algorithm);
+    }
+
+    private static byte[] findMacSecret(String secret, String algorithm)
+    {
+        byte[] bytes = null;
+        
+        if(secret == null)
+        {
+            try
+            {
+                KeyGenerator kg = KeyGenerator.getInstance(algorithm);
+                bytes = kg.generateKey().getEncoded();
+                
+                if(log.isLoggable(Level.FINE))
+                {
+                    log.fine("generated random mac password of length " + bytes.length);
+                }
+            }
+            catch (NoSuchAlgorithmException e)
+            {
+                // Generate random password length 8, 
+                int length = 8;
+                bytes = new byte[length];
+                new Random().nextBytes(bytes);
+                
+                if(log.isLoggable(Level.FINE))
+                {
+                    log.fine("generated random mac password of length " + length);
+                }
+            }
+        }
+        else 
+        {
+            bytes = new Base64().decode(secret.getBytes());
+        }
+        
+        return bytes;
+    }
+}
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/serial/DefaultSerialFactory.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/serial/DefaultSerialFactory.java
new file mode 100644
index 0000000..efaa810
--- /dev/null
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/serial/DefaultSerialFactory.java
@@ -0,0 +1,42 @@
+/*
+ * 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.trinidadinternal.util.serial;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+
+import org.apache.myfaces.trinidadinternal.util.MyFacesObjectInputStream;
+
+public class DefaultSerialFactory implements SerialFactory
+{
+
+    public ObjectOutputStream getObjectOutputStream(OutputStream outputStream) throws IOException
+    {
+        return new ObjectOutputStream(outputStream);
+    }
+
+    public ObjectInputStream getObjectInputStream(InputStream inputStream) throws IOException
+    {
+        return new MyFacesObjectInputStream(inputStream);
+    }
+    
+}
diff --git a/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/serial/SerialFactory.java b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/serial/SerialFactory.java
new file mode 100644
index 0000000..76487fb
--- /dev/null
+++ b/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/util/serial/SerialFactory.java
@@ -0,0 +1,31 @@
+/*
+ * 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.trinidadinternal.util.serial;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+
+public interface SerialFactory
+{
+    ObjectOutputStream getObjectOutputStream(OutputStream outputStream) throws IOException;
+    ObjectInputStream getObjectInputStream(InputStream inputStream) throws IOException;
+}
diff --git a/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/renderkit/core/resource/CoreBundle_cs.xrts b/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/renderkit/core/resource/CoreBundle_cs.xrts
index ef02939..e98043f 100644
--- a/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/renderkit/core/resource/CoreBundle_cs.xrts
+++ b/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/renderkit/core/resource/CoreBundle_cs.xrts
@@ -105,9 +105,9 @@
 <resource key="af_table.SELECT_RANGE_NEXT" dnt="false">Následující {0}</resource>
 <!--navigation bar with no more records going forward.-->
 <!--the following text will be drawn in a disabled font-->
-<resource key="af_selectRangeChoiceBar.DISABLED_NEXT" dnt="false">Další</resource>
-<resource key="af_table.SELECT_RANGE_DISABLED_NEXT" dnt="false">Další</resource>
-<resource key="af_treeTable.DISABLED_NEXT" dnt="false">Další</resource>
+<resource key="af_selectRangeChoiceBar.DISABLED_NEXT" dnt="false">Následující</resource>
+<resource key="af_table.SELECT_RANGE_DISABLED_NEXT" dnt="false">Následující</resource>
+<resource key="af_treeTable.DISABLED_NEXT" dnt="false">Následující</resource>
 <!--navigation bar with no more records going backward.-->
 <!--the following text will be drawn in a disabled font-->
 <resource key="af_selectRangeChoiceBar.DISABLED_PREVIOUS" dnt="false">PĹ™edchozí</resource>