You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2013/11/10 01:12:41 UTC

svn commit: r1540431 - in /myfaces/core/trunk/impl/src: main/java/org/apache/myfaces/view/facelets/ main/java/org/apache/myfaces/view/facelets/impl/ main/java/org/apache/myfaces/view/facelets/tag/jsf/ main/java/org/apache/myfaces/view/facelets/tag/jstl...

Author: lu4242
Date: Sun Nov 10 00:12:40 2013
New Revision: 1540431

URL: http://svn.apache.org/r1540431
Log:
MYFACES-3811 Fix c:forEach behavior once for all

Added:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/IterationState.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/LegacyForEachHandler.java
      - copied, changed from r1539924, myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ForEachHandler.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/managed/ForEachBean.java   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/forEach1.xhtml
      - copied, changed from r1539924, myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/componentBinding1.xhtml
Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentSupport.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ForEachHandler.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/LegacyJstlCoreLibrary.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/AcidMyFacesRequestTestCase.java

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java?rev=1540431&r1=1540430&r2=1540431&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletCompositionContext.java Sun Nov 10 00:12:40 2013
@@ -451,6 +451,27 @@ abstract public class FaceletComposition
     }
     
     /**
+     * Start a new unique id section, which means a new counter is used to
+     * generate unique ids to components, but appending a base to the
+     * new counter.
+     * 
+     * @since 2.2.0
+     * @return
+     */
+    public String startComponentUniqueIdSection(String base)
+    {
+        return null;
+    }
+    
+    /**
+     * @since 2.2.0
+     * @param base 
+     */
+    public void endComponentUniqueIdSection(String base)
+    {
+    }
+    
+    /**
      * Generate a unique id that will be used later to derive a unique id per tag
      * by FaceletContext.generateUniqueId(). This generator ensures uniqueness per
      * view but FaceletContext.generateUniqueId() ensures uniqueness per view and

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java?rev=1540431&r1=1540430&r2=1540431&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/FaceletCompositionContextImpl.java Sun Nov 10 00:12:40 2013
@@ -1015,6 +1015,13 @@ public class FaceletCompositionContextIm
         _sectionUniqueComponentIdCounter.startUniqueIdSection();
         return _sectionUniqueIdCounter.startUniqueIdSection();
     }
+    
+    public String startComponentUniqueIdSection(String base)
+    {
+        _level++;
+        _sectionUniqueComponentIdCounter.startUniqueIdSection(base);
+        return _sectionUniqueIdCounter.startUniqueIdSection(base);
+    }
 
     @Override
     public void incrementUniqueId()
@@ -1053,6 +1060,13 @@ public class FaceletCompositionContextIm
         _sectionUniqueComponentIdCounter.endUniqueIdSection();
     }
     
+    public void endComponentUniqueIdSection(String base)
+    {
+        _level--;
+        _sectionUniqueIdCounter.endUniqueIdSection(base);
+        _sectionUniqueComponentIdCounter.endUniqueIdSection(base);
+    }
+    
     @Override
     public void startMetadataSection()
     {

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java?rev=1540431&r1=1540430&r2=1540431&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/impl/SectionUniqueIdCounter.java Sun Nov 10 00:12:40 2013
@@ -202,6 +202,19 @@ public class SectionUniqueIdCounter
         }
     }
     
+    public void endUniqueIdSection(String base)
+    {
+        if (_activeSection <= 0)
+        {
+            return;
+        }
+        else
+        {
+            _counterStack.remove(_activeSection);
+            _activeSection--;
+        }
+    }
+    
     private static class Section
     {
         

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentSupport.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentSupport.java?rev=1540431&r1=1540430&r2=1540431&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentSupport.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/ComponentSupport.java Sun Nov 10 00:12:40 2013
@@ -785,6 +785,18 @@ public final class ComponentSupport
         }
     }
     
+    public static FaceletState getFaceletState(FaceletContext ctx, UIComponent parent, boolean create)
+    {
+        UIViewRoot root = getViewRoot(ctx, parent);
+        FaceletState map = (FaceletState) root.getAttributes().get(FACELET_STATE_INSTANCE);
+        if (map == null && create)
+        {
+            map = new FaceletState();
+            root.getAttributes().put(FACELET_STATE_INSTANCE, map);
+        }
+        return map;
+    }
+    
     public static void setCachedFacesContext(UIComponent component,
         FacesContext context)
     {

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ForEachHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ForEachHandler.java?rev=1540431&r1=1540430&r2=1540431&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ForEachHandler.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ForEachHandler.java Sun Nov 10 00:12:40 2013
@@ -19,6 +19,7 @@
 package org.apache.myfaces.view.facelets.tag.jstl.core;
 
 import java.io.IOException;
+import java.io.Serializable;
 import java.lang.reflect.Array;
 import java.util.Collection;
 import java.util.Iterator;
@@ -28,7 +29,9 @@ import java.util.Map;
 import javax.el.ELException;
 import javax.el.ValueExpression;
 import javax.faces.FacesException;
+import javax.faces.application.StateManager;
 import javax.faces.component.UIComponent;
+import javax.faces.event.PhaseId;
 import javax.faces.view.facelets.FaceletContext;
 import javax.faces.view.facelets.FaceletException;
 import javax.faces.view.facelets.TagAttribute;
@@ -43,6 +46,7 @@ import org.apache.myfaces.view.facelets.
 import org.apache.myfaces.view.facelets.PageContext;
 import org.apache.myfaces.view.facelets.tag.ComponentContainerHandler;
 import org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport;
+import org.apache.myfaces.view.facelets.tag.jsf.FaceletState;
 
 /**
  * The basic iteration tag, accepting many different
@@ -168,15 +172,7 @@ public final class ForEachHandler extend
     public void apply(FaceletContext ctx, UIComponent parent) throws IOException, FacesException, FaceletException,
             ELException
     {
-
-        int s = this.getBegin(ctx);
         int e = this.getEnd(ctx);
-        int m = this.getStep(ctx);
-        Integer sO = this.begin != null ? Integer.valueOf(s) : null;
-        Integer eO = this.end != null ? Integer.valueOf(e) : null;
-        Integer mO = this.step != null ? Integer.valueOf(m) : null;
-
-        boolean t = this.getTransient(ctx);
         Object src = null;
         ValueExpression srcVE = null;
         if (this.items != null)
@@ -194,132 +190,446 @@ public final class ForEachHandler extend
             src = b;
         }
         FaceletCompositionContext fcc = FaceletCompositionContext.getCurrentInstance(ctx);
+        // Just increment one number to ensure the prefix doesn't conflict later if two
+        // c:forEach are close between each other. Note c:forEach is different from
+        // c:if tag and doesn't require a section because c:forEach requires to provide
+        // multiple sections starting with a specified "base" related to the element
+        // position and value in the collection.
+        fcc.incrementUniqueComponentId();
+        String uniqueId = fcc.generateUniqueId();
         if (src != null)
         {
-            fcc.startComponentUniqueIdSection();
             AbstractFaceletContext actx = (AbstractFaceletContext) ctx;
             PageContext pctx = actx.getPageContext();
-            Iterator<?> itr = this.toIterator(src);
-            if (itr != null)
+            // c:forEach is special because it requires FaceletState even if no pss is used.
+            FaceletState restoredFaceletState = ComponentSupport.getFaceletState(ctx, parent, false);
+            IterationState restoredSavedOption = (restoredFaceletState == null) ? null : 
+                (IterationState) restoredFaceletState.getState(uniqueId);
+
+            if (restoredSavedOption != null)
+            {            
+                if (!PhaseId.RESTORE_VIEW.equals(ctx.getFacesContext().getCurrentPhaseId()))
+                {
+                    // Refresh, evaluate and synchronize state
+                    applyOnRefresh(ctx, fcc, pctx, parent, uniqueId, src, srcVE, restoredSavedOption);
+                }
+                else
+                {
+                    // restore view, don't record iteration, use the saved value
+                    applyOnRestore(ctx, fcc, pctx, parent, uniqueId, src, srcVE, restoredSavedOption);
+                }
+            }
+            else
             {
-                int i = 0;
+                // First time         
+                applyFirstTime(ctx, fcc, pctx, parent, uniqueId, src, srcVE);
+            }
+        }
 
-                // move to start
-                while (i < s && itr.hasNext())
+        if (fcc.isUsingPSSOnThisView() && fcc.isRefreshTransientBuildOnPSS() && !fcc.isRefreshingTransientBuild())
+        {
+            //Mark the parent component to be saved and restored fully.
+            ComponentSupport.markComponentToRestoreFully(ctx.getFacesContext(), parent);
+        }
+        if (fcc.isDynamicComponentSection())
+        {
+            ComponentSupport.markComponentToRefreshDynamically(ctx.getFacesContext(), parent);
+        }
+    }
+    
+    private void setVar(FaceletContext ctx, PageContext pctx, boolean t, Object src, 
+        ValueExpression srcVE, Object value, String v, int i)
+    {
+        // set the var
+        if (v != null)
+        {
+            if (t || srcVE == null)
+            {
+                if (value == null)
                 {
-                    itr.next();
-                    i++;
+                    pctx.getAttributes().put(v, null);
                 }
+                else
+                {
+                    pctx.getAttributes().put(v, 
+                            ctx.getExpressionFactory().createValueExpression(
+                                value, Object.class));
+                }
+            }
+            else
+            {
+                ValueExpression ve = this.getVarExpr(srcVE, src, value, i);
+                pctx.getAttributes().put(v, ve);
+            }
+        }
+    }
+    
+    private void applyFirstTime(FaceletContext ctx, FaceletCompositionContext fcc, PageContext pctx, 
+        UIComponent parent, String uniqueId, Object src, ValueExpression srcVE) throws IOException
+    {
+        int s = this.getBegin(ctx);
+        int e = this.getEnd(ctx);
+        int m = this.getStep(ctx);
+        Integer sO = this.begin != null ? Integer.valueOf(s) : null;
+        Integer eO = this.end != null ? Integer.valueOf(e) : null;
+        Integer mO = this.step != null ? Integer.valueOf(m) : null;
+        boolean t = this.getTransient(ctx);
+        IterationState iterationState = new IterationState();
+
+        boolean serializableValues = true;
+        Iterator<?> itr = this.toIterator(src);
+        if (itr != null)
+        {
+            int i = 0;
+
+            // move to start
+            while (i < s && itr.hasNext())
+            {
+                itr.next();
+                i++;
+            }
 
-                String v = this.getVarName(ctx);
-                String vs = this.getVarStatusName(ctx);
-                ValueExpression ve = null;
-                ValueExpression vO = this.capture(v, pctx);
-                ValueExpression vsO = this.capture(vs, pctx);
-                int mi = 0;
-                Object value = null;
-                try
+            String v = this.getVarName(ctx);
+            String vs = this.getVarStatusName(ctx);
+            ValueExpression vO = this.capture(v, pctx);
+            ValueExpression vsO = this.capture(vs, pctx);
+            int mi = 0;
+            Object value = null;
+            try
+            {
+                boolean first = true;
+                while (i <= e && itr.hasNext())
                 {
-                    boolean first = true;
-                    while (i <= e && itr.hasNext())
+                    value = itr.next();
+
+                    // first time, use the counter
+                    Integer count = iterationState.getCounter();
+                    String base = count.toString();
+                    iterationState.setCounter(count+1);
+
+                    if (value instanceof Serializable)
+                    {
+                        iterationState.getValueList().add(
+                            new Object[]{base, value, i});
+                    }
+                    else
                     {
-                        value = itr.next();
+                        serializableValues = false;
+                    }
+
+                    fcc.startComponentUniqueIdSection(base);
 
-                        // set the var
-                        if (v != null)
+                    setVar(ctx, pctx, t, src, srcVE, value, v, i);
+                    boolean last = !itr.hasNext();
+                    // set the varStatus
+                    if (vs != null)
+                    {
+                        IterationStatus itrS = new IterationStatus(first, last, i, sO, eO, mO, value);
+                        if (t || srcVE == null)
                         {
-                            if (t || srcVE == null)
+                            if (srcVE == null)
                             {
-                                if (value == null)
-                                {
-                                    pctx.getAttributes().put(v, null);
-                                }
-                                else
-                                {
-                                    pctx.getAttributes().put(v, 
-                                            ctx.getExpressionFactory().createValueExpression(
-                                                value, Object.class));
-                                }
+                                pctx.getAttributes().put(vs, null);
                             }
                             else
                             {
-                                ve = this.getVarExpr(srcVE, src, value, i);
-                                pctx.getAttributes().put(v, ve);
+                                pctx.getAttributes().put(vs, 
+                                        ctx.getExpressionFactory().createValueExpression(
+                                            itrS, Object.class));
                             }
                         }
-
-                        // set the varStatus
-                        if (vs != null)
+                        else
                         {
-                            IterationStatus itrS = new IterationStatus(first, !itr.hasNext(), i, sO, eO, mO, value);
-                            if (t || srcVE == null)
-                            {
-                                if (srcVE == null)
-                                {
-                                    pctx.getAttributes().put(vs, null);
-                                }
-                                else
-                                {
-                                    pctx.getAttributes().put(vs, 
-                                            ctx.getExpressionFactory().createValueExpression(
-                                                itrS, Object.class));
-                                }
-                            }
-                            else
-                            {
-                                ve = new IterationStatusExpression(itrS);
-                                pctx.getAttributes().put(vs, ve);
-                            }
+                            ValueExpression ve = new IterationStatusExpression(itrS);
+                            pctx.getAttributes().put(vs, ve);
                         }
+                    }
 
-                        // execute body
-                        this.nextHandler.apply(ctx, parent);
+                    // execute body
+                    this.nextHandler.apply(ctx, parent);
 
-                        // increment steps
-                        mi = 1;
-                        while (mi < m && itr.hasNext())
-                        {
-                            itr.next();
-                            mi++;
-                            i++;
-                        }
+                    fcc.endComponentUniqueIdSection(base);
+
+                    // increment steps
+                    mi = 1;
+                    while (mi < m && itr.hasNext())
+                    {
+                        itr.next();
+                        mi++;
                         i++;
+                    }
+                    i++;
+
+                    first = false;
+                }
+            }
+            finally
+            {
+                removeVarAndVarStatus(pctx, v, vO, vs, vsO);
+            }
+        }
+        if (serializableValues)
+        {
+            FaceletState faceletState = ComponentSupport.getFaceletState(ctx, parent, true);
+            faceletState.putState(uniqueId, iterationState);
+        }
+    }
+    
+    private void applyOnRestore(FaceletContext ctx, FaceletCompositionContext fcc, PageContext pctx, 
+        UIComponent parent, String uniqueId, Object src, ValueExpression srcVE, IterationState restoredSavedOption)
+        throws IOException
+    {
+        int s = this.getBegin(ctx);
+        int e = this.getEnd(ctx);
+        int m = this.getStep(ctx);
+        Integer sO = this.begin != null ? Integer.valueOf(s) : null;
+        Integer eO = this.end != null ? Integer.valueOf(e) : null;
+        Integer mO = this.step != null ? Integer.valueOf(m) : null;
+        boolean t = this.getTransient(ctx);
 
-                        first = false;
+        // restore view, don't record iteration, use the saved value
+        String v = this.getVarName(ctx);
+        String vs = this.getVarStatusName(ctx);
+        ValueExpression vO = this.capture(v, pctx);
+        ValueExpression vsO = this.capture(vs, pctx);
+        Object value = null;
+        try
+        {
+            int size = restoredSavedOption.getValueList().size();
+            for (int si = 0; si < size; si++)
+            {
+                Object[] stateValue = restoredSavedOption.getValueList().get(si);
+                value = stateValue[1];
+                String base = (String) stateValue[0];
+
+                fcc.startComponentUniqueIdSection(base);
+
+                setVar(ctx, pctx, t, src, srcVE, value, v, (Integer) stateValue[2]);
+                
+                boolean first = (si == 0);
+                boolean last = (si == size-1);
+                int i = (Integer)stateValue[2];
+                // set the varStatus
+                if (vs != null)
+                {
+                    IterationStatus itrS = new IterationStatus(first, last, i, sO, eO, mO, value);
+                    if (t || srcVE == null)
+                    {
+                        if (srcVE == null)
+                        {
+                            pctx.getAttributes().put(vs, null);
+                        }
+                        else
+                        {
+                            pctx.getAttributes().put(vs, 
+                                    ctx.getExpressionFactory().createValueExpression(
+                                        itrS, Object.class));
+                        }
+                    }
+                    else
+                    {
+                        ValueExpression ve = new IterationStatusExpression(itrS);
+                        pctx.getAttributes().put(vs, ve);
                     }
                 }
-                finally
+
+                // execute body
+                this.nextHandler.apply(ctx, parent);
+
+                fcc.endComponentUniqueIdSection(base);
+            }
+        }
+        finally
+        {
+            removeVarAndVarStatus(pctx, v, vO, vs, vsO);
+        }
+    }
+    
+    private void applyOnRefresh(FaceletContext ctx, FaceletCompositionContext fcc, PageContext pctx, 
+        UIComponent parent, String uniqueId, Object src, ValueExpression srcVE, IterationState restoredSavedOption)
+        throws IOException
+    {
+        int s = this.getBegin(ctx);
+        int e = this.getEnd(ctx);
+        int m = this.getStep(ctx);
+        Integer sO = this.begin != null ? Integer.valueOf(s) : null;
+        Integer eO = this.end != null ? Integer.valueOf(e) : null;
+        Integer mO = this.step != null ? Integer.valueOf(m) : null;
+        boolean t = this.getTransient(ctx);
+
+        // Refresh, evaluate and synchronize state
+        Iterator<?> itr = this.toIterator(src);
+        IterationState iterationState = new IterationState();
+        iterationState.setCounter(restoredSavedOption.getCounter());
+        if (itr != null)
+        {
+            int i = 0;
+
+            // move to start
+            while (i < s && itr.hasNext())
+            {
+                itr.next();
+                i++;
+            }
+
+            String v = this.getVarName(ctx);
+            String vs = this.getVarStatusName(ctx);
+            ValueExpression vO = this.capture(v, pctx);
+            ValueExpression vsO = this.capture(vs, pctx);
+            int mi = 0;
+            Object value = null;
+            int stateIndex = 0;
+            try
+            {
+                boolean first = true;
+                while (i <= e && itr.hasNext())
                 {
-                    //Remove them from PageContext
-                    if (v != null)
+                    value = itr.next();
+                    Object[] stateValue = null; /*restoredSavedOption.getValueList().get(stateIndex);*/
+                    String base = null;
+                    boolean found = false;
+
+                    // The important thing here is use the same base for the generated component ids
+                    // for each element in the iteration that was used on the restore. To do that
+                    // 
+                    int stateIndexCheck = stateIndex;
+                    for (; stateIndexCheck < restoredSavedOption.getValueList().size(); stateIndexCheck++)
+                    {
+                        stateValue = restoredSavedOption.getValueList().get(stateIndexCheck);
+                        if (value.equals(stateValue[1]))
+                        {
+                            found = true;
+                            break;
+                        }
+                    }
+                    if (found)
                     {
-                        pctx.getAttributes().put(v, vO);
+                        stateIndex = stateIndexCheck;
+                        base = (String) stateValue[0];
+                        stateIndex++;
                     }
                     else
                     {
-                        pctx.getAttributes().remove(v);
+                        // No state, added item, create new count
+                        Integer count = iterationState.getCounter();
+                        base = count.toString();
+                        iterationState.setCounter(count+1);
+                        stateValue = null;
+                    }
+
+                    if (value instanceof Serializable)
+                    {
+                        iterationState.getValueList().add(
+                            new Object[]{base, value, i});
                     }
