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/12/13 02:18:10 UTC

svn commit: r1550609 [1/5] - in /myfaces/core/trunk: api/src/main/java/javax/faces/component/ api/src/test/java/javax/faces/component/ impl/src/main/java/org/apache/myfaces/application/ impl/src/main/java/org/apache/myfaces/config/ impl/src/main/java/o...

Author: lu4242
Date: Fri Dec 13 01:18:08 2013
New Revision: 1550609

URL: http://svn.apache.org/r1550609
Log:
MYFACES-3664 JSF View Pooling (going beyond JSF Stateless Mode)

Added:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ViewPoolMapping.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ViewPoolParameter.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ViewPoolMappingImpl.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ViewPoolParameterImpl.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/RequestViewMetadata.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/ViewPoolProcessor.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/pool/
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/pool/RestoreViewFromPoolResult.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/pool/ViewEntry.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/pool/ViewPool.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/pool/ViewPoolFactory.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/pool/ViewStructureMetadata.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/pool/impl/
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/pool/impl/DynamicViewKey.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/pool/impl/MetadataViewKey.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/pool/impl/MetadataViewKeyImpl.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/pool/impl/SoftViewEntry.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/pool/impl/ViewPoolEntryHolder.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/pool/impl/ViewPoolFactoryImpl.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/pool/impl/ViewPoolImpl.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/pool/impl/ViewStructureMetadataImpl.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/pool/impl/WeakViewEntry.java   (with props)
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pool/
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pool/DynamicBean.java   (with props)
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pool/SimpleRequestBean.java   (with props)
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pool/StateHolderConverter.java   (with props)
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pool/UISimpleComponentA.java   (with props)
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pool/ViewParamBean.java   (with props)
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pool/ViewPoolFaceletsTestCase.java   (with props)
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/view/facelets/pool/ViewPoolMyFacesRequestTestCase.java   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/dynPage1.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/dynPageResource.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/dynPageResource2.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/dynPageResourceCleanup1.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/dynPageResourceCleanup2.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/partialPage1.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/resources/
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/resources/test.js   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/resources/test1.js   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/resources/testComposite/
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/resources/testComposite/dynComp_1.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/staticPage.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/staticPage2.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/staticPageBinding1.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/staticPageBinding2.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/staticPageBinding3.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/staticPageBinding3_1.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/staticPageBinding4.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/staticPageBindingValidator1.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/staticPageContract1.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/staticPageLocale1.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/staticPageNoForm.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/staticPageNoForm2.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/staticPageStateHolderConverter1.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/staticPageStateHolderConverter2.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/staticUIParamPage1.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/staticUIParamPage1_1.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/staticViewParamPage1.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/test-facelet.taglib.xml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/view/facelets/pool/view-pool-faces-config.xml   (with props)
Modified:
    myfaces/core/trunk/api/src/main/java/javax/faces/component/UIComponentBase.java
    myfaces/core/trunk/api/src/main/java/javax/faces/component/UIData.java
    myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java
    myfaces/core/trunk/api/src/main/java/javax/faces/component/_DeltaStateHelper.java
    myfaces/core/trunk/api/src/main/java/javax/faces/component/_ViewAttributeMap.java
    myfaces/core/trunk/api/src/test/java/javax/faces/component/_DeltaStateHelperTest.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ActionListenerImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/RuntimeConfig.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesConfigData.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesConfigExtension.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/DigesterFacesConfigDispenserImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/DigesterFacesConfigUnmarshallerImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesConfigExtensionImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/RequestViewContext.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImplBase.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ApplyRequestValuesExecutor.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/InvokeApplicationExecutor.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/FaceletState.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/facelets/tag/jsf/core/ViewHandler.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UIComponentBase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UIComponentBase.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UIComponentBase.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UIComponentBase.java Fri Dec 13 01:18:08 2013
@@ -85,6 +85,10 @@ public abstract class UIComponentBase ex
     private static final String _STRING_BUILDER_KEY
             = "javax.faces.component.UIComponentBase.SHARED_STRING_BUILDER";
 
+    static final int RESET_MODE_OFF = 0;
+    static final int RESET_MODE_SOFT = 1;
+    static final int RESET_MODE_HARD = 2;
+
     private _ComponentAttributesMap _attributesMap = null;
     private _PassThroughAttributesMap _passthroughAttributesMap = null;
     private List<UIComponent> _childrenList = null;
