diff --git a/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlResponseStateManager.java b/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlResponseStateManager.java
index 8ae5fc4..7dc9710 100755
--- a/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlResponseStateManager.java
+++ b/impl/src/main/java/org/apache/myfaces/renderkit/html/HtmlResponseStateManager.java
@@ -1,329 +1,329 @@
-/*
- * 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.renderkit.html;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.logging.Logger;
-
-import jakarta.faces.context.FacesContext;
-import jakarta.faces.context.ResponseWriter;
-import jakarta.faces.lifecycle.ClientWindow;
-import jakarta.faces.render.RenderKitFactory;
-import jakarta.faces.render.ResponseStateManager;
-
-import org.apache.myfaces.application.viewstate.StateCache;
-import org.apache.myfaces.renderkit.MyfacesResponseStateManager;
-import org.apache.myfaces.config.MyfacesConfig;
-import org.apache.myfaces.renderkit.html.util.HTML;
-import org.apache.myfaces.spi.StateCacheProvider;
-import org.apache.myfaces.spi.StateCacheProviderFactory;
-
-/**
- * @author Manfred Geiler (latest modification by $Author$)
- * @version $Revision$ $Date$
- */
-public class HtmlResponseStateManager extends MyfacesResponseStateManager
-{
-    private static final Logger log = Logger.getLogger(HtmlResponseStateManager.class.getName());
-    
-    private static final String VIEW_STATE_COUNTER = "oam.partial.VIEW_STATE_COUNTER";
-    private static final String CLIENT_WINDOW_COUNTER = "oam.partial.CLIENT_WINDOW_COUNTER";
-    
-    private static final String SESSION_TOKEN = "oam.rsm.SESSION_TOKEN";
-
-    private StateCacheProvider stateCacheFactory;
-    private MyfacesConfig myfacesConfig;
-    
-    public HtmlResponseStateManager()
-    {        
-        FacesContext facesContext = FacesContext.getCurrentInstance();
-        myfacesConfig = MyfacesConfig.getCurrentInstance(facesContext.getExternalContext());
-        
-        stateCacheFactory = StateCacheProviderFactory
-                .getStateCacheProviderFactory(facesContext.getExternalContext())
-                .getStateCacheProvider(facesContext.getExternalContext());
-    }
-    
-    @Override
-    public void writeState(FacesContext facesContext, Object state) throws IOException
-    {
-        ResponseWriter responseWriter = facesContext.getResponseWriter();
-
-        Object savedStateObject = null;
-        
-        if (!facesContext.getViewRoot().isTransient())
-        {
-            // Only if the view is not transient needs to be saved
-            savedStateObject = getStateCache(facesContext).encodeSerializedState(facesContext, state);
-        }
-
-        // write the view state field
-        writeViewStateField(facesContext, responseWriter, savedStateObject);
-
-        // renderKitId field
-        writeRenderKitIdField(facesContext, responseWriter);
-        
-        // windowId field
-        writeWindowIdField(facesContext, responseWriter);
-    }
-    
-    private void writeWindowIdField(FacesContext facesContext, ResponseWriter responseWriter) throws IOException
-    {
-        ClientWindow clientWindow = facesContext.getExternalContext().getClientWindow();
-        if (clientWindow != null)
-        {
-            responseWriter.startElement(HTML.INPUT_ELEM, null);
-            responseWriter.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
-            responseWriter.writeAttribute(HTML.ID_ATTR, generateUpdateClientWindowId(facesContext), null);
-            responseWriter.writeAttribute(HTML.NAME_ATTR, ResponseStateManager.CLIENT_WINDOW_PARAM, null);
-            responseWriter.writeAttribute(HTML.VALUE_ATTR, clientWindow.getId(), null);
-            responseWriter.endElement(HTML.INPUT_ELEM);
-        }
-    }
-    
-    @Override
-    public void saveState(FacesContext facesContext, Object state)
-    {
-        if (!facesContext.getViewRoot().isTransient())
-        {
-            getStateCache(facesContext).saveSerializedView(facesContext, state);
-        }
-    }
-
-    private void writeViewStateField(FacesContext facesContext, ResponseWriter responseWriter, Object savedState)
-        throws IOException
-    {
-        String serializedState = getStateCache(facesContext).getStateTokenProcessor(facesContext)
-                .encode(facesContext, savedState);
-
-        responseWriter.startElement(HTML.INPUT_ELEM, null);
-        responseWriter.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
-        responseWriter.writeAttribute(HTML.NAME_ATTR, ResponseStateManager.VIEW_STATE_PARAM, null);
-        if (myfacesConfig.isRenderViewStateId())
-        {
-            // responseWriter.writeAttribute(HTML.ID_ATTR, STANDARD_STATE_SAVING_PARAM, null);
-            // JSF 2.2 if jakarta.faces.ViewState is used as the id, in portlet
-            // case it will be duplicate ids and that not xml friendly.
-            responseWriter.writeAttribute(HTML.ID_ATTR,
-                HtmlResponseStateManager.generateUpdateViewStateId(facesContext),
-                null);
-        }
-        responseWriter.writeAttribute(HTML.VALUE_ATTR, serializedState, null);
-        if (myfacesConfig.isAutocompleteOffViewState())
-        {
-            responseWriter.writeAttribute(HTML.AUTOCOMPLETE_ATTR, "off", null);
-        }
-        responseWriter.endElement(HTML.INPUT_ELEM);
-    }
-
-    private void writeRenderKitIdField(FacesContext facesContext, ResponseWriter responseWriter) throws IOException
-    {
-
-        String defaultRenderKitId = facesContext.getApplication().getDefaultRenderKitId();
-        if (defaultRenderKitId != null && !RenderKitFactory.HTML_BASIC_RENDER_KIT.equals(defaultRenderKitId))
-        {
-            responseWriter.startElement(HTML.INPUT_ELEM, null);
-            responseWriter.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
-            responseWriter.writeAttribute(HTML.NAME_ATTR, ResponseStateManager.RENDER_KIT_ID_PARAM, null);
-            responseWriter.writeAttribute(HTML.VALUE_ATTR, defaultRenderKitId, null);
-            responseWriter.endElement(HTML.INPUT_ELEM);
-        }
-    }
-
-    @Override
-    public Object getState(FacesContext facesContext, String viewId)
-    {
-        Object savedState = getSavedState(facesContext);
-        if (savedState == null)
-        {
-            return null;
-        }
-
-        return getStateCache(facesContext).restoreSerializedView(facesContext, viewId, savedState);
-    }
-
-    /**
-     * Reconstructs the state from the "jakarta.faces.ViewState" request parameter.
-     * 
-     * @param facesContext
-     *            the current FacesContext
-     * 
-     * @return the reconstructed state, or <code>null</code> if there was no saved state
-     */
-    private Object getSavedState(FacesContext facesContext)
-    {
-        Object encodedState = 
-            facesContext.getExternalContext().getRequestParameterMap().get(ResponseStateManager.VIEW_STATE_PARAM);
-        if(encodedState==null || (((String) encodedState).length() == 0))
-        {
-            return null;
-        }
-
-        Object savedStateObject = getStateCache(facesContext).getStateTokenProcessor(facesContext)
-                .decode(facesContext, (String)encodedState);
-        
-        return savedStateObject;
-    }
-
-    /**
-     * Checks if the current request is a postback
-     * 
-     * @since 1.2
-     */
-    @Override
-    public boolean isPostback(FacesContext context)
-    {
-        return context.getExternalContext().getRequestParameterMap().containsKey(ResponseStateManager.VIEW_STATE_PARAM);
-    }
-
-    @Override
-    public String getViewState(FacesContext facesContext, Object baseState)
-    {
-        // If the view is transient, baseState is null, so it should return null.
-        // In this way, PartialViewContext will skip <update ...> section related
-        // to view state (stateless view does not have state, so it does not need
-        // to update the view state section). 
-        if (baseState == null)
-        {
-            return null;
-        }
-        if (facesContext.getViewRoot().isTransient())
-        {
-            return null;
-        }
-        
-        Object state = getStateCache(facesContext).saveSerializedView(facesContext, baseState);
-
-        return getStateCache(facesContext).getStateTokenProcessor(facesContext).encode(facesContext, state);
-    }
-
-    @Override
-    public boolean isStateless(FacesContext context, String viewId)
-    {
-        if (context.isPostback())
-        {
-            String encodedState = 
-                context.getExternalContext().getRequestParameterMap().get(ResponseStateManager.VIEW_STATE_PARAM);
-            if (encodedState == null || ((String) encodedState).length() == 0)
-            {
-                return false;
-            }
-
-            return getStateCache(context).getStateTokenProcessor(context).isStateless(context, encodedState);
-        }
-        else 
-        {
-            // "... java.lang.IllegalStateException - if this method is invoked 
-            // and the statefulness of the preceding call to writeState(
-            // jakarta.faces.context.FacesContext, java.lang.Object) cannot be determined.
-            throw new IllegalStateException(
-                "Cannot decide if the view is stateless or not, since the request is "
-                + "not postback (no preceding writeState(...)).");
-        }
-    }
-
-    @Override
-    public String getCryptographicallyStrongTokenFromSession(FacesContext context)
-    {
-        Map<String, Object> sessionMap = context.getExternalContext().getSessionMap();
-        String savedToken = (String) sessionMap.get(SESSION_TOKEN);
-        if (savedToken == null)
-        {
-            savedToken = getStateCache(context).createCryptographicallyStrongTokenFromSession(context);
-            sessionMap.put(SESSION_TOKEN, savedToken);
-        }
-        return savedToken;
-    }
-    
-    @Override
-    public boolean isWriteStateAfterRenderViewRequired(FacesContext facesContext)
-    {
-        return getStateCache(facesContext).isWriteStateAfterRenderViewRequired(facesContext);
-    }
-
-    protected StateCache getStateCache(FacesContext facesContext)
-    {
-        return stateCacheFactory.getStateCache(facesContext);
-    }
-
-    public static String generateUpdateClientWindowId(FacesContext facesContext)
-    {
-        // JSF 2.2 section 2.2.6.1 Partial State Rendering
-        // According to the javascript doc of faces.ajax.response,
-        //
-        // The new syntax looks like this:
-        // <update id="<VIEW_ROOT_CONTAINER_CLIENT_ID><SEP>jakarta.faces.ClientWindow<SEP><UNIQUE_PER_VIEW_NUMBER>">
-        //    <![CDATA[...]]>
-        // </update>
-        //
-        // UNIQUE_PER_VIEW_NUMBER aim for portlet case. In that case it is possible to have
-        // multiple sections for update. In servlet case there is only one update section per
-        // ajax request.
-        
-        char separator = facesContext.getNamingContainerSeparatorChar();
-
-        Integer count = (Integer) facesContext.getAttributes().get(CLIENT_WINDOW_COUNTER);
-        if (count == null)
-        {
-            count = Integer.valueOf(1);
-        }
-        else
-        {
-            count += 1;
-        }
-        facesContext.getAttributes().put(CLIENT_WINDOW_COUNTER, count);
-
-        String id = facesContext.getViewRoot().getContainerClientId(facesContext) + 
-            separator + ResponseStateManager.CLIENT_WINDOW_PARAM + separator + count;
-        return id;
-    }
-    
-    public static String generateUpdateViewStateId(FacesContext facesContext)
-    {
-        // JSF 2.2 section 2.2.6.1 Partial State Rendering
-        // According to the javascript doc of faces.ajax.response,
-        //
-        // The new syntax looks like this:
-        // <update id="<VIEW_ROOT_CONTAINER_CLIENT_ID><SEP>jakarta.faces.ViewState<SEP><UNIQUE_PER_VIEW_NUMBER>">
-        //    <![CDATA[...]]>
-        // </update>
-        //
-        // UNIQUE_PER_VIEW_NUMBER aim for portlet case. In that case it is possible to have
-        // multiple sections for update. In servlet case there is only one update section per
-        // ajax request.
-
-        char separator = facesContext.getNamingContainerSeparatorChar();
-
-        Integer count = (Integer) facesContext.getAttributes().get(VIEW_STATE_COUNTER);
-        if (count == null)
-        {
-            count = Integer.valueOf(1);
-        }
-        else
-        {
-            count += 1;
-        }
-        facesContext.getAttributes().put(VIEW_STATE_COUNTER, count);
-
-        String id = facesContext.getViewRoot().getContainerClientId(facesContext) + 
-            separator + ResponseStateManager.VIEW_STATE_PARAM + separator + count;
-        return id;
-    }
-}
+/*
+ * 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.renderkit.html;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import jakarta.faces.context.FacesContext;
+import jakarta.faces.context.ResponseWriter;
+import jakarta.faces.lifecycle.ClientWindow;
+import jakarta.faces.render.RenderKitFactory;
+import jakarta.faces.render.ResponseStateManager;
+
+import org.apache.myfaces.application.viewstate.StateCache;
+import org.apache.myfaces.renderkit.MyfacesResponseStateManager;
+import org.apache.myfaces.config.MyfacesConfig;
+import org.apache.myfaces.renderkit.html.util.HTML;
+import org.apache.myfaces.spi.StateCacheProvider;
+import org.apache.myfaces.spi.StateCacheProviderFactory;
+
+/**
+ * @author Manfred Geiler (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+public class HtmlResponseStateManager extends MyfacesResponseStateManager
+{
+    private static final Logger log = Logger.getLogger(HtmlResponseStateManager.class.getName());
+    
+    private static final String VIEW_STATE_COUNTER = "oam.partial.VIEW_STATE_COUNTER";
+    private static final String CLIENT_WINDOW_COUNTER = "oam.partial.CLIENT_WINDOW_COUNTER";
+    
+    private static final String SESSION_TOKEN = "oam.rsm.SESSION_TOKEN";
+
+    private StateCacheProvider stateCacheFactory;
+    private MyfacesConfig myfacesConfig;
+    
+    public HtmlResponseStateManager()
+    {        
+        FacesContext facesContext = FacesContext.getCurrentInstance();
+        myfacesConfig = MyfacesConfig.getCurrentInstance(facesContext.getExternalContext());
+        
+        stateCacheFactory = StateCacheProviderFactory
+                .getStateCacheProviderFactory(facesContext.getExternalContext())
+                .getStateCacheProvider(facesContext.getExternalContext());
+    }
+    
+    @Override
+    public void writeState(FacesContext facesContext, Object state) throws IOException
+    {
+        ResponseWriter responseWriter = facesContext.getResponseWriter();
+
+        Object savedStateObject = null;
+        
+        if (!facesContext.getViewRoot().isTransient())
+        {
+            // Only if the view is not transient needs to be saved
+            savedStateObject = getStateCache(facesContext).encodeSerializedState(facesContext, state);
+        }
+
+        // write the view state field
+        writeViewStateField(facesContext, responseWriter, savedStateObject);
+
+        // renderKitId field
+        writeRenderKitIdField(facesContext, responseWriter);
+        
+        // windowId field
+        writeWindowIdField(facesContext, responseWriter);
+    }
+    
+    private void writeWindowIdField(FacesContext facesContext, ResponseWriter responseWriter) throws IOException
+    {
+        ClientWindow clientWindow = facesContext.getExternalContext().getClientWindow();
+        if (clientWindow != null)
+        {
+            responseWriter.startElement(HTML.INPUT_ELEM, null);
+            responseWriter.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
+            responseWriter.writeAttribute(HTML.ID_ATTR, generateUpdateClientWindowId(facesContext), null);
+            responseWriter.writeAttribute(HTML.NAME_ATTR, ResponseStateManager.CLIENT_WINDOW_PARAM, null);
+            responseWriter.writeAttribute(HTML.VALUE_ATTR, clientWindow.getId(), null);
+            responseWriter.endElement(HTML.INPUT_ELEM);
+        }
+    }
+    
+    @Override
+    public void saveState(FacesContext facesContext, Object state)
+    {
+        if (!facesContext.getViewRoot().isTransient())
+        {
+            getStateCache(facesContext).saveSerializedView(facesContext, state);
+        }
+    }
+
+    private void writeViewStateField(FacesContext facesContext, ResponseWriter responseWriter, Object savedState)
+        throws IOException
+    {
+        String serializedState = getStateCache(facesContext).getStateTokenProcessor(facesContext)
+                .encode(facesContext, savedState);
+
+        responseWriter.startElement(HTML.INPUT_ELEM, null);
+        responseWriter.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
+        responseWriter.writeAttribute(HTML.NAME_ATTR, ResponseStateManager.VIEW_STATE_PARAM, null);
+        if (myfacesConfig.isRenderViewStateId())
+        {
+            // responseWriter.writeAttribute(HTML.ID_ATTR, STANDARD_STATE_SAVING_PARAM, null);
+            // JSF 2.2 if jakarta.faces.ViewState is used as the id, in portlet
+            // case it will be duplicate ids and that not xml friendly.
+            responseWriter.writeAttribute(HTML.ID_ATTR,
+                HtmlResponseStateManager.generateUpdateViewStateId(facesContext),
+                null);
+        }
+        responseWriter.writeAttribute(HTML.VALUE_ATTR, serializedState, null);
+        if (myfacesConfig.isAutocompleteOffViewState())
+        {
+            responseWriter.writeAttribute(HTML.AUTOCOMPLETE_ATTR, "off", null);
+        }
+        responseWriter.endElement(HTML.INPUT_ELEM);
+    }
+
+    private void writeRenderKitIdField(FacesContext facesContext, ResponseWriter responseWriter) throws IOException
+    {
+
+        String defaultRenderKitId = facesContext.getApplication().getDefaultRenderKitId();
+        if (defaultRenderKitId != null && !RenderKitFactory.HTML_BASIC_RENDER_KIT.equals(defaultRenderKitId))
+        {
+            responseWriter.startElement(HTML.INPUT_ELEM, null);
+            responseWriter.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
+            responseWriter.writeAttribute(HTML.NAME_ATTR, ResponseStateManager.RENDER_KIT_ID_PARAM, null);
+            responseWriter.writeAttribute(HTML.VALUE_ATTR, defaultRenderKitId, null);
+            responseWriter.endElement(HTML.INPUT_ELEM);
+        }
+    }
+
+    @Override
+    public Object getState(FacesContext facesContext, String viewId)
+    {
+        Object savedState = getSavedState(facesContext);
+        if (savedState == null)
+        {
+            return null;
+        }
+
+        return getStateCache(facesContext).restoreSerializedView(facesContext, viewId, savedState);
+    }
+
+    /**
+     * Reconstructs the state from the "jakarta.faces.ViewState" request parameter.
+     * 
+     * @param facesContext
+     *            the current FacesContext
+     * 
+     * @return the reconstructed state, or <code>null</code> if there was no saved state
+     */
+    private Object getSavedState(FacesContext facesContext)
+    {
+        Object encodedState = 
+            facesContext.getExternalContext().getRequestParameterMap().get(ResponseStateManager.VIEW_STATE_PARAM);
+        if(encodedState==null || (((String) encodedState).length() == 0))
+        {
+            return null;
+        }
+
+        Object savedStateObject = getStateCache(facesContext).getStateTokenProcessor(facesContext)
+                .decode(facesContext, (String)encodedState);
+        
+        return savedStateObject;
+    }
+
+    /**
+     * Checks if the current request is a postback
+     * 
+     * @since 1.2
+     */
+    @Override
+    public boolean isPostback(FacesContext context)
+    {
+        return context.getExternalContext().getRequestParameterMap().containsKey(ResponseStateManager.VIEW_STATE_PARAM);
+    }
+
+    @Override
+    public String getViewState(FacesContext facesContext, Object baseState)
+    {
+        // If the view is transient, baseState is null, so it should return null.
+        // In this way, PartialViewContext will skip <update ...> section related
+        // to view state (stateless view does not have state, so it does not need
+        // to update the view state section). 
+        if (baseState == null)
+        {
+            return null;
+        }
+        if (facesContext.getViewRoot().isTransient())
+        {
+            return null;
+        }
+        
+        Object state = getStateCache(facesContext).saveSerializedView(facesContext, baseState);
+
+        return getStateCache(facesContext).getStateTokenProcessor(facesContext).encode(facesContext, state);
+    }
+
+    @Override
+    public boolean isStateless(FacesContext context, String viewId)
+    {
+        if (context.isPostback())
+        {
+            String encodedState = 
+                context.getExternalContext().getRequestParameterMap().get(ResponseStateManager.VIEW_STATE_PARAM);
+            if (encodedState == null || ((String) encodedState).length() == 0)
+            {
+                return false;
+            }
+
+            return getStateCache(context).getStateTokenProcessor(context).isStateless(context, encodedState);
+        }
+        else 
+        {
+            // "... java.lang.IllegalStateException - if this method is invoked 
+            // and the statefulness of the preceding call to writeState(
+            // jakarta.faces.context.FacesContext, java.lang.Object) cannot be determined.
+            throw new IllegalStateException(
+                "Cannot decide if the view is stateless or not, since the request is "
+                + "not postback (no preceding writeState(...)).");
+        }
+    }
+
+    @Override
+    public String getCryptographicallyStrongTokenFromSession(FacesContext context)
+    {
+        Map<String, Object> sessionMap = context.getExternalContext().getSessionMap();
+        String savedToken = (String) sessionMap.get(SESSION_TOKEN);
+        if (savedToken == null)
+        {
+            savedToken = getStateCache(context).createCryptographicallyStrongTokenFromSession(context);
+            sessionMap.put(SESSION_TOKEN, savedToken);
+        }
+        return savedToken;
+    }
+    
+    @Override
+    public boolean isWriteStateAfterRenderViewRequired(FacesContext facesContext)
+    {
+        return getStateCache(facesContext).isWriteStateAfterRenderViewRequired(facesContext);
+    }
+
+    protected StateCache getStateCache(FacesContext facesContext)
+    {
+        return stateCacheFactory.getStateCache(facesContext);
+    }
+
+    public static String generateUpdateClientWindowId(FacesContext facesContext)
+    {
+        // JSF 2.2 section 2.2.6.1 Partial State Rendering
+        // According to the javascript doc of faces.ajax.response,
+        //
+        // The new syntax looks like this:
+        // <update id="<VIEW_ROOT_CONTAINER_CLIENT_ID><SEP>jakarta.faces.ClientWindow<SEP><UNIQUE_PER_VIEW_NUMBER>">
+        //    <![CDATA[...]]>
+        // </update>
+        //
+        // UNIQUE_PER_VIEW_NUMBER aim for portlet case. In that case it is possible to have
+        // multiple sections for update. In servlet case there is only one update section per
+        // ajax request.
+        
+        char separator = facesContext.getNamingContainerSeparatorChar();
+
+        Integer count = (Integer) facesContext.getAttributes().get(CLIENT_WINDOW_COUNTER);
+        if (count == null)
+        {
+            count = Integer.valueOf(1);
+        }
+        else
+        {
+            count += 1;
+        }
+        facesContext.getAttributes().put(CLIENT_WINDOW_COUNTER, count);
+
+        String id = facesContext.getViewRoot().getContainerClientId(facesContext) + 
+            separator + ResponseStateManager.CLIENT_WINDOW_PARAM + separator + count;
+        return id;
+    }
+    
+    public static String generateUpdateViewStateId(FacesContext facesContext)
+    {
+        // JSF 2.2 section 2.2.6.1 Partial State Rendering
+        // According to the javascript doc of faces.ajax.response,
+        //
+        // The new syntax looks like this:
+        // <update id="<VIEW_ROOT_CONTAINER_CLIENT_ID><SEP>jakarta.faces.ViewState<SEP><UNIQUE_PER_VIEW_NUMBER>">
+        //    <![CDATA[...]]>
+        // </update>
+        //
+        // UNIQUE_PER_VIEW_NUMBER aim for portlet case. In that case it is possible to have
+        // multiple sections for update. In servlet case there is only one update section per
+        // ajax request.
+
+        char separator = facesContext.getNamingContainerSeparatorChar();
+
+        Integer count = (Integer) facesContext.getAttributes().get(VIEW_STATE_COUNTER);
+        if (count == null)
+        {
+            count = Integer.valueOf(1);
+        }
+        else
+        {
+            count += 1;
+        }
+        facesContext.getAttributes().put(VIEW_STATE_COUNTER, count);
+
+        String id = facesContext.getViewRoot().getContainerClientId(facesContext) + 
+            separator + ResponseStateManager.VIEW_STATE_PARAM + separator + count;
+        return id;
+    }
+}
diff --git a/impl/src/main/java/org/apache/myfaces/webapp/MyFacesHttpSessionListener.java b/impl/src/main/java/org/apache/myfaces/webapp/MyFacesHttpSessionListener.java
index 7f5b99a..13f7217 100644
--- a/impl/src/main/java/org/apache/myfaces/webapp/MyFacesHttpSessionListener.java
+++ b/impl/src/main/java/org/apache/myfaces/webapp/MyFacesHttpSessionListener.java
@@ -1,84 +1,84 @@
-/*
- * 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.webapp;
-
-import jakarta.faces.context.ExceptionHandler;
-import jakarta.faces.context.ExternalContext;
-import jakarta.faces.context.FacesContext;
-import jakarta.servlet.ServletContext;
-import jakarta.servlet.http.HttpSessionEvent;
-import jakarta.servlet.http.HttpSessionListener;
-import org.apache.myfaces.cdi.clientwindow.ClientWindowScopeContext;
-import org.apache.myfaces.cdi.view.ViewScopeContext;
-import org.apache.myfaces.context.ExceptionHandlerImpl;
-import org.apache.myfaces.context.servlet.StartupFacesContextImpl;
-import org.apache.myfaces.context.servlet.StartupServletExternalContextImpl;
-import org.apache.myfaces.flow.cdi.FlowScopeContext;
-
-public class MyFacesHttpSessionListener implements HttpSessionListener
-{
-    public static final String APPLICATION_MAP_KEY = MyFacesHttpSessionListener.class.getName();
-
-    @Override
-    public void sessionCreated(HttpSessionEvent event)
-    {
-    }
-
-    @Override
-    public void sessionDestroyed(HttpSessionEvent event)
-    {
-        // If we don't propagate this event, CDI will do for us but outside JSF control
-        // so when @PreDestroy methods are called there will not be an active FacesContext.
-        // The trick here is ensure clean the affected scopes to avoid duplicates.
-        // Remember cdi session scope is different from jsf session scope, because in
-        // jsf case the beans are stored under a session attribute, so it has the problem
-        // with attributeRemoved, but on cdi a wrapper is used instead, avoiding the problem.
-        FacesContext facesContext = FacesContext.getCurrentInstance();
-        if (facesContext != null)
-        {
-            FlowScopeContext.destroyAll(facesContext);
-            ViewScopeContext.destroyAll(facesContext);
-            ClientWindowScopeContext.destroyAll(facesContext);
-        }
-        else
-        {
-            // In case no FacesContext is available, we are on session invalidation
-            // through timeout. In that case, create a dummy FacesContext for this one
-            // like the one used in startup or shutdown and invoke the destroy method.
-            try
-            {
-                ServletContext servletContext = event.getSession().getServletContext();
-                ExternalContext externalContext = new StartupServletExternalContextImpl(servletContext, false);
-                ExceptionHandler exceptionHandler = new ExceptionHandlerImpl();
-                facesContext = new StartupFacesContextImpl(externalContext, externalContext, exceptionHandler, false);
-
-                FlowScopeContext.destroyAll(facesContext);
-                ViewScopeContext.destroyAll(facesContext);
-                ClientWindowScopeContext.destroyAll(facesContext);
-            }
-            finally
-            {
-                if (facesContext != null)
-                {
-                    facesContext.release();
-                }
-            }
-        }
-    }
-}
+/*
+ * 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.webapp;
+
+import jakarta.faces.context.ExceptionHandler;
+import jakarta.faces.context.ExternalContext;
+import jakarta.faces.context.FacesContext;
+import jakarta.servlet.ServletContext;
+import jakarta.servlet.http.HttpSessionEvent;
+import jakarta.servlet.http.HttpSessionListener;
+import org.apache.myfaces.cdi.clientwindow.ClientWindowScopeContext;
+import org.apache.myfaces.cdi.view.ViewScopeContext;
+import org.apache.myfaces.context.ExceptionHandlerImpl;
+import org.apache.myfaces.context.servlet.StartupFacesContextImpl;
+import org.apache.myfaces.context.servlet.StartupServletExternalContextImpl;
+import org.apache.myfaces.flow.cdi.FlowScopeContext;
+
+public class MyFacesHttpSessionListener implements HttpSessionListener
+{
+    public static final String APPLICATION_MAP_KEY = MyFacesHttpSessionListener.class.getName();
+
+    @Override
+    public void sessionCreated(HttpSessionEvent event)
+    {
+    }
+
+    @Override
+    public void sessionDestroyed(HttpSessionEvent event)
+    {
+        // If we don't propagate this event, CDI will do for us but outside JSF control
+        // so when @PreDestroy methods are called there will not be an active FacesContext.
+        // The trick here is ensure clean the affected scopes to avoid duplicates.
+        // Remember cdi session scope is different from jsf session scope, because in
+        // jsf case the beans are stored under a session attribute, so it has the problem
+        // with attributeRemoved, but on cdi a wrapper is used instead, avoiding the problem.
+        FacesContext facesContext = FacesContext.getCurrentInstance();
+        if (facesContext != null)
+        {
+            FlowScopeContext.destroyAll(facesContext);
+            ViewScopeContext.destroyAll(facesContext);
+            ClientWindowScopeContext.destroyAll(facesContext);
+        }
+        else
+        {
+            // In case no FacesContext is available, we are on session invalidation
+            // through timeout. In that case, create a dummy FacesContext for this one
+            // like the one used in startup or shutdown and invoke the destroy method.
+            try
+            {
+                ServletContext servletContext = event.getSession().getServletContext();
+                ExternalContext externalContext = new StartupServletExternalContextImpl(servletContext, false);
+                ExceptionHandler exceptionHandler = new ExceptionHandlerImpl();
+                facesContext = new StartupFacesContextImpl(externalContext, externalContext, exceptionHandler, false);
+
+                FlowScopeContext.destroyAll(facesContext);
+                ViewScopeContext.destroyAll(facesContext);
+                ClientWindowScopeContext.destroyAll(facesContext);
+            }
+            finally
+            {
+                if (facesContext != null)
+                {
+                    facesContext.release();
+                }
+            }
+        }
+    }
+}
diff --git a/impl/src/test/java/org/apache/myfaces/view/facelets/tag/faces/html/SelectOneItemsTest.java b/impl/src/test/java/org/apache/myfaces/view/facelets/tag/faces/html/SelectOneItemsTest.java
index b5d4be2..7172ad0 100644
--- a/impl/src/test/java/org/apache/myfaces/view/facelets/tag/faces/html/SelectOneItemsTest.java
+++ b/impl/src/test/java/org/apache/myfaces/view/facelets/tag/faces/html/SelectOneItemsTest.java
@@ -1,43 +1,43 @@
-/*
- * 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.view.facelets.tag.faces.html;
-
-import org.apache.myfaces.test.core.AbstractMyFacesCDIRequestTestCase;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-public class SelectOneItemsTest extends AbstractMyFacesCDIRequestTestCase
-{
-    @Test
-    public void testIndex() throws Exception
-    {
-        startViewRequest("/selectOneItems.xhtml");
-        processLifecycleExecuteAndRender();
-        
-        String content = getRenderedContent();
-        System.err.println(content);
-        Assert.assertTrue(content.contains("Cars"));
-        Assert.assertTrue(content.contains("Animals"));
-        Assert.assertTrue(content.contains("Audi"));
-        Assert.assertTrue(content.contains("Fish"));
-
-        endRequest();
-    }
+/*
+ * 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.view.facelets.tag.faces.html;
+
+import org.apache.myfaces.test.core.AbstractMyFacesCDIRequestTestCase;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class SelectOneItemsTest extends AbstractMyFacesCDIRequestTestCase
+{
+    @Test
+    public void testIndex() throws Exception
+    {
+        startViewRequest("/selectOneItems.xhtml");
+        processLifecycleExecuteAndRender();
+        
+        String content = getRenderedContent();
+        System.err.println(content);
+        Assert.assertTrue(content.contains("Cars"));
+        Assert.assertTrue(content.contains("Animals"));
+        Assert.assertTrue(content.contains("Audi"));
+        Assert.assertTrue(content.contains("Fish"));
+
+        endRequest();
+    }
 }
\ No newline at end of file
diff --git a/impl/src/test/java/org/apache/myfaces/view/facelets/tag/faces/html/SelectOneItemsTestBean.java b/impl/src/test/java/org/apache/myfaces/view/facelets/tag/faces/html/SelectOneItemsTestBean.java
index 846e547..16b77ae 100644
--- a/impl/src/test/java/org/apache/myfaces/view/facelets/tag/faces/html/SelectOneItemsTestBean.java
+++ b/impl/src/test/java/org/apache/myfaces/view/facelets/tag/faces/html/SelectOneItemsTestBean.java
@@ -1,106 +1,106 @@
-/*
- * 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.view.facelets.tag.faces.html;
-
-import jakarta.annotation.PostConstruct;
-import jakarta.enterprise.context.RequestScoped;
-import jakarta.inject.Named;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-@Named
-@RequestScoped
-public class SelectOneItemsTestBean {
-
-    private List<Category> categories = new ArrayList<>();
-    private Long selectedProductId;
-
-    @PostConstruct
-    public void init() {
-        categories.add(new Category("Animals", new Product(1L, "Dog"), new Product(2L, "Cat"), new Product(3L, "Fish")));
-        categories.add(new Category("Cars", new Product(4L, "Alfa"), new Product(5L, "Audi"), new Product(6L, "BMW")));
-    }
-
-    public List<Category> getCategories() {
-        return categories;
-    }
-
-    public Long getSelectedProductId() {
-        return selectedProductId;
-    }
-
-    public void setSelectedProductId(Long selectedProductId) {
-        this.selectedProductId = selectedProductId;
-    }
-
-    public static class Product {
-        private Long id;
-        private String name;
-
-        public Product() {
-        }
-
-        public Product(Long id, String name) {
-            this.id = id;
-            this.name = name;
-        }
-
-        public Long getId() {
-            return id;
-        }
-
-        public void setId(Long id) {
-            this.id = id;
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public void setName(String name) {
-            this.name = name;
-        }
-    }
-
-    public class Category {
-        private String name;
-        private List<Product> products = new ArrayList<>();
-
-        public Category() {
-        }
-
-        public Category(String name, Product... products) {
-            this.name = name;
-            this.products = Arrays.asList(products);
-        }
-
-        public String getName() {
-            return name;
-        }
-
-        public void setName(String name) {
-            this.name = name;
-        }
-
-        public List<Product> getProducts() {
-            return products;
-        }
-    }
-}
+/*
+ * 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.view.facelets.tag.faces.html;
+
+import jakarta.annotation.PostConstruct;
+import jakarta.enterprise.context.RequestScoped;
+import jakarta.inject.Named;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@Named
+@RequestScoped
+public class SelectOneItemsTestBean {
+
+    private List<Category> categories = new ArrayList<>();
+    private Long selectedProductId;
+
+    @PostConstruct
+    public void init() {
+        categories.add(new Category("Animals", new Product(1L, "Dog"), new Product(2L, "Cat"), new Product(3L, "Fish")));
+        categories.add(new Category("Cars", new Product(4L, "Alfa"), new Product(5L, "Audi"), new Product(6L, "BMW")));
+    }
+
+    public List<Category> getCategories() {
+        return categories;
+    }
+
+    public Long getSelectedProductId() {
+        return selectedProductId;
+    }
+
+    public void setSelectedProductId(Long selectedProductId) {
+        this.selectedProductId = selectedProductId;
+    }
+
+    public static class Product {
+        private Long id;
+        private String name;
+
+        public Product() {
+        }
+
+        public Product(Long id, String name) {
+            this.id = id;
+            this.name = name;
+        }
+
+        public Long getId() {
+            return id;
+        }
+
+        public void setId(Long id) {
+            this.id = id;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+    }
+
+    public class Category {
+        private String name;
+        private List<Product> products = new ArrayList<>();
+
+        public Category() {
+        }
+
+        public Category(String name, Product... products) {
+            this.name = name;
+            this.products = Arrays.asList(products);
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        public List<Product> getProducts() {
+            return products;
+        }
+    }
+}