+
+                    fcc.startComponentUniqueIdSection(base);
+
+                    setVar(ctx, pctx, t, src, srcVE, value, v, i);
+
+                    boolean last = !itr.hasNext();
+                    // set the varStatus
                     if (vs != null)
                     {
-                        pctx.getAttributes().put(vs, vsO);
+                        IterationStatus itrS = new IterationStatus(first, last, i, sO, eO, mO, value);
+                        if (t || srcVE == null)
+                        {
+                            if (srcVE == null)
+                            {
+                                pctx.getAttributes().put(vs, null);
+                            }
+                            else
+                            {
+                                pctx.getAttributes().put(vs, 
+                                        ctx.getExpressionFactory().createValueExpression(
+                                            itrS, Object.class));
+                            }
+                        }
+                        else
+                        {
+                            ValueExpression ve = new IterationStatusExpression(itrS);
+                            pctx.getAttributes().put(vs, ve);
+                        }
                     }
-                    else
+                    //setVarStatus(ctx, pctx, t, sO, eO, mO, srcVE, value, vs, first, !itr.hasNext(), i);
+
+                    // execute body
+                    boolean markInitialState = (stateValue == null);// !restoredSavedOption.equals(i)
+                    boolean oldMarkInitialState = false;
+                    Boolean isBuildingInitialState = null;
+                    try
+                    {
+                        if (markInitialState && fcc.isUsingPSSOnThisView())
+                        {
+                            //set markInitialState flag
+                            oldMarkInitialState = fcc.isMarkInitialState();
+                            fcc.setMarkInitialState(true);
+                            isBuildingInitialState = (Boolean) ctx.getFacesContext().getAttributes().put(
+                                    StateManager.IS_BUILDING_INITIAL_STATE, Boolean.TRUE);
+                        }                                
+                        this.nextHandler.apply(ctx, parent);
+                    }
+                    finally
+                    {
+                        if (markInitialState && fcc.isUsingPSSOnThisView())
+                        {
+                            //unset markInitialState flag
+                            if (isBuildingInitialState == null)
+                            {
+                                ctx.getFacesContext().getAttributes().remove(
+                                        StateManager.IS_BUILDING_INITIAL_STATE);
+                            }
+                            else
+                            {
+                                ctx.getFacesContext().getAttributes().put(
+                                        StateManager.IS_BUILDING_INITIAL_STATE, isBuildingInitialState);
+                            }
+                            fcc.setMarkInitialState(oldMarkInitialState);
+                        }
+                    }
+
+                    fcc.endComponentUniqueIdSection(base);
+
+                    // increment steps
+                    mi = 1;
+                    while (mi < m && itr.hasNext())
                     {
-                        pctx.getAttributes().remove(vs);
+                        itr.next();
+                        mi++;
+                        i++;
                     }