@@ -1216,6 +1220,10 @@ public abstract class UIComponentBase ex
     public void markInitialState()
     {
         super.markInitialState();
+        
+        // Enable copyFullInitialState behavior when delta is written into this component.
+        ((_DeltaStateHelper)getStateHelper()).setCopyFullInitialState(true);
+        
         if (_facesListeners != null)
         {
             _facesListeners.markInitialState();
@@ -1925,6 +1933,31 @@ public abstract class UIComponentBase ex
             throw new NullPointerException ("context");
         }
         
+        if (context.getViewRoot() != null)
+        {
+            if (context.getViewRoot().getResetSaveStateMode() == RESET_MODE_SOFT)
+            {
+                // Force FacesContext cleanup to prevent leak it.
+                setCachedFacesContext(null);
+                // Reset state to recalculate state first.
+                StateHelper stateHelper = getStateHelper(false);
+                if (stateHelper != null)
+                {
+                    ((_DeltaStateHelper)stateHelper).resetSoftState(context);
+                }
+            }
+            if (context.getViewRoot().getResetSaveStateMode() == RESET_MODE_HARD)
+            {
+                // Force FacesContext cleanup to prevent leak it.
+                setCachedFacesContext(null);
+                // Reset state to recalculate state first.
+                StateHelper stateHelper = getStateHelper(false);
+                if (stateHelper != null)
+                {
+                    ((_DeltaStateHelper)stateHelper).resetHardState(context);
+                }
+            }
+        }
         if (initialStateMarked())
         {
             //Delta

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UIData.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UIData.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UIData.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UIData.java Fri Dec 13 01:18:08 2013
@@ -1477,6 +1477,23 @@ public class UIData extends UIComponentB
     @Override
     public Object saveState(FacesContext context)
     {
+        if (context.getViewRoot() != null)
+        {
+            if (context.getViewRoot().getResetSaveStateMode() == RESET_MODE_SOFT)
+            {
+                _dataModelMap.clear();
+                _isValidChilds=true;
+                _rowTransientStates.clear();
+            }
+            if (context.getViewRoot().getResetSaveStateMode() == RESET_MODE_HARD)
+            {
+                _dataModelMap.clear();
+                _isValidChilds=true;
+                _rowTransientStates.clear();
+                _rowStates.clear();
+                _rowDeltaStates.clear();
+            }
+        }
         if (initialStateMarked())
         {
             Object parentSaved = super.saveState(context);

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java Fri Dec 13 01:18:08 2013
@@ -144,6 +144,9 @@ public class UIViewRoot extends UICompon
     private static final String JAVAX_FACES_LOCATION_BODY = "javax_faces_location_body";
     private static final String JAVAX_FACES_LOCATION_FORM = "javax_faces_location_form";
     
+    private static final String SKIP_VIEW_MAP_SAVE_STATE = "oam.viewPool.SKIP_VIEW_MAP_SAVE_STATE";
+    
+    private transient int _resetSaveStateMode = 0;
     private transient boolean _resourceDependencyUniqueId;
     private transient Map<String,Object> _attributesMap;
     
@@ -1358,7 +1361,23 @@ public class UIViewRoot extends UICompon
     {
         getStateHelper().put(PropertyKeys.afterPhaseListener, afterPhaseListener);
     }
-    
+
+    /**
+     * @return the clearTransientMapOnSaveState
+     */
+    int getResetSaveStateMode()
+    {
+        return _resetSaveStateMode;
+    }
+
+    /**
+     * @param clearTransientMapOnSaveState the clearTransientMapOnSaveState to set
+     */
+    void setResetSaveStateMode(int clearTransientMapOnSaveState)
+    {
+        this._resetSaveStateMode = clearTransientMapOnSaveState;
+    }
+
     @Override
     public Map<String, Object> getAttributes()
     {
@@ -1413,9 +1432,64 @@ public class UIViewRoot extends UICompon
     @Override
     public Object saveState(FacesContext facesContext)
     {
+        if (getResetSaveStateMode() == RESET_MODE_SOFT)
+        {
+            // Clear view listeners.
+            if (_systemEventListeners != null)
+            {
+                _systemEventListeners.clear();
+            }
+            if (_events != null)
+            {
+                _events.clear();
+            }
+            if (listenerSuccessMap != null)
+            {
+                listenerSuccessMap.clear();
+            }
+        }
+        if (getResetSaveStateMode() == RESET_MODE_HARD)
+        {
+            // Clear view listeners.
+            if (_systemEventListeners != null)
+            {
+                _systemEventListeners.clear();
+            }
+            if (_events != null)
+            {
+                _events.clear();
+            }
+            if (listenerSuccessMap != null)
+            {
+                listenerSuccessMap.clear();
+            }
+            if (_viewScope != null)
+            {
+                if (VIEW_SCOPE_PROXY_MAP_CLASS.isInstance(_viewScope))
+                {
+                    _viewScope = null;
+                }
+                else
+                {
+                    _viewScope.clear();
+                }
+            }
+        }
+        
         if (initialStateMarked())
         {
             Object parentSaved = super.saveState(facesContext);
+            if (_viewScope != null && 
+                Boolean.TRUE.equals(facesContext.getAttributes().get(
+                SKIP_VIEW_MAP_SAVE_STATE)))
+            {
+                if (parentSaved == null)
+                {
+                    return null;
+                }
+                return new Object[]{parentSaved, null};
+            }
+            
             if (parentSaved == null && _viewScope == null)
             {
                 //No values
@@ -1435,6 +1509,12 @@ public class UIViewRoot extends UICompon
         }
         else
         {
+            if (_viewScope != null && 
+                Boolean.TRUE.equals(facesContext.getAttributes().get(
+                SKIP_VIEW_MAP_SAVE_STATE)))
+            {
+                return new Object[]{super.saveState(facesContext), null};
+            }
             Object[] values = new Object[2];
             values[0] = super.saveState(facesContext);
             values[1] = saveAttachedState(facesContext,_viewScope);

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/_DeltaStateHelper.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/_DeltaStateHelper.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/_DeltaStateHelper.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/_DeltaStateHelper.java Fri Dec 13 01:18:08 2013
@@ -171,6 +171,21 @@ class _DeltaStateHelper implements State
 
     private boolean _transient = false;
 
+    /**
+     * This is a copy-on-write map of the full state after markInitialState()
+     * was called, but before any delta is written that is not part of
+     * the initial state (value, localValueSet, submittedValue, valid).
+     * The intention is allow to reset the StateHelper when copyFullInitialState
+     * is set to true.
+     */
+    private Map<Serializable, Object> _initialFullState;
+    
+    /**
+     * Indicates if a copy-on-write map is created to allow reset the state
+     * of this StateHelper.
+     */
+    private boolean _copyFullInitialState;
+
     public _DeltaStateHelper(UIComponent component)
     {
         super();
@@ -178,6 +193,8 @@ class _DeltaStateHelper implements State
         _fullState = new HashMap<Serializable, Object>();
         _deltas = null;
         _transientState = null;
+        _initialFullState = null;
+        _copyFullInitialState = false;
         //_stateHolderKeys = new HashSet<Serializable>();
     }
 
@@ -186,10 +203,49 @@ class _DeltaStateHelper implements State
      * 
      * @return
      */
-    private boolean _createDeltas()
+    private boolean _createDeltas(Serializable key)
     {
         if (isInitialStateMarked())
         {
+            if (_copyFullInitialState && _initialFullState == null)
+            {
+                if (_initialState == null)
+                {
+                    // Copy it directly
+                    _initialFullState = new HashMap<Serializable, Object>();
+                    copyMap(_component.getFacesContext(), _fullState, _initialFullState);
+                }
+                else
+                {
+                    // Create only if the passed key is not part of the defined initial state
+                    boolean keyInInitialState = false;
+                    for (int i = 0; i < _initialState.length; i+=2)
+                    {
+                        Serializable key2 = (Serializable) _initialState[i];
+                        if (key.equals(key2))
+                        {
+                            keyInInitialState = true;
+                            break;
+                        }
+                    }
+                    if (!keyInInitialState)
+                    {
+                        // Copy it directly, but note in this case if the initialFullState map
+                        // contains some key already defined in initialState, this key must be
+                        // overriden. It is better to do in that way, because it is possible
+                        // to skip resetState() if the view cannot be recycled.
+                        _initialFullState = new HashMap<Serializable, Object>();
+                        copyMap(_component.getFacesContext(), _fullState, _initialFullState);
+                        /*
+                        for (int i = 0; i < _initialState.length; i+=2)
+                        {
+                            Serializable key2 = (Serializable) _initialState[i];
+                            Object defaultValue = _initialState[i+1];
+                            _initialFullState.put(key2, defaultValue);
+                        }*/
+                    }
+                }
+            }
             if (_deltas == null)
             {
                 _deltas = new HashMap<Serializable, Object>(2);
@@ -200,6 +256,65 @@ class _DeltaStateHelper implements State
         return false;
     }
     
+    void setCopyFullInitialState(boolean value)
+    {
+        _copyFullInitialState = value;
+    }
+    
+    private static void copyMap(FacesContext context, 
+            Map<Serializable, Object> sourceMap, 
+            Map<Serializable, Object> targetMap)
+    {
+        Map serializableMap = sourceMap;
+        Map.Entry<Serializable, Object> entry;
+
+        Iterator<Map.Entry<Serializable, Object>> it = serializableMap
+                .entrySet().iterator();
+        while (it.hasNext())
+        {
+            entry = it.next();
+            Serializable key = entry.getKey();
+            Object value = entry.getValue();
+
+            // The condition in which the call to saveAttachedState
+            // is to handle List, StateHolder or non Serializable instances.
+            // we check it here, to prevent unnecessary calls.
+            if (value instanceof StateHolder ||
+                value instanceof List ||
+                !(value instanceof Serializable))
+            {
+                Object savedValue = UIComponentBase.saveAttachedState(context,
+                    value);
+
+                targetMap.put(key, UIComponentBase.restoreAttachedState(context,
+                        savedValue));
+            }
+            else if (!(value instanceof Serializable))
+            {
+                Object newInstance;
+                try
+                {
+                    newInstance = entry.getValue().getClass().newInstance();
+                }
+                catch (InstantiationException e)
+                {
+                    throw new RuntimeException("Could not restore StateHolder of type " + 
+                            entry.getValue().getClass().getName()
+                            + " (missing no-args constructor?)", e);
+                }
+                catch (IllegalAccessException e)
+                {
+                    throw new RuntimeException(e);
+                }
+                targetMap.put(key, newInstance);
+            }
+            else
+            {
+                targetMap.put(key, value);
+            }
+        }
+    }
+    
     protected boolean isInitialStateMarked()
     {
         return _component.initialStateMarked();
@@ -207,7 +322,7 @@ class _DeltaStateHelper implements State
 
     public void add(Serializable key, Object value)
     {
-        if (_createDeltas())
+        if (_createDeltas(key))
         {
             //Track delta case
             Map<Object, Boolean> deltaListMapValues = (Map<Object, Boolean>) _deltas
@@ -273,7 +388,7 @@ class _DeltaStateHelper implements State
     public Object put(Serializable key, Object value)
     {
         Object returnValue = null;
-        if (_createDeltas())
+        if (_createDeltas(key))
         {
             if (_deltas.containsKey(key))
             {
@@ -307,7 +422,7 @@ class _DeltaStateHelper implements State
     {
         boolean returnSet = false;
         Object returnValue = null;
-        if (_createDeltas())
+        if (_createDeltas(key))
         {
             //Track delta case
             Map<String, Object> mapValues = (Map<String, Object>) _deltas
@@ -350,7 +465,7 @@ class _DeltaStateHelper implements State
     public Object remove(Serializable key)
     {
         Object returnValue = null;
-        if (_createDeltas())
+        if (_createDeltas(key))
         {
             if (_deltas.containsKey(key))
             {
@@ -384,7 +499,7 @@ class _DeltaStateHelper implements State
         Object returnValue = null;
         if (collectionOrMap instanceof InternalMap)
         {
-            if (_createDeltas())
+            if (_createDeltas(key))
             {
                 returnValue = _removeValueOrKeyFromMap(_deltas, key,
                         valueOrKey, true);
@@ -398,7 +513,7 @@ class _DeltaStateHelper implements State
         }
         else if (collectionOrMap instanceof InternalList)
         {
-            if (_createDeltas())
+            if (_createDeltas(key))
             {
                 returnValue = _removeValueOrKeyFromCollectionDelta(_deltas,
                         key, valueOrKey);
@@ -629,7 +744,7 @@ class _DeltaStateHelper implements State
                 }
             }
         }
-        */       
+        */
         return retArr;
     }
 
@@ -706,6 +821,62 @@ class _DeltaStateHelper implements State
             }
         }
     }
+    
+    /**
+     * Try to reset the state and then check if the reset was succesful or not,
+     * calling saveState().
+     */
+    public Object resetHardState(FacesContext context)
+    {
+        if (_transientState != null)
+        {
+            _transientState.clear();
+        }
+        if (_deltas != null && !_deltas.isEmpty() && isInitialStateMarked())
+        {
+            clearFullStateMap(context);
+        }
+        return saveState(context);
+    }
+    
+    /**
+     * Execute a "soft reset", which means only remove all transient state.
+     */
+    public Object resetSoftState(FacesContext context)
+    {
+        if (_transientState != null)
+        {
+            _transientState.clear();
+        }
+        return null;
+    }
+    
+    protected void clearFullStateMap(FacesContext context)
+    {
+        if (_deltas != null)
+        {
+            _deltas.clear();
+        }
+        if (_initialFullState != null)
+        {
+            // If there is no delta, fullState is not required to be cleared.
+            _fullState.clear();
+            copyMap(context, _initialFullState, _fullState);
+        }
+        if (_initialState != null)
+        {
+            // If initial state is defined, override properties in _initialFullState.
+            for (int i = 0; i < _initialState.length; i+=2)
+            {
+                Serializable key2 = (Serializable) _initialState[i];
+                Object defaultValue = _initialState[i+1];
+                if (_fullState.containsKey(key2))
+                {
+                    _fullState.put(key2, defaultValue);
+                }
+            }
+        }
+    }
 
     public void setTransient(boolean transientValue)
     {

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/_ViewAttributeMap.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/_ViewAttributeMap.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/_ViewAttributeMap.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/_ViewAttributeMap.java Fri Dec 13 01:18:08 2013
@@ -28,8 +28,8 @@ class _ViewAttributeMap implements Map<S
 {
     private static final long serialVersionUID = -9106832109394257866L;
 
-    //private static final String RESET_SAVE_STATE_MODE_KEY = 
-    //        "oam.view.resetSaveStateMode";
+    private static final String RESET_SAVE_STATE_MODE_KEY = 
+            "oam.view.resetSaveStateMode";
 
     /**
      * Key under UIViewRoot to generated unique ids for components added 
@@ -73,12 +73,12 @@ class _ViewAttributeMap implements Map<S
     {
         checkKey(key);
         int keyLength = ((String)key).length();
-        /*
+
         if (RESET_SAVE_STATE_MODE_KEY.length() == keyLength
             && RESET_SAVE_STATE_MODE_KEY.equals(key))
         {
             return _root.getResetSaveStateMode();
-        }*/
+        }
         if (RESOURCE_DEPENDENCY_UNIQUE_ID_KEY.length() == keyLength
             && RESOURCE_DEPENDENCY_UNIQUE_ID_KEY.equals(key))
         {
@@ -96,14 +96,13 @@ class _ViewAttributeMap implements Map<S
     {
         int keyLength = ((String)key).length();
 
-        /*
         if (RESET_SAVE_STATE_MODE_KEY.length() == keyLength
             && RESET_SAVE_STATE_MODE_KEY.equals(key))
         {
             Integer b = _root.getResetSaveStateMode();
             _root.setResetSaveStateMode(value == null ? 0 : (Integer) value);
             return b;
-        }*/
+        }
         if (RESOURCE_DEPENDENCY_UNIQUE_ID_KEY.length() == keyLength
             && RESOURCE_DEPENDENCY_UNIQUE_ID_KEY.equals(key))
         {

Modified: myfaces/core/trunk/api/src/test/java/javax/faces/component/_DeltaStateHelperTest.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/test/java/javax/faces/component/_DeltaStateHelperTest.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/test/java/javax/faces/component/_DeltaStateHelperTest.java (original)
+++ myfaces/core/trunk/api/src/test/java/javax/faces/component/_DeltaStateHelperTest.java Fri Dec 13 01:18:08 2013
@@ -261,7 +261,7 @@ public class _DeltaStateHelperTest exten
         //theoretically there should be almot no data in the delta state if the full state already has been stored!
         _instance.setInitialStateMarked(true);
         _instance.put(KEY5, VAL5);
-        Object[] deltaSaveState = (Object[]) _instance.saveState(null);
+        Object[] deltaSaveState = (Object[]) _instance.saveState(facesContext);
         //only the new value should be saved as delta
         assertTrue("Delta Savestate structure", deltaSaveState.length == 2
                 && deltaSaveState[0].equals(KEY5)

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ActionListenerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ActionListenerImpl.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ActionListenerImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ActionListenerImpl.java Fri Dec 13 01:18:08 2013
@@ -20,15 +20,21 @@ package org.apache.myfaces.application;
 
 import javax.el.MethodExpression;
 import javax.faces.application.Application;
+import javax.faces.application.ConfigurableNavigationHandler;
+import javax.faces.application.NavigationCase;
 import javax.faces.application.NavigationHandler;
 import javax.faces.component.ActionSource;
 import javax.faces.component.ActionSource2;
 import javax.faces.component.UIComponent;
+import javax.faces.component.UIViewRoot;
 import javax.faces.context.FacesContext;
 import javax.faces.el.MethodBinding;
 import javax.faces.event.AbortProcessingException;
 import javax.faces.event.ActionEvent;
 import javax.faces.event.ActionListener;
+import javax.faces.event.PhaseId;
+import org.apache.myfaces.view.facelets.ViewPoolProcessor;
+import org.apache.myfaces.view.facelets.pool.ViewPool;
 
 
 /**
@@ -85,20 +91,56 @@ public class ActionListenerImpl implemen
 
         }
         
-        NavigationHandler navigationHandler = application.getNavigationHandler();
-        String toFlowDocumentId = (component != null) ? 
-            (String) component.getAttributes().get(ActionListener.TO_FLOW_DOCUMENT_ID_ATTR_NAME) : null;
-        
-        if (toFlowDocumentId != null)
+        UIViewRoot root = facesContext.getViewRoot();
+        ViewPoolProcessor processor = ViewPoolProcessor.getInstance(facesContext);
+        ViewPool pool = (processor != null) ? processor.getViewPool(facesContext, root) : null;
+        if (pool != null && pool.isDeferredNavigationEnabled() && 
+            processor.isViewPoolStrategyAllowedForThisView(facesContext, root) &&
+            (PhaseId.INVOKE_APPLICATION.equals(facesContext.getCurrentPhaseId()) ||
+             PhaseId.APPLY_REQUEST_VALUES.equals(facesContext.getCurrentPhaseId())) )
         {
-            navigationHandler.handleNavigation(facesContext, fromAction, outcome, toFlowDocumentId);
+            NavigationHandler navigationHandler = application.getNavigationHandler();
+            if (navigationHandler instanceof ConfigurableNavigationHandler)
+            {
+                NavigationCase navigationCase = ((ConfigurableNavigationHandler) navigationHandler).
+                    getNavigationCase(facesContext, fromAction, outcome);
+                if (navigationCase != null)
+                {
+                    // Deferred invoke navigation. The first one wins
+                    if (!facesContext.getAttributes().containsKey(ViewPoolProcessor.INVOKE_DEFERRED_NAVIGATION))
+                    {
+                        String toFlowDocumentId = (component != null) ? 
+                            (String) component.getAttributes().get(ActionListener.TO_FLOW_DOCUMENT_ID_ATTR_NAME) : null;
+                        if (toFlowDocumentId != null)
+                        {
+                            facesContext.getAttributes().put(ViewPoolProcessor.INVOKE_DEFERRED_NAVIGATION, 
+                                    new Object[]{fromAction, outcome, toFlowDocumentId});
+                        }
+                        else
+                        {
+                            facesContext.getAttributes().put(ViewPoolProcessor.INVOKE_DEFERRED_NAVIGATION, 
+                                    new Object[]{fromAction, outcome});
+                        }
+                    }
+                }
+            }
         }
         else
         {
-            navigationHandler.handleNavigation(facesContext, fromAction, outcome);
-        }
-        //Render Response if needed
-        facesContext.renderResponse();
+            NavigationHandler navigationHandler = application.getNavigationHandler();
+            String toFlowDocumentId = (component != null) ? 
+                (String) component.getAttributes().get(ActionListener.TO_FLOW_DOCUMENT_ID_ATTR_NAME) : null;
 
+            if (toFlowDocumentId != null)
+            {
+                navigationHandler.handleNavigation(facesContext, fromAction, outcome, toFlowDocumentId);
+            }
+            else
+            {
+                navigationHandler.handleNavigation(facesContext, fromAction, outcome);
+            }
+            //Render Response if needed
+            facesContext.renderResponse();
+        }
     }
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java Fri Dec 13 01:18:08 2013
@@ -80,6 +80,7 @@ import javax.faces.event.SystemEventList
 import javax.faces.event.SystemEventListenerHolder;
 import javax.faces.flow.FlowHandler;
 import javax.faces.render.ClientBehaviorRenderer;
+import javax.faces.render.RenderKit;
 import javax.faces.render.Renderer;
 import javax.faces.render.RendererWrapper;
 import javax.faces.validator.Validator;
@@ -97,6 +98,7 @@ import org.apache.myfaces.config.Runtime
 import org.apache.myfaces.config.element.Property;
 import org.apache.myfaces.config.element.ResourceBundle;
 import org.apache.myfaces.context.RequestViewContext;
+import org.apache.myfaces.context.RequestViewMetadata;
 import org.apache.myfaces.el.PropertyResolverImpl;
 import org.apache.myfaces.el.VariableResolverToApplicationELResolverAdapter;
 import org.apache.myfaces.el.convert.MethodExpressionToMethodBinding;
@@ -1944,6 +1946,10 @@ public class ApplicationImpl extends App
                 attributes.put("library", library);
             }
             
+            // Identify the resource as created by effect of a @ResourceDependency annotation.
+            output.getAttributes().put(RequestViewMetadata.RESOURCE_DEPENDENCY_KEY, 
+                new Object[]{annotation.library(), annotation.name()});
+            
             // If target is the empty string, let target be null.
             String target = annotation.target();
             if (target != null && target.length() > 0)
@@ -2498,6 +2504,10 @@ public class ApplicationImpl extends App
                     attributes.put("library", library);
                 }
             }
+            
+            // Identify the resource as created by effect of a @ResourceDependency annotation.
+            output.getAttributes().put(RequestViewMetadata.RESOURCE_DEPENDENCY_KEY, 
+                new Object[]{annotation.library(), annotation.name()});
 
             // If target is the empty string, let target be null.
             String target = annotation.target();
@@ -2526,7 +2536,13 @@ public class ApplicationImpl extends App
          * RenderKit.getRenderer(java.lang.String, java.lang.String) on the result, passing the argument componentFamily
          * of the newly created component as the first argument and the argument rendererType as the second argument.
          */
-        Renderer renderer = context.getRenderKit().getRenderer(component.getFamily(), rendererType);
+        RenderKit renderKit = context.getRenderKit();
+        if (renderKit == null)
+        {
+            // If no renderKit is set, it means we are on initialization step, skip this step.
+            return;
+        }
+        Renderer renderer = renderKit.getRenderer(component.getFamily(), rendererType);
         if (renderer == null)
         {
             // If no such Renderer can be found, a message must be logged with a helpful error message.

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java Fri Dec 13 01:18:08 2013
@@ -70,6 +70,7 @@ import org.apache.myfaces.shared.renderk
 import org.apache.myfaces.shared.util.ClassUtils;
 import org.apache.myfaces.shared.util.HashMapUtils;
 import org.apache.myfaces.shared.util.StringUtils;
+import org.apache.myfaces.view.facelets.ViewPoolProcessor;
 import org.apache.myfaces.view.facelets.tag.jsf.PreDisposeViewEvent;
 
 /**
@@ -212,6 +213,14 @@ public class NavigationHandlerImpl
                 {
                     partialViewContext.setRenderAll(true);
                 }
+
+                // Dispose view if the view has been marked as disposable by default action listener
+                ViewPoolProcessor processor = ViewPoolProcessor.getInstance(facesContext);
+                if (processor != null && 
+                    processor.isViewPoolEnabledForThisView(facesContext, facesContext.getViewRoot()))
+                {
+                    processor.disposeView(facesContext, facesContext.getViewRoot());
+                }
                 
                 // JSF 2.0 Spec call Flash.setRedirect(true) to notify Flash scope and take proper actions
                 externalContext.getFlash().setRedirect(true);
@@ -256,6 +265,14 @@ public class NavigationHandlerImpl
                 
                 applyFlowTransition(facesContext, navigationContext);
 
+                // Dispose view if the view has been marked as disposable by default action listener
+                ViewPoolProcessor processor = ViewPoolProcessor.getInstance(facesContext);
+                if (processor != null && 
+                    processor.isViewPoolEnabledForThisView(facesContext, facesContext.getViewRoot()))
+                {
+                    processor.disposeView(facesContext, facesContext.getViewRoot());
+                }
+                
                 // create UIViewRoot for new view
                 UIViewRoot viewRoot = null;
                 

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java Fri Dec 13 01:18:08 2013
@@ -135,6 +135,7 @@ import org.apache.myfaces.shared.util.We
 import org.apache.myfaces.shared_impl.util.serial.DefaultSerialFactory;
 import org.apache.myfaces.shared_impl.util.serial.SerialFactory;
 import org.apache.myfaces.cdi.dependent.BeanEntry;
+import org.apache.myfaces.config.element.ViewPoolMapping;
 import org.apache.myfaces.config.element.facelets.FaceletTagLibrary;
 import org.apache.myfaces.renderkit.LazyRenderKit;
 import org.apache.myfaces.spi.FacesConfigurationMerger;
@@ -1093,6 +1094,11 @@ public class FacesConfigurator
         }
         runtimeConfig.setNamespaceById(Collections.unmodifiableMap(namespaceById));
         runtimeConfig.setIdByNamespace(Collections.unmodifiableMap(idByNamespace));
+        
+        for (ViewPoolMapping viewPoolMapping : dispenser.getViewPoolMappings())
+        {
+            runtimeConfig.addViewPoolMapping(viewPoolMapping);
+        }
     }
 
     private void removePurgedBeansFromSessionAndApplication(RuntimeConfig runtimeConfig)

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/RuntimeConfig.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/RuntimeConfig.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/RuntimeConfig.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/RuntimeConfig.java Fri Dec 13 01:18:08 2013
@@ -43,6 +43,7 @@ import org.apache.myfaces.config.element
 import org.apache.myfaces.config.element.ManagedBean;
 import org.apache.myfaces.config.element.NavigationRule;
 import org.apache.myfaces.config.element.ResourceBundle;
+import org.apache.myfaces.config.element.ViewPoolMapping;
 import org.apache.myfaces.config.element.facelets.FaceletTagLibrary;
 
 /**
@@ -118,6 +119,8 @@ public class RuntimeConfig
     
     private Map<Integer, String> _namespaceById = new HashMap<Integer, String>();
     private Map<String, Integer> _idByNamespace = new HashMap<String, Integer>();
+    
+    private List<ViewPoolMapping> _viewPoolMappings = new ArrayList<ViewPoolMapping>();
 
     public static RuntimeConfig getCurrentInstance(ExternalContext externalContext)
     {
@@ -555,4 +558,13 @@ public class RuntimeConfig
         this._idByNamespace = idByNamespace;
     }
 
+    public List<ViewPoolMapping> getViewPoolMappings()
+    {
+        return _viewPoolMappings;
+    }
+    
+    public void addViewPoolMapping(ViewPoolMapping mapping)
+    {
+        _viewPoolMappings.add(mapping);
+    }
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesConfigData.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesConfigData.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesConfigData.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesConfigData.java Fri Dec 13 01:18:08 2013
@@ -297,4 +297,9 @@ public abstract class FacesConfigData im
     {
         return Collections.emptyList();
     }
+    
+    public Collection<ViewPoolMapping> getViewPoolMappings()
+    {
+        return Collections.emptyList();
+    }
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesConfigExtension.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesConfigExtension.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesConfigExtension.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesConfigExtension.java Fri Dec 13 01:18:08 2013
@@ -19,6 +19,7 @@
 package org.apache.myfaces.config.element;
 
 import java.io.Serializable;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -29,4 +30,14 @@ import java.util.List;
 public abstract class FacesConfigExtension implements Serializable
 {
     public abstract List<FaceletsProcessing> getFaceletsProcessingList();
+    
+    /**
+     * @since 2.2.0
+     * @return 
+     */
+    public List<ViewPoolMapping> getViewPoolMappings()
+    {
+        return Collections.emptyList();
+    }
+
 }

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ViewPoolMapping.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ViewPoolMapping.java?rev=1550609&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ViewPoolMapping.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ViewPoolMapping.java Fri Dec 13 01:18:08 2013
@@ -0,0 +1,33 @@
+/*
+ * 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.config.element;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ *
+ */
+public abstract class ViewPoolMapping implements Serializable
+{
+    public abstract String getUrlPattern();
+    
+    public abstract List<ViewPoolParameter> getParameterList();
+    
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ViewPoolMapping.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ViewPoolParameter.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ViewPoolParameter.java?rev=1550609&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ViewPoolParameter.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ViewPoolParameter.java Fri Dec 13 01:18:08 2013
@@ -0,0 +1,34 @@
+/*
+ * 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.config.element;
+
+import java.io.Serializable;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+public abstract class ViewPoolParameter implements Serializable
+{
+    
+    public abstract String getName();
+    
+    public abstract String getValue();
+    
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/ViewPoolParameter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/DigesterFacesConfigDispenserImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/DigesterFacesConfigDispenserImpl.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/DigesterFacesConfigDispenserImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/DigesterFacesConfigDispenserImpl.java Fri Dec 13 01:18:08 2013
@@ -48,6 +48,7 @@ import org.apache.myfaces.config.element
 import org.apache.myfaces.config.element.RenderKit;
 import org.apache.myfaces.config.element.ResourceBundle;
 import org.apache.myfaces.config.element.SystemEventListener;
+import org.apache.myfaces.config.element.ViewPoolMapping;
 import org.apache.myfaces.config.element.facelets.FaceletTagLibrary;
 import org.apache.myfaces.config.impl.digester.elements.RenderKitImpl;
 
@@ -128,6 +129,8 @@ public class DigesterFacesConfigDispense
     
     private List <String> resourceResolvers = new ArrayList<String>();
     
+    private List<ViewPoolMapping> viewPoolMappings = new ArrayList<ViewPoolMapping>();
+    
     // Unmodifiable list/maps to avoid modifications
     private transient List<String> umapplicationFactories;
     private transient List<String> umexceptionHandlerFactories;
@@ -164,6 +167,7 @@ public class DigesterFacesConfigDispense
     private transient List<ComponentTagDeclaration> umcomponentTagDeclarations;
     private transient List<FaceletTagLibrary> umfaceletTagLibraries;
     private transient List <String> umresourceResolvers;
+    private transient List<ViewPoolMapping> umviewPoolMappings;
     
     /**
      * Add another unmarshalled faces config object.
@@ -320,6 +324,10 @@ public class DigesterFacesConfigDispense
         facesFlowDefinitions.addAll(config.getFacesFlowDefinitions());
         protectedViewUrlPatterns.addAll(config.getProtectedViewsUrlPatternList());
         resourceResolvers.addAll(config.getResourceResolversList());
+        for (FacesConfigExtension extension : config.getFacesConfigExtensions())
+        {
+            viewPoolMappings.addAll(extension.getViewPoolMappings());
+        }
     }
 
     /**
@@ -1026,4 +1034,13 @@ public class DigesterFacesConfigDispense
         return umfaceletTagLibraries;
     }
     
+    @Override
+    public Collection<ViewPoolMapping> getViewPoolMappings()
+    {
+        if (umviewPoolMappings == null)
+        {
+            umviewPoolMappings = Collections.unmodifiableList(viewPoolMappings);
+        }
+        return umviewPoolMappings;
+    }
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/DigesterFacesConfigUnmarshallerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/DigesterFacesConfigUnmarshallerImpl.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/DigesterFacesConfigUnmarshallerImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/DigesterFacesConfigUnmarshallerImpl.java Fri Dec 13 01:18:08 2013
@@ -443,6 +443,19 @@ public class DigesterFacesConfigUnmarsha
         digester.addSetNext("faces-config/flow-definition/inbound-parameter", "addInboundParameter");
         digester.addCallMethod("faces-config/flow-definition/inbound-parameter/name", "setName", 0);
         digester.addCallMethod("faces-config/flow-definition/inbound-parameter/value", "setValue", 0);
+        
+        //View Pool config
+        digester.addObjectCreate("faces-config/faces-config-extension/view-pool-mapping", 
+            ViewPoolMappingImpl.class);
+        digester.addSetNext("faces-config/faces-config-extension/view-pool-mapping", 
+            "addViewPoolMapping");
+        digester.addCallMethod(
+                        "faces-config/faces-config-extension/view-pool-mapping/url-pattern", "setUrlPattern", 0);
+        digester.addObjectCreate("faces-config/faces-config-extension/view-pool-mapping/parameter", 
+            ViewPoolParameterImpl.class);
+        digester.addSetNext("faces-config/faces-config-extension/view-pool-mapping/parameter", "addParameter");
+        digester.addCallMethod("faces-config/faces-config-extension/view-pool-mapping/parameter/name", "setName", 0);
+        digester.addCallMethod("faces-config/faces-config-extension/view-pool-mapping/parameter/value", "setValue", 0);
     }
 
     private void postProcessFacesConfig(String systemId, FacesConfigImpl config)

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesConfigExtensionImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesConfigExtensionImpl.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesConfigExtensionImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesConfigExtensionImpl.java Fri Dec 13 01:18:08 2013
@@ -19,7 +19,9 @@
 package org.apache.myfaces.config.impl.digester.elements;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import org.apache.myfaces.config.element.ViewPoolMapping;
 
 /**
  * 
@@ -35,6 +37,9 @@ public class FacesConfigExtensionImpl ex
     
     private List<org.apache.myfaces.config.element.FaceletsProcessing> _faceletsProcessingList = 
         new ArrayList<org.apache.myfaces.config.element.FaceletsProcessing>();
+    
+    private List<ViewPoolMapping> viewPoolMappings;
+    private transient List<ViewPoolMapping> unmodifiableViewPoolMappings;
 
     @Override
     public List<org.apache.myfaces.config.element.FaceletsProcessing> getFaceletsProcessingList()
@@ -46,4 +51,28 @@ public class FacesConfigExtensionImpl ex
     {
         _faceletsProcessingList.add(elem);
     }
+    
+    @Override
+    public List<ViewPoolMapping> getViewPoolMappings()
+    {
+        if (viewPoolMappings == null)
+        {
+            return Collections.emptyList();
+        }
+        if (unmodifiableViewPoolMappings == null)
+        {
+            unmodifiableViewPoolMappings = 
+                Collections.unmodifiableList(viewPoolMappings);
+        }
+        return unmodifiableViewPoolMappings;
+    }
+    
+    public void addViewPoolMapping(ViewPoolMapping mapping)
+    {
+        if (viewPoolMappings == null)
+        {
+            viewPoolMappings = new ArrayList<ViewPoolMapping>();
+        }
+        viewPoolMappings.add(mapping);
+    }
 }

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ViewPoolMappingImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ViewPoolMappingImpl.java?rev=1550609&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ViewPoolMappingImpl.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ViewPoolMappingImpl.java Fri Dec 13 01:18:08 2013
@@ -0,0 +1,68 @@
+/*
+ * 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.config.impl.digester.elements;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.myfaces.config.element.ViewPoolMapping;
+import org.apache.myfaces.config.element.ViewPoolParameter;
+
+/**
+ *
+ */
+public class ViewPoolMappingImpl extends ViewPoolMapping implements Serializable
+{
+    
+    private String urlPattern;
+    
+    private List<ViewPoolParameter> _parameterList;
+
+    public ViewPoolMappingImpl()
+    {
+        _parameterList = new ArrayList<ViewPoolParameter>();
+    }
+
+    /**
+     * @return the urlPattern
+     */
+    public String getUrlPattern()
+    {
+        return urlPattern;
+    }
+
+    /**
+     * @param urlPattern the urlPattern to set
+     */
+    public void setUrlPattern(String urlPattern)
+    {
+        this.urlPattern = urlPattern;
+    }
+
+    @Override
+    public List<ViewPoolParameter> getParameterList()
+    {
+        return _parameterList;
+    }
+    
+    public void addParameter(ViewPoolParameter parameter)
+    {
+        _parameterList.add(parameter);
+    }
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ViewPoolMappingImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ViewPoolParameterImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ViewPoolParameterImpl.java?rev=1550609&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ViewPoolParameterImpl.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ViewPoolParameterImpl.java Fri Dec 13 01:18:08 2013
@@ -0,0 +1,58 @@
+/*
+ * 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.config.impl.digester.elements;
+
+import org.apache.myfaces.config.element.ViewPoolParameter;
+
+/**
+ *
+ */
+public class ViewPoolParameterImpl extends ViewPoolParameter
+{
+    private String _name;
+    private String _value;
+
+    @Override
+    public String getName()
+    {
+        return _name;
+    }
+
+    @Override
+    public String getValue()
+    {
+        return _value;
+    }
+
+    /**
+     * @param name the name to set
+     */
+    public void setName(String name)
+    {
+        this._name = name;
+    }
+
+    /**
+     * @param value the value to set
+     */
+    public void setValue(String value)
+    {
+        this._value = value;
+    }
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/ViewPoolParameterImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/RequestViewContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/RequestViewContext.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/RequestViewContext.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/RequestViewContext.java Fri Dec 13 01:18:08 2013
@@ -50,13 +50,20 @@ public class RequestViewContext
     
     private static final Set<VisitHint> VISIT_HINTS = Collections.unmodifiableSet( 
             EnumSet.of(VisitHint.SKIP_ITERATION));
+
+    private RequestViewMetadata requestViewMetadata;
     
-    private Map<ResourceDependency, Boolean> addedResources;
+    private Map<String, Boolean> renderTargetMap = null;
     
-    // No lazy init: every view has one (UIView.class) or more classes to process   
-    private Map<Class<?>, Boolean> processedClasses = new HashMap<Class<?>,Boolean>();
+    public RequestViewContext()
+    {
+        this.requestViewMetadata = new RequestViewMetadata();
+    }
     
-    private Map<String, Boolean> renderTargetMap = null;
+    public RequestViewContext(RequestViewMetadata rvm)
+    {
+        this.requestViewMetadata = new RequestViewMetadata();
+    }
 
     static public RequestViewContext getCurrentInstance()
     {
@@ -94,33 +101,63 @@ public class RequestViewContext
             return rvc;
         }
     }
-
-    public boolean isResourceDependencyAlreadyProcessed(ResourceDependency dependency)
+    
+    static public RequestViewContext getCurrentInstance(FacesContext ctx, UIViewRoot root, boolean create)
     {
-        if (addedResources == null)
+        if (create)
         {
-            return false;
+            return getCurrentInstance(ctx, root);
         }
-        return addedResources.containsKey(dependency); 
+        Map<UIViewRoot, RequestViewContext> map
+                = (Map<UIViewRoot, RequestViewContext>) ctx.getAttributes().get(VIEW_CONTEXT_KEY);
+        if (map != null)
+        {
+            return map.get(root);
+        }
+        return null;
     }
     
-    public void setResourceDependencyAsProcessed(ResourceDependency dependency)
+    static public RequestViewContext newInstance(RequestViewMetadata rvm)
+    {
+        RequestViewContext clone = new RequestViewContext(rvm.cloneInstance());
+        return clone;
+    }
+    
+    static public void setCurrentInstance(FacesContext ctx, UIViewRoot root, RequestViewContext rvc)
     {
-        if (addedResources == null)
+        Map<UIViewRoot, RequestViewContext> map
+                = (Map<UIViewRoot, RequestViewContext>) ctx.getAttributes().get(VIEW_CONTEXT_KEY);
+        if (map == null)
         {
-            addedResources = new HashMap<ResourceDependency,Boolean>();
+            map = new HashMap<UIViewRoot, RequestViewContext>();
+            rvc = new RequestViewContext();
+            map.put(root, rvc);
+            ctx.getAttributes().put(VIEW_CONTEXT_KEY, map);
+        }
+        else
+        {
+            map.put(root, rvc);
         }
-        addedResources.put(dependency, true);
+    }
+
+    public boolean isResourceDependencyAlreadyProcessed(ResourceDependency dependency)
+    {
+        return requestViewMetadata.isResourceDependencyAlreadyProcessed(dependency);
+    }
+    
+    public void setResourceDependencyAsProcessed(ResourceDependency dependency)
+    {
+        requestViewMetadata.setResourceDependencyAsProcessed(dependency);
     }
 
     public boolean isClassAlreadyProcessed(Class<?> inspectedClass)
     {
-        return processedClasses.containsKey(inspectedClass);
+        return requestViewMetadata.isClassAlreadyProcessed(inspectedClass);
     }
 
     public void setClassProcessed(Class<?> inspectedClass)
     {
-        processedClasses.put(inspectedClass, Boolean.TRUE);
+        requestViewMetadata.setClassProcessed(inspectedClass);
     }
     
     public boolean isRenderTarget(String target)
@@ -186,4 +223,17 @@ public class RequestViewContext
             return VisitResult.ACCEPT;
         }
     }
+    
+    public RequestViewMetadata getRequestViewMetadata()
+    {
+        return requestViewMetadata;
+    }
+
+    /**
+     * @param requestViewMetadata the requestViewMetadata to set
+     */
+    public void setRequestViewMetadata(RequestViewMetadata requestViewMetadata)
+    {
+        this.requestViewMetadata = requestViewMetadata;
+    }
 }

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/RequestViewMetadata.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/RequestViewMetadata.java?rev=1550609&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/RequestViewMetadata.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/RequestViewMetadata.java Fri Dec 13 01:18:08 2013
@@ -0,0 +1,176 @@
+/*
+ * 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.context;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.faces.application.ResourceDependency;
+import javax.faces.context.FacesContext;
+import org.apache.myfaces.view.facelets.el.ELText;
+
+/**
+ *
+ * @author lu4242
+ */
+public class RequestViewMetadata implements Serializable
+{
+    public static final String RESOURCE_DEPENDENCY_KEY = "oam.component.resource.RDK";
+
+    // No lazy init: every view has one (UIView.class) or more classes to process   
+    private Map<Class<?>, Boolean> processedClasses = new HashMap<Class<?>,Boolean>();
+    
+    private Map<ResourceDependency, Boolean> addedResources;
+    
+    private Map<Class<?>, Boolean> initialProcessedClasses;
+    private Map<ResourceDependency, Boolean> initialAddedResources;
+    
+    public RequestViewMetadata()
+    {
+        initialProcessedClasses = null;
+        initialAddedResources = null;
+    }
+    
+    /**
+     * Clone the current request view metadata into another instance, so 
+     * it can be used in a view.
+     * 
+     * @return 
+     */
+    public RequestViewMetadata cloneInstance()
+    {
+        RequestViewMetadata rvm = new RequestViewMetadata();
+        rvm.initialProcessedClasses = new HashMap<Class<?>, Boolean>(
+                this.initialProcessedClasses != null ? 
+                    this.initialProcessedClasses : this.processedClasses);
+        if (this.initialAddedResources != null)
+        {
+            rvm.initialAddedResources = new HashMap<ResourceDependency, Boolean>(
+                    this.initialAddedResources);
+        }
+        else if (this.addedResources != null)
+        {
+            rvm.initialAddedResources = new HashMap<ResourceDependency, Boolean>(
+                    this.addedResources);
+        }
+        return rvm;
+    }
+    
+    public boolean isResourceDependencyAlreadyProcessed(ResourceDependency dependency)
+    {
+        if (initialAddedResources != null)
+        {
+            if (initialAddedResources.containsKey(dependency))
+            {
+                return true;
+            }
+        }
+        if (addedResources == null)
+        {
+            return false;
+        }
+        return addedResources.containsKey(dependency); 
+    }
+    
+    public void setResourceDependencyAsProcessed(ResourceDependency dependency)
+    {
+        if (addedResources == null)
+        {
+            addedResources = new HashMap<ResourceDependency,Boolean>();
+        }
+        addedResources.put(dependency, true);
+    }
+
+    public boolean isClassAlreadyProcessed(Class<?> inspectedClass)
+    {
+        if (initialProcessedClasses != null)
+        {
+            if (initialProcessedClasses.containsKey(inspectedClass))
+            {
+                return true;
+            }
+        }
+        return processedClasses.containsKey(inspectedClass);
+    }
+
+    public void setClassProcessed(Class<?> inspectedClass)
+    {
+        processedClasses.put(inspectedClass, Boolean.TRUE);
+    }
+    
+    public Map<String, List<ResourceDependency>> getResourceDependencyAnnotations(FacesContext context)
+    {
+        if (initialAddedResources == null && addedResources == null)
+        {
+            return Collections.emptyMap();
+        }
+        Map<String, List<ResourceDependency>> map = new HashMap<String, List<ResourceDependency>>();
+        //List<ResourceDependency> list = new ArrayList<ResourceDependency>();
+        if (initialAddedResources != null)
+        {
+            for (ResourceDependency annotation : initialAddedResources.keySet())
+            {
+                String target = annotation.target();
+                if (target != null && target.length() > 0)
+                {
+                    target = ELText.parse(context.getApplication().getExpressionFactory(),
+                                          context.getELContext(), target).toString(context.getELContext());
+                }
+                else
+                {
+                    target = "head";
+                }
+                List<ResourceDependency> list = map.get(target);
+                if (list == null)
+                {
+                    list = new ArrayList<ResourceDependency>();
+                    map.put(target, list);
+                }
+                list.add(annotation);
+            }
+        }
+        if (addedResources != null)
+        {
+            for (ResourceDependency annotation : addedResources.keySet())
+            {
+                String target = annotation.target();
+                if (target != null && target.length() > 0)
+                {
+                    target = ELText.parse(context.getApplication().getExpressionFactory(),
+                                          context.getELContext(), target).toString(context.getELContext());
+                }
+                else
+                {
+                    target = "head";
+                }
+                List<ResourceDependency> list = map.get(target);
+                if (list == null)
+                {
+                    list = new ArrayList<ResourceDependency>();
+                    map.put(target, list);
+                }
+                list.add(annotation);
+            }
+        }
+        return map;
+    }
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/RequestViewMetadata.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImplBase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImplBase.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImplBase.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/context/servlet/FacesContextImplBase.java Fri Dec 13 01:18:08 2013
@@ -50,6 +50,7 @@ import org.apache.myfaces.el.unified.Fac
  */
 public abstract class FacesContextImplBase extends FacesContext
 {
+    public final static String SKIP_CLEAR_VIEW_MAP_HINT = "oam.fc.skipClearViewMapHint";
 
     private Application _application;
     private ExternalContext _externalContext;
@@ -278,11 +279,14 @@ public abstract class FacesContextImplBa
         // the clear method must be called on the Map returned from UIViewRoot.getViewMap().
         if (_viewRoot != null && !_viewRoot.equals(viewRoot))
         {
-            //call getViewMap(false) to prevent unnecessary map creation
-            Map<String, Object> viewMap = _viewRoot.getViewMap(false);
-            if (viewMap != null)
+            if (!Boolean.TRUE.equals(getAttributes().get(SKIP_CLEAR_VIEW_MAP_HINT)))
             {
-                viewMap.clear();
+                //call getViewMap(false) to prevent unnecessary map creation
+                Map<String, Object> viewMap = _viewRoot.getViewMap(false);
+                if (viewMap != null)
+                {
+                    viewMap.clear();
+                }
             }
         }
         _viewRoot = viewRoot;

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ApplyRequestValuesExecutor.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ApplyRequestValuesExecutor.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ApplyRequestValuesExecutor.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ApplyRequestValuesExecutor.java Fri Dec 13 01:18:08 2013
@@ -20,6 +20,7 @@ package org.apache.myfaces.lifecycle;
 
 import javax.faces.context.FacesContext;
 import javax.faces.event.PhaseId;
+import org.apache.myfaces.view.facelets.ViewPoolProcessor;
 
 /**
  * Implements the apply request values phase (JSF Spec 2.2.2)
@@ -29,6 +30,9 @@ import javax.faces.event.PhaseId;
  */
 class ApplyRequestValuesExecutor extends PhaseExecutor
 {
+    private ViewPoolProcessor viewPoolProcessor;
+    private boolean initialized = false;
+
     public boolean execute(FacesContext facesContext)
     {
         if (facesContext.getViewRoot() == null)
@@ -36,6 +40,12 @@ class ApplyRequestValuesExecutor extends
             throw new ViewNotFoundException("A view is required to execute "+facesContext.getCurrentPhaseId());
         }
         facesContext.getViewRoot().processDecodes(facesContext);
+        
+        ViewPoolProcessor processor = getViewPoolProcessor(facesContext);
+        if (processor != null)
+        {
+            processor.processDeferredNavigation(facesContext);
+        }
         return false;
     }
 
@@ -43,4 +53,14 @@ class ApplyRequestValuesExecutor extends
     {
         return PhaseId.APPLY_REQUEST_VALUES;
     }
+    
+    private ViewPoolProcessor getViewPoolProcessor(FacesContext context)
+    {
+        if (!initialized)
+        {
+            viewPoolProcessor = ViewPoolProcessor.getInstance(context);
+            initialized = true;
+        }
+        return viewPoolProcessor;
+    }
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/InvokeApplicationExecutor.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/InvokeApplicationExecutor.java?rev=1550609&r1=1550608&r2=1550609&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/InvokeApplicationExecutor.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/InvokeApplicationExecutor.java Fri Dec 13 01:18:08 2013
@@ -20,6 +20,7 @@ package org.apache.myfaces.lifecycle;
 
 import javax.faces.context.FacesContext;
 import javax.faces.event.PhaseId;
+import org.apache.myfaces.view.facelets.ViewPoolProcessor;
 
 /**
  * Implements the invoke application phase (JSF Spec 2.2.5)
@@ -29,6 +30,9 @@ import javax.faces.event.PhaseId;
  */
 class InvokeApplicationExecutor extends PhaseExecutor
 {
+    private ViewPoolProcessor viewPoolProcessor;
+    private boolean initialized = false;
+    
     public boolean execute(FacesContext facesContext)
     {
         if (facesContext.getViewRoot() == null)
@@ -36,6 +40,13 @@ class InvokeApplicationExecutor extends 
             throw new ViewNotFoundException("A view is required to execute "+facesContext.getCurrentPhaseId());
         }
         facesContext.getViewRoot().processApplication(facesContext);
+        
+        ViewPoolProcessor processor = getViewPoolProcessor(facesContext);
+        if (processor != null)
+        {
+            processor.processDeferredNavigation(facesContext);
+        }
+        
         return false;
     }
 
@@ -43,4 +54,14 @@ class InvokeApplicationExecutor extends 
     {
         return PhaseId.INVOKE_APPLICATION;
     }
+    
+    private ViewPoolProcessor getViewPoolProcessor(FacesContext context)
+    {
+        if (!initialized)
+        {
+            viewPoolProcessor = ViewPoolProcessor.getInstance(context);
+            initialized = true;
+        }
+        return viewPoolProcessor;
+    }
 }