+                    i++;
+
+                    first = false;
                 }
             }
-            fcc.endComponentUniqueIdSection();
+            finally
+            {
+                removeVarAndVarStatus(pctx, v, vO, vs, vsO);
+            }
         }
-
-        if (fcc.isUsingPSSOnThisView() && fcc.isRefreshTransientBuildOnPSS() && !fcc.isRefreshingTransientBuild())
+        FaceletState faceletState = ComponentSupport.getFaceletState(ctx, parent, true);
+        faceletState.putState(uniqueId, iterationState);
+    }
+    
+    private void removeVarAndVarStatus(PageContext pctx, String v, ValueExpression vO, String vs, ValueExpression vsO)
+    {
+        //Remove them from PageContext
+        if (v != null)
         {
-            //Mark the parent component to be saved and restored fully.
-            ComponentSupport.markComponentToRestoreFully(ctx.getFacesContext(), parent);
+            pctx.getAttributes().put(v, vO);
         }
-        if (fcc.isDynamicComponentSection())
+        else
         {
-            ComponentSupport.markComponentToRefreshDynamically(ctx.getFacesContext(), parent);
+            pctx.getAttributes().remove(v);
+        }
+        if (vs != null)
+        {
+            pctx.getAttributes().put(vs, vsO);
+        }
+        else
+        {
+            pctx.getAttributes().remove(vs);
         }
     }
 
@@ -372,7 +682,8 @@ public final class ForEachHandler extend
     {
         if (src instanceof List || src.getClass().isArray())
         {
-            return new IndexedValueExpression(ve, i);
+            //return new IndexedValueExpression(ve, i);
+            return new IteratedValueExpression(ve, value);
         }
         else if (src instanceof Map && value instanceof Map.Entry)
         {

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/IterationState.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/IterationState.java?rev=1540431&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/IterationState.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/IterationState.java Sun Nov 10 00:12:40 2013
@@ -0,0 +1,109 @@
+/*
+ * 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.jstl.core;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Holds the iteration state generated by c:forEach tag.
+ */
+public class IterationState implements Serializable
+{
+    /**
+     * This counter is used to generate an unique base per element
+     * in the collection that will be used later in the id
+     * generation algorithm.
+     */
+    private int counter;
+    
+    private List<Object[]> valueList;
+    
+    public IterationState()
+    {
+        this.valueList = new ArrayList<Object[]>();
+    }
+
+    /**
+     * @return the valueList
+     */
+    public List<Object[]> getValueList()
+    {
+        return valueList;
+    }
+
+    /**
+     * @param valueList the valueList to set
+     */
+    public void setValueList(List<Object[]> valueList)
+    {
+        this.valueList = valueList;
+    }
+
+    /**
+     * @return the counter
+     */
+    public int getCounter()
+    {
+        return counter;
+    }
+
+    /**
+     * @param counter the counter to set
+     */
+    public void setCounter(int counter)
+    {
+        this.counter = counter;
+    }
+    
+    public Iterator getIterator()
+    {
+        return new IteratorWrapper(valueList.iterator());
+    }
+
+    private static class IteratorWrapper implements Iterator
+    {
+        private Iterator<Object[]> delegate;
+
+        public IteratorWrapper(Iterator<Object[]> delegate)
+        {
+            this.delegate = delegate;
+        }
+
+        @Override
+        public boolean hasNext()
+        {
+            return delegate.hasNext();
+        }
+
+        @Override
+        public Object next()
+        {
+            return delegate.next()[1];
+        }
+
+        @Override
+        public void remove()
+        {
+            delegate.remove();
+        }
+    }
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/IterationState.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/LegacyForEachHandler.java (from r1539924, myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ForEachHandler.java)
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/LegacyForEachHandler.java?p2=myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/LegacyForEachHandler.java&p1=myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ForEachHandler.java&r1=1539924&r2=1540431&rev=1540431&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/ForEachHandler.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/LegacyForEachHandler.java Sun Nov 10 00:12:40 2013
@@ -36,8 +36,6 @@ import javax.faces.view.facelets.TagAttr
 import javax.faces.view.facelets.TagConfig;
 import javax.faces.view.facelets.TagHandler;
 
-import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletAttribute;
-import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFaceletTag;
 import org.apache.myfaces.view.facelets.AbstractFaceletContext;
 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
 import org.apache.myfaces.view.facelets.PageContext;
@@ -49,12 +47,17 @@ import org.apache.myfaces.view.facelets.
  * collection types and supporting subsetting and other
  * functionality
  * 
+ * NOTE: This implementation is provided for compatibility reasons and
+ * it is considered faulty. It is enabled using
+ * org.apache.myfaces.STRICT_JSF_2_FACELETS_COMPATIBILITY web config param.
+ * Don't use it if EL expression caching is enabled.
+ * 
  * @author Jacob Hookom
  * @author Andrew Robinson
  * @version $Id$
  */
-@JSFFaceletTag(name="c:forEach")
-public final class ForEachHandler extends TagHandler implements ComponentContainerHandler
+//@JSFFaceletTag(name="c:forEach")
+public final class LegacyForEachHandler extends TagHandler implements ComponentContainerHandler
 {
 
     private static class ArrayIterator implements Iterator<Object>
@@ -98,7 +101,7 @@ public final class ForEachHandler extend
      * Iteration begins with index set at the value
      * specified.
      */
-    @JSFFaceletAttribute(className="int")
+    //@JSFFaceletAttribute(className="int")
     private final TagAttribute begin;
 
     /**
@@ -109,20 +112,20 @@ public final class ForEachHandler extend
      * Iteration ends when index reaches the value
      * specified.
      */
-    @JSFFaceletAttribute(className="int")
+    //@JSFFaceletAttribute(className="int")
     private final TagAttribute end;
 
     /**
      * Collection of items to iterate over.
      */
-    @JSFFaceletAttribute(className="javax.el.ValueExpression")
+    //@JSFFaceletAttribute(className="javax.el.ValueExpression")
     private final TagAttribute items;
 
     /**
      * Iteration will only process every step items of
      * the collection, starting with the first one.
      */
-    @JSFFaceletAttribute(className="int")
+    //@JSFFaceletAttribute(className="int")
     private final TagAttribute step;
 
     private final TagAttribute tranzient;
@@ -133,20 +136,20 @@ public final class ForEachHandler extend
      * variable has nested visibility. Its type depends
      * on the object of the underlying collection.
      */
-    @JSFFaceletAttribute(className="java.lang.String")
+    //@JSFFaceletAttribute(className="java.lang.String")
     private final TagAttribute var;
 
     /**
      * Name of the exported scoped variable for the
      * status of the iteration. 
      */
-    @JSFFaceletAttribute(className="java.lang.String")
+    //@JSFFaceletAttribute(className="java.lang.String")
     private final TagAttribute varStatus;
 
     /**
      * @param config
      */
-    public ForEachHandler(TagConfig config)
+    public LegacyForEachHandler(TagConfig config)
     {
         super(config);
         this.items = this.getAttribute("items");

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/LegacyJstlCoreLibrary.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/LegacyJstlCoreLibrary.java?rev=1540431&r1=1540430&r2=1540431&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/LegacyJstlCoreLibrary.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jstl/core/LegacyJstlCoreLibrary.java Sun Nov 10 00:12:40 2013
@@ -49,7 +49,7 @@ public final class LegacyJstlCoreLibrary
 
         this.addTagHandler("if", IfHandler.class);
 
-        this.addTagHandler("forEach", ForEachHandler.class);
+        this.addTagHandler("forEach", LegacyForEachHandler.class);
 
         this.addTagHandler("catch", CatchHandler.class);
 
@@ -68,7 +68,7 @@ public final class LegacyJstlCoreLibrary
 
         this.addTagHandler("if", IfHandler.class);
 
-        this.addTagHandler("forEach", ForEachHandler.class);
+        this.addTagHandler("forEach", LegacyForEachHandler.class);
 
         this.addTagHandler("catch", CatchHandler.class);
 

Modified: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java?rev=1540431&r1=1540430&r2=1540431&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java Sun Nov 10 00:12:40 2013
@@ -75,8 +75,6 @@ import org.apache.myfaces.test.el.MockEx
 import org.apache.myfaces.test.mock.MockPrintWriter;
 import org.apache.myfaces.test.mock.MockServletConfig;
 import org.apache.myfaces.test.mock.MockServletContext;
-import org.apache.myfaces.util.DebugUtils;
-import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage;
 import org.apache.myfaces.webapp.AbstractFacesInitializer;
 import org.apache.myfaces.webapp.StartupServletContextListener;
 import org.junit.After;

Modified: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/AcidMyFacesRequestTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/AcidMyFacesRequestTestCase.java?rev=1540431&r1=1540430&r2=1540431&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/AcidMyFacesRequestTestCase.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/AcidMyFacesRequestTestCase.java Sun Nov 10 00:12:40 2013
@@ -23,6 +23,7 @@ import javax.faces.application.StateMana
 import javax.faces.component.UICommand;
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIInput;
+import javax.faces.component.UIOutput;
 import javax.faces.component.UIPanel;
 import javax.faces.component.html.HtmlDataTable;
 
@@ -31,6 +32,7 @@ import org.apache.myfaces.shared.config.
 import org.apache.myfaces.test.mock.MockPrintWriter;
 import org.apache.myfaces.view.facelets.pss.acid.managed.CheckActionEventBean;
 import org.apache.myfaces.view.facelets.pss.acid.managed.CustomSessionBean;
+import org.apache.myfaces.view.facelets.pss.acid.managed.ForEachBean;
 import org.apache.myfaces.view.facelets.pss.acid.managed.ResourceDependencyBean;
 import org.junit.Assert;
 import org.junit.Test;
@@ -1741,4 +1743,99 @@ public class AcidMyFacesRequestTestCase 
         tearDownRequest();
     }
 
+    @Test
+    public void testCForEach1() throws Exception
+    {
+        setupRequest("/forEach1.xhtml");
+        processLifecycleExecute();
+        
+        executeBeforeRender(facesContext);
+        executeBuildViewCycle(facesContext);
+        
+        UIOutput itemA_1 = (UIOutput) facesContext.getViewRoot().findComponent("mainForm:item_a");
+        Assert.assertNotNull(itemA_1);
+        Assert.assertEquals("a", itemA_1.getValue());
+        itemA_1.getAttributes().put("prop", "a");
+        UIOutput itemB_1 = (UIOutput) facesContext.getViewRoot().findComponent("mainForm:item_b");
+        Assert.assertNotNull(itemB_1);
+        Assert.assertEquals("b", itemB_1.getValue());
+        itemB_1.getAttributes().put("prop", "b");
+        UIOutput itemC_1 = (UIOutput) facesContext.getViewRoot().findComponent("mainForm:item_c");
+        Assert.assertNotNull(itemC_1);
+        Assert.assertEquals("c", itemC_1.getValue());
+        itemC_1.getAttributes().put("prop", "c");
+        
+        executeViewHandlerRender(facesContext);
+        
+        UICommand button = (UICommand) facesContext.getViewRoot().findComponent("mainForm:postback");
+        submit(button);
+        
+        processLifecycleExecute();
+
+        UIOutput itemA_2 = (UIOutput) facesContext.getViewRoot().findComponent("mainForm:item_a");
+        Assert.assertNotNull(itemA_2);
+        Assert.assertEquals("a", itemA_2.getValue());
+        Assert.assertEquals("a", itemA_2.getAttributes().get("prop"));
+        UIOutput itemB_2 = (UIOutput) facesContext.getViewRoot().findComponent("mainForm:item_b");
+        Assert.assertNotNull(itemB_2);
+        Assert.assertEquals("b", itemB_2.getValue());
+        Assert.assertEquals("b", itemB_2.getAttributes().get("prop"));
+        UIOutput itemC_2 = (UIOutput) facesContext.getViewRoot().findComponent("mainForm:item_c");
+        Assert.assertNotNull(itemC_2);
+        Assert.assertEquals("c", itemC_2.getValue());
+        Assert.assertEquals("c", itemC_2.getAttributes().get("prop"));
+
+        ForEachBean bean = facesContext.getApplication().evaluateExpressionGet(facesContext, "#{forEachBean}", 
+            ForEachBean.class);
+        bean.addFirst();
+        bean.addMiddle();
+        bean.removeLast();
+        
+        executeBeforeRender(facesContext);
+        executeBuildViewCycle(facesContext);
+
+        UIOutput itemA_3 = (UIOutput) facesContext.getViewRoot().findComponent("mainForm:item_a");
+        Assert.assertNotNull(itemA_3);
+        Assert.assertEquals("a", itemA_3.getValue());
+        Assert.assertEquals("a", itemA_3.getAttributes().get("prop"));
+        UIOutput itemB_3 = (UIOutput) facesContext.getViewRoot().findComponent("mainForm:item_b");
+        Assert.assertNotNull(itemB_3);
+        Assert.assertEquals("b", itemB_3.getValue());
+        Assert.assertEquals("b", itemB_3.getAttributes().get("prop"));
+        UIOutput itemC_3 = (UIOutput) facesContext.getViewRoot().findComponent("mainForm:item_c");
+        Assert.assertNull(itemC_3);
+        UIOutput itemZ_3 = (UIOutput) facesContext.getViewRoot().findComponent("mainForm:item_z");
+        Assert.assertNotNull(itemZ_3);
+        Assert.assertEquals("z", itemZ_3.getValue());
+        Assert.assertNull(itemZ_3.getAttributes().get("prop"));
+        UIOutput itemX_3 = (UIOutput) facesContext.getViewRoot().findComponent("mainForm:item_x");
+        Assert.assertNotNull(itemX_3);
+        Assert.assertEquals("x", itemX_3.getValue());
+        Assert.assertNull(itemX_3.getAttributes().get("prop"));
+        
+        executeViewHandlerRender(facesContext);
+
+        UICommand button2 = (UICommand) facesContext.getViewRoot().findComponent("mainForm:postback");
+        submit(button2);
+        
+        processLifecycleExecute();
+
+        UIOutput itemA_4 = (UIOutput) facesContext.getViewRoot().findComponent("mainForm:item_a");
+        Assert.assertNotNull(itemA_4);
+        Assert.assertEquals("a", itemA_4.getValue());
+        UIOutput itemB_4 = (UIOutput) facesContext.getViewRoot().findComponent("mainForm:item_b");
+        Assert.assertNotNull(itemB_4);
+        Assert.assertEquals("b", itemB_4.getValue());
+        UIOutput itemC_4 = (UIOutput) facesContext.getViewRoot().findComponent("mainForm:item_c");
+        Assert.assertNull(itemC_4);
+        UIOutput itemZ_4 = (UIOutput) facesContext.getViewRoot().findComponent("mainForm:item_z");
+        Assert.assertNotNull(itemZ_4);
+        Assert.assertEquals("z", itemZ_4.getValue());
+        UIOutput itemX_4 = (UIOutput) facesContext.getViewRoot().findComponent("mainForm:item_x");
+        Assert.assertNotNull(itemX_4);
+        Assert.assertEquals("x", itemX_4.getValue());
+
+        tearDownRequest();
+    }
+
 }

Added: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/managed/ForEachBean.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/managed/ForEachBean.java?rev=1540431&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/managed/ForEachBean.java (added)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/managed/ForEachBean.java Sun Nov 10 00:12:40 2013
@@ -0,0 +1,66 @@
+/*
+ * 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.pss.acid.managed;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.PostConstruct;
+import javax.faces.bean.ManagedBean;
+import javax.faces.bean.SessionScoped;
+
+/**
+ *
+ */
+@ManagedBean(name="forEachBean")
+@SessionScoped
+public class ForEachBean
+{
+    private List<String> items1;
+    
+    public ForEachBean()
+    {
+        items1 = new ArrayList<String>();
+        items1.add("a");
+        items1.add("b");
+        items1.add("c");
+    }
+
+    /**
+     * @return the items1
+     */
+    public List<String> getItems1()
+    {
+        return items1;
+    }
+    
+    public void addFirst()
+    {
+        items1.add(0, "z");
+    }
+
+    public void addMiddle()
+    {
+        items1.add(2, "x");
+    }
+
+    public void removeLast()
+    {
+        items1.remove(items1.size()-1);
+    }
+}

Propchange: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pss/acid/managed/ForEachBean.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/forEach1.xhtml (from r1539924, myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/componentBinding1.xhtml)
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/forEach1.xhtml?p2=myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/forEach1.xhtml&p1=myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/componentBinding1.xhtml&r1=1539924&r2=1540431&rev=1540431&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/componentBinding1.xhtml (original)
+++ myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pss/acid/forEach1.xhtml Sun Nov 10 00:12:40 2013
@@ -15,13 +15,24 @@
 <html xmlns="http://www.w3.org/1999/xhtml"
     xmlns:h="http://java.sun.com/jsf/html"
     xmlns:f="http://java.sun.com/jsf/core"
-    xmlns:ui="http://java.sun.com/jsf/facelets">
+    xmlns:ui="http://java.sun.com/jsf/facelets"
+    xmlns:c="http://java.sun.com/jsp/jstl/core">
 <h:head>
 </h:head>
 <h:body>
-  <h:panelGroup id="panel" binding="#{componentBindingBean.panel}"/>
   <h:form id="mainForm">
-     <h:commandButton id="postback" value="POSTBACK"/>
+    <c:if test="#{true}">
+        Start
+    </c:if>
+    <h:outputText value="Start"/>
+    <c:forEach items="#{forEachBean.items1}" var="item">
+        <p><h:outputText id="item_#{item}" value="#{item}"/></p>
+    </c:forEach>
+    <h:outputText value="End"/>
+    <c:if test="#{true}">
+        End
+    </c:if>
+    <h:commandButton id="postback" value="POSTBACK"/>
   </h:form>
 </h:body>
 </html>