/*
 * 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;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.application.Application;
import javax.faces.application.NavigationHandler;
import javax.faces.application.ProjectStage;
import javax.faces.application.ResourceDependency;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseId;
import javax.faces.view.StateManagementStrategy;
import javax.faces.view.ViewDeclarationLanguage;
import org.apache.myfaces.application.StateManagerImpl;
import org.apache.myfaces.component.ComponentResourceContainer;
import org.apache.myfaces.context.RequestViewContext;
import org.apache.myfaces.context.RequestViewMetadata;
import org.apache.myfaces.lifecycle.RestoreViewSupport;
import org.apache.myfaces.config.MyfacesConfig;
import org.apache.myfaces.util.WebConfigParamUtils;
import org.apache.myfaces.view.facelets.impl.FaceletCompositionContextImpl;
import org.apache.myfaces.view.facelets.pool.ViewPool;
import org.apache.myfaces.view.facelets.pool.ViewPoolFactory;
import org.apache.myfaces.view.facelets.pool.ViewEntry;
import org.apache.myfaces.view.facelets.pool.ViewStructureMetadata;
import org.apache.myfaces.view.facelets.pool.impl.ViewPoolFactoryImpl;
import org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport;
import org.apache.myfaces.view.facelets.tag.jsf.FaceletState;

/**
 * This class is reponsible for all processing tasks related to the view pool.
 * 
 * For enable the pool only for a subset of your views, you can
 * add an entry inside faces-config.xml file like this:
 * <pre>
 * {@code 
 * <faces-config-extension>
 *   <view-pool-mapping>
 *      <url-pattern>/*</url-pattern>
 *      <parameter>
 *          <name>org.apache.myfaces.VIEW_POOL_MAX_POOL_SIZE</name>
 *          <value>5</value>
 *      </parameter>
 *  </view-pool-mapping>
 * </faces-config-extension>
 * }
 * </pre>
 * 
 * @author Leonardo Uribe
 */
public class ViewPoolProcessor
{
    /**
     * Used to hold the view pool processor instance on the application map. 
     * A ViewPoolProcessor is only accessible if the view pool has been
     * enabled for the whole application (using a web config parameter) or 
     * partially (an &lt;view-pool-mapping&gt; entry inside &lt;faces-config-extension&gt;).
     */
    private final static String INSTANCE = "oam.ViewPoolProcessor";
    
    /**
     * UIViewRoot attribute to enable/disable the view for use pooling.
     */
    public final static String ENABLE_VIEW_POOL = "oamEnableViewPool";
    
    /**
     * Flag that indicates to the StateManagementStrategy that no state needs 
     * to be stored and we are using saveState() to dispose the view and store it
     * into the pool directly.
     */
    public final static String FORCE_HARD_RESET = "oam.ViewPool.forceHardReset";
    
    /**
     * Flag to indicate that dispose this view on navigation is valid.
     */
    public final static String DISPOSE_VIEW_NAVIGATION = "oam.ViewPool.disposeViewOnNavigation";
    
    /**
     * Attribute of UIViewRoot that indicates if a soft (1) or hard(2) 
     * (reset and check) reset is required in the call to saveState().
     */
    public final static String RESET_SAVE_STATE_MODE_KEY ="oam.view.resetSaveStateMode";
    
    /**
     * Indicates no reset should be done on this state saving
     */
    public static final Integer RESET_MODE_OFF = 0;
    
    /**
     * Indicates a soft reset should be done when saveState(...) is performed,
     * which means all transient state should be cleared but the delta state 
     * should not be destroyed in the process.
     */
    public static final Integer RESET_MODE_SOFT = 1;
    
    /**
     * Indicates a hard reset should be done when saveState(...) is performed,
     * which means all transient and delta state should be cleared, destroying
     * all existing state in the process. If something cannot be reseted, the 
     * state should return non null, so the algorithm can remove the component
     * from the tree and mark the tree as partial (requires refresh before
     * reuse).
     */
    public static final Integer RESET_MODE_HARD = 2;
    
    /**
     * Param used to indicate a "deferred navigation" needs to be done. To allow the view pool to
     * dispose the view properly (and reuse it later), it is necessary to ensure the view is not
     * being used at the moment. If the navigation call occur inside an action listener, the current
     * view is being used and cannot be disposed (because it conflicts with hard/soft reset). This
     * extension allows to call handleNavigation() before end invoke application phase, but after
     * traverse the component tree. 
     */
    public static final String INVOKE_DEFERRED_NAVIGATION = "oam.invoke.navigation";

    private ViewPoolFactory viewPoolFactory;
    private RestoreViewSupport restoreViewSupport;
    
    public ViewPoolProcessor(FacesContext context)
    {
        viewPoolFactory = new ViewPoolFactoryImpl(context);
        restoreViewSupport = new RestoreViewSupport(context);
    }
    
    public static ViewPoolProcessor getInstance(FacesContext context)
    {
        return (ViewPoolProcessor) context.getExternalContext().getApplicationMap().get(INSTANCE);
    }
    
    /**
     * This method should be called at startup to decide if a view processor should be
     * provided or not to the runtime.
     * 
     * @param context 
     */
    public static void initialize(FacesContext context)
    {
        if (context.isProjectStage(ProjectStage.Production))
        {
            MyfacesConfig myfacesConfig = MyfacesConfig.getCurrentInstance(context);
            
            boolean initialize = true;

            if (myfacesConfig.getELExpressionCacheMode() != ELExpressionCacheMode.alwaysRecompile)
            {
                Logger.getLogger(ViewPoolProcessor.class.getName()).log(Level.INFO,
                        MyfacesConfig.CACHE_EL_EXPRESSIONS
                                + " web config parameter is set to \""
                                + ((myfacesConfig.getELExpressionCacheMode() == null)
                                        ? "none" : myfacesConfig.getELExpressionCacheMode())
                                + "\". To enable view pooling this param"
                                + " must be set to \"alwaysRecompile\". View Pooling disabled.");
                initialize = false;
            }
            
            long refreshPeriod = WebConfigParamUtils.getLongInitParameter(context.getExternalContext(),
                    ViewHandler.FACELETS_REFRESH_PERIOD_PARAM_NAME,
                    FaceletViewDeclarationLanguage.DEFAULT_REFRESH_PERIOD_PRODUCTION);

            if (refreshPeriod != -1)
            {
                Logger.getLogger(ViewPoolProcessor.class.getName()).log(
                    Level.INFO, ViewHandler.FACELETS_REFRESH_PERIOD_PARAM_NAME +
                    " web config parameter is set to \"" + Long.toString(refreshPeriod) +
                    "\". To enable view pooling this param"+
                    " must be set to \"-1\". View Pooling disabled.");
                initialize = false;
            }
            
            if (myfacesConfig.isStrictJsf2FaceletsCompatibility())
            {
                Logger.getLogger(ViewPoolProcessor.class.getName()).log(
                    Level.INFO, MyfacesConfig.STRICT_JSF_2_FACELETS_COMPATIBILITY +
                    " web config parameter is set to \"" + "true" +
                    "\". To enable view pooling this param "+
                    " must be set to \"false\". View Pooling disabled.");
                initialize = false;
            }
            
            if (initialize)
            {
                ViewPoolProcessor processor = new ViewPoolProcessor(context);
                context.getExternalContext().
                    getApplicationMap().put(INSTANCE, processor);
            }
        }
    }

    public ViewPool getViewPool(FacesContext context, UIViewRoot root)
    {
        if (root.isTransient())
        {
            // Stateless views cannot be pooled, because we are reusing
            // state saving algorithm for that.
            return null;
        }

        Boolean enableViewPool = (Boolean) root.getAttributes().get(ViewPoolProcessor.ENABLE_VIEW_POOL);
        if (enableViewPool != null && !Boolean.TRUE.equals(enableViewPool))
        {
            // view pool not enabled for this view.
            return null;
        }
        else
        {
            return viewPoolFactory.getViewPool(context, root);
        }
    }
    
    public boolean isViewPoolEnabledForThisView(FacesContext context, UIViewRoot root)
    {
        if (root.isTransient())
        {
            // Stateless views cannot be pooled, because we are reusing
            // state saving algorithm for that.
            return false;
        }

        Boolean enableViewPool = (Boolean) root.getAttributes().get(ViewPoolProcessor.ENABLE_VIEW_POOL);
        if (enableViewPool != null)
        {
            return enableViewPool;
        }

        ViewPool viewPool = getViewPool(context, root);
        if (viewPool != null)
        {
            return true;
        }

        return false;
    }

    public boolean isViewPoolStrategyAllowedForThisView(FacesContext context, UIViewRoot root)
    {
        // Check if the viewId is not null.
        if (root.getViewId() == null)
        {
            return false;
        }
        if (root.isTransient())
        {
            // Stateless views cannot be pooled, because we are reusing
            // state saving algorithm for that.
            return false;
        }
        
        // Check if the view is enabled or not for use pooling
        if (!isViewPoolEnabledForThisView(context, root))
        {
            return false;
        }

        // Check if the vdl is using PSS on this view (has a vdl and that vdl is facelets)
        ViewDeclarationLanguage vdl = context.getApplication().getViewHandler().
            getViewDeclarationLanguage(context, root.getViewId());
        if (vdl == null)
        {
            return false;
        }
        else if (!ViewDeclarationLanguage.FACELETS_VIEW_DECLARATION_LANGUAGE_ID.equals(vdl.getId()))
        {
            return false;
        }
        
        if (vdl.getStateManagementStrategy(context, root.getViewId()) == null)
        {
            return false;
        }
        return true;
    }

    public void setViewPoolDisabledOnThisView(FacesContext context, UIViewRoot root, boolean value)
    {
        root.getAttributes().put(ViewPoolProcessor.ENABLE_VIEW_POOL, !value);
    }
    
    /**
     * Takes the newView and restore the state taken as base the provided ViewEntry,
     * and then move all child components from oldView to newView, to finally obtain
     * a clean component tree.
     * 
     * @param context
     * @param newView
     * @param entry 
     */
    public void cloneAndRestoreView(FacesContext context, UIViewRoot newView, 
            ViewEntry entry, ViewStructureMetadata metadata)
    {
        UIViewRoot oldView = entry.getViewRoot();
        // retrieveViewRootInitialState(context, oldView)
        Object viewState = metadata.getViewRootState();
        Object newViewState;
        UIComponent metadataFacet = newView.getFacet(UIViewRoot.METADATA_FACET_NAME);
        if (viewState == null)
        {
            // (Optional, it should be always metadata)
            oldView.clearInitialState();
            viewState = oldView.saveState(context);
        }
        Map<String, Object> viewScopeMap = newView.getViewMap(false);
        if (viewScopeMap != null && !viewScopeMap.isEmpty())
        {
            newViewState = newView.saveState(context);
        }
        else
        {
            newViewState = null;
        }
        
        boolean oldProcessingEvents = context.isProcessingEvents();
        context.setProcessingEvents(false);
        try
        {
            if (oldView.getFacetCount() > 0)
            {
                List<String> facetKeys = new ArrayList<>(oldView.getFacets().keySet());

                for (String facetKey : facetKeys)
                {
                    //context.setProcessingEvents(false);
                    if (metadataFacet != null && UIViewRoot.METADATA_FACET_NAME.equals(facetKey) &&
                        !PhaseId.RESTORE_VIEW.equals(context.getCurrentPhaseId()))
                    {
                        // Metadata facet is special, it is created when ViewHandler.createView(...) is
                        // called, so it shouldn't be taken from the oldView, otherwise the state
                        // will be lost. Instead reuse it and discard the one in oldView.
                        // But on restore view phase, use the old one, because the new one does not
                        // have initial state marked.
                        newView.getFacets().put(facetKey, metadataFacet);
                    }
                    else
                    {
                        UIComponent facet = oldView.getFacets().remove(facetKey);
                        //context.setProcessingEvents(true);
                        newView.getFacets().put(facetKey, facet);
                    }
                }
            }
            if (oldView.getChildCount() > 0)
            {
                for (Iterator<UIComponent> it = oldView.getChildren().iterator(); it.hasNext();)
                {
                    //context.setProcessingEvents(false);
                    UIComponent c = it.next();
                    it.remove();
                    //context.setProcessingEvents(true);
                    newView.getChildren().add(c);
                }
            }
            
            // Restore the newView as saved just before markInitialState() call
            newView.restoreState(context, viewState);
            newView.markInitialState();
            
            if (!PhaseId.RESTORE_VIEW.equals(context.getCurrentPhaseId()))
            {
                // Restore bindings like in restore view phase, because in this case,
                // bindings needs to be set (Application.createComponent is not called!).
                restoreViewSupport.processComponentBinding(context, newView);
                
                // Restore view scope map if necessary
                if (viewScopeMap != null && !viewScopeMap.isEmpty())
                {
                    Map<String, Object> newViewScopeMap = newView.getViewMap(false);
                    if (newViewScopeMap == null)
                    {
                        newView.restoreViewScopeState(context, newViewState);
                    }
                    else
                    {
                        // Should theoretically not happen, because when a pooled static view 
                        // is saved, the view scope map is skipped, otherwise it could be a
                        // leak. Anyway, we let this code here that overrides the values from
                        // the original map.
                        for (Map.Entry<String, Object> entry2 : viewScopeMap.entrySet())
                        {
                            newViewScopeMap.put(entry2.getKey(), entry2.getValue());
                        }
                    }
                }
            }
            
            // Update request view metadata to ensure resource list is restored as when the
            // view was built on the first time. This ensures correct calculation of added 
            // resources by dynamic behavior. 
            RequestViewContext rcv = RequestViewContext.getCurrentInstance(context, newView, false);
            if (rcv != null)
            {
                rcv.setRequestViewMetadata(metadata.getRequestViewMetadata().cloneInstance());
            }
            else
            {
                RequestViewContext.setCurrentInstance(context, newView,
                        RequestViewContext.newInstance(metadata.getRequestViewMetadata().cloneInstance()));
            }
        }
        finally
        {
            context.setProcessingEvents(oldProcessingEvents);
        }
    }
    
    public void storeViewStructureMetadata(FacesContext context, UIViewRoot root)
    {
        ViewPool viewPool = getViewPool(context, root);
        if (viewPool != null)
        {
            FaceletState faceletState = (FaceletState) root.getAttributes().get(
                    ComponentSupport.FACELET_STATE_INSTANCE);
            boolean isDynamic = faceletState != null ? faceletState.isDynamic() : false;
            if (!isDynamic)
            {
                viewPool.storeStaticViewStructureMetadata(context, root, faceletState);            
            }
            else
            {
                viewPool.storeDynamicViewStructureMetadata(context, root, faceletState);
            }
        }
    }
    
    public ViewStructureMetadata retrieveViewStructureMetadata(FacesContext context, UIViewRoot root)
    {
        ViewPool viewPool = getViewPool(context, root);
        if (viewPool != null)
        {
            FaceletState faceletState = (FaceletState) root.getAttributes().get(
                    ComponentSupport.FACELET_STATE_INSTANCE);
            boolean isDynamic = faceletState != null ? faceletState.isDynamic() : false;
            if (!isDynamic)
            {
                return viewPool.retrieveStaticViewStructureMetadata(context, root);
            }
            else
            {
                return viewPool.retrieveDynamicViewStructureMetadata(context, root, faceletState);
            }
        }
        return null;
    }
    
    public void pushResetableView(FacesContext context, UIViewRoot view, FaceletState faceletViewState)
    {
        ViewPool viewPool = getViewPool(context, view);
        if (viewPool != null)
        {
            boolean isDynamic = faceletViewState != null ? faceletViewState.isDynamic() : false;
            if (!isDynamic)
            {
                clearTransientAndNonFaceletComponentsForStaticView(context, view);
                viewPool.pushStaticStructureView(context, view);
            }
            else
            {
                ViewStructureMetadata viewStructureMetadata = viewPool.retrieveDynamicViewStructureMetadata(
                    context, view, faceletViewState);
                if (viewStructureMetadata != null)
                {
                    clearTransientAndNonFaceletComponentsForDynamicView(context, view, viewStructureMetadata);
                    viewPool.pushDynamicStructureView(context, view, faceletViewState);
                }
            }
        }
    }
    
    public void pushPartialView(FacesContext context, UIViewRoot view, FaceletState faceletViewState, int count)
    {
        ViewPool viewPool = getViewPool(context, view);
        
        if (viewPool != null && viewPool.isWorthToRecycleThisView(context, view))
        {
            ViewStructureMetadata viewStructureMetadata = null;
            if (faceletViewState == null)
            {
                viewStructureMetadata = viewPool.retrieveStaticViewStructureMetadata(context, view);
            }
            else
            {
                viewStructureMetadata = viewPool.retrieveDynamicViewStructureMetadata(
                    context, view, faceletViewState);
            }
            if (viewStructureMetadata != null)
            {
                ClearPartialTreeContext ptc = new ClearPartialTreeContext();
                // add partial structure view to the map.
                clearTransientAndRemoveNonResetableComponents(context, ptc, view, viewStructureMetadata);
                int reusableCount = ptc.getCount();
                float factor = ((float) reusableCount) / ((float) count);
                if (factor > 0.3f)
                {
                    viewPool.pushPartialStructureView(context, view);
                }
            }
        }        
    }
    
    protected void clearTransientAndNonFaceletComponentsForStaticView(FacesContext context, UIViewRoot root)
    {
        // In a static view, clear components that are both transient and non bound to any facelet tag handler
        // is quite simple. Since the structure of the view is static, there is no need to check component resources.
        clearTransientAndNonFaceletComponents(context, root);
    }
    
    public void clearTransientAndNonFaceletComponentsForDynamicView(final FacesContext context, 
            final UIViewRoot root, final ViewStructureMetadata viewStructureMetadata)
    {
        //Scan children
        int childCount = root.getChildCount();
        if (childCount > 0)
        {
            for (int i = 0; i < childCount; i++)
            {
                UIComponent child = root.getChildren().get(i);
                if (child != null && child.isTransient() &&
                    child.getAttributes().get(ComponentSupport.MARK_CREATED) == null)
                {
                    root.getChildren().remove(i);
                    i--;
                    childCount--;
                }
                else
                {
                    if (child.getChildCount() > 0 || !child.getFacets().isEmpty())
                    {
                        clearTransientAndNonFaceletComponents(context, child);
                    }
                }
            }
        }

        clearTransientAndNonFaceletComponentsForDynamicViewUIViewRootFacets(
            context, root, viewStructureMetadata);
    }
    
    private void clearTransientAndNonFaceletComponentsForDynamicViewUIViewRootFacets(final FacesContext context, 
            final UIViewRoot root, ViewStructureMetadata viewStructureMetadata)
    {
        
        //Scan facets
        if (root.getFacetCount() > 0)
        {
            Map<String, UIComponent> facets = root.getFacets();
            for (Iterator<UIComponent> itr = facets.values().iterator(); itr.hasNext();)
            {
                UIComponent fc = itr.next();
                if (fc != null && !(fc instanceof ComponentResourceContainer))
                {
                    if ( fc.isTransient() &&
                        fc.getAttributes().get(ComponentSupport.MARK_CREATED) == null)
                    {
                        itr.remove();
                    }
                    else
                    {
                        if (fc.getChildCount() > 0 || !fc.getFacets().isEmpty())
                        {
                            clearTransientAndNonFaceletComponents(context, fc);
                        }
                    }
                }
                else if (fc != null)
                {
                    // In a facet which is a ComponentResourceContainer instance,
                    // we need to check these two cases:
                    // 1. Resources relocated by facelets
                    // 2. Resources created by effect of a @ResourceDependency annotation
                    if (fc.getId() != null
                            && fc.getId().startsWith(FaceletCompositionContextImpl.JAVAX_FACES_LOCATION_PREFIX))
                    {
                        String target = fc.getId().substring(
                                FaceletCompositionContextImpl.JAVAX_FACES_LOCATION_PREFIX.length());
                        Map<String, List<ResourceDependency>> addedResources = 
                            viewStructureMetadata.getRequestViewMetadata().
                                getResourceDependencyAnnotations(context);
                        List<ResourceDependency> resourceDependencyList = (addedResources != null) ?
                            addedResources.get(target) : null;

                        clearComponentResourceContainer(context, fc, resourceDependencyList);
                    }
                }
            }
        }
    }
    
    private void clearComponentResourceContainer(final FacesContext context, UIComponent component,
        List<ResourceDependency> resourceDependencyList)
    {
        //Scan children
        int childCount = component.getChildCount();
        if (childCount > 0)
        {
            for (int i = 0; i < childCount; i++)
            {
                UIComponent child = component.getChildren().get(i);
                String id = (String) child.getAttributes().get(ComponentSupport.MARK_CREATED);
                if (child != null && child.isTransient() && id == null)
                {
                    //Remove both transient not facelets bound components
                    component.getChildren().remove(i);
                    i--;
                    childCount--;
                }
                else if (id != null)
                {
                    // If it has an id set, it is a facelet component resource.
                    // The refresh algorithm take care of the cleanup.
                }
                /*
                else if (!child.isTransient() && id != null && !faceletResources.contains(id))
                {
                    // check if the resource has a facelet tag in this "dynamic state", if not
                    // remove it. Really leave a component resource does not harm, but 
                    // the objective is make this view as close as when if it is built as new.
                    component.getChildren().remove(i);
                    i--;
                    childCount--;
                }*/
                else
                {
                    // Check if the component instance was created using a @ResourceDependency annotation
                    Object[] rdk = (Object[]) child.getAttributes().get(RequestViewMetadata.RESOURCE_DEPENDENCY_KEY);
                    if (rdk != null)
                    {
                        boolean found = false;
                        String library = (String) rdk[0];
                        String name = (String) rdk[1];
                        if (resourceDependencyList != null)
                        {
                            for (ResourceDependency resource : resourceDependencyList)
                            {
                                if (library == null && resource.library() == null)
                                {
                                    if (name != null && name.equals(resource.name()))
                                    {
                                        found = true;
                                        break;
                                    }
                                }
                                else
                                {
                                    if (library != null && library.equals(resource.library()) &&
                                        name != null && name.equals(resource.name()) )
                                    {
                                        found = true;
                                        break;
                                    }
                                }
                            }
                        }
                        if (!found)
                        {
                            //Remove it, because for this dynamic state it it does not exists.
                            component.getChildren().remove(i);
                            i--;
                            childCount--;
                        }
                        // If found just leave it.
                    }
                    else
                    {
                        if (child.getChildCount() > 0 || !child.getFacets().isEmpty())
                        {
                            clearTransientAndNonFaceletComponents(context, child);
                        }
                    }
                }
            }
        }
    }

    /**
     * Clear all transient components not created by facelets algorithm. In this way,
     * we ensure the component tree does not have any changes done after markInitialState.
     * 
     * @param context
     * @param component 
     */
    private void clearTransientAndNonFaceletComponents(final FacesContext context, final UIComponent component)
    {
        //Scan children
        int childCount = component.getChildCount();
        if (childCount > 0)
        {
            for (int i = 0; i < childCount; i++)
            {
                UIComponent child = component.getChildren().get(i);
                if (child != null && child.isTransient() &&
                    child.getAttributes().get(ComponentSupport.MARK_CREATED) == null)
                {
                    component.getChildren().remove(i);
                    i--;
                    childCount--;
                }
                else
                {
                    if (child.getChildCount() > 0 || !child.getFacets().isEmpty())
                    {
                        clearTransientAndNonFaceletComponents(context, child);
                    }
                }
            }
        }

        //Scan facets
        if (component.getFacetCount() > 0)
        {
            Map<String, UIComponent> facets = component.getFacets();
            for (Iterator<UIComponent> itr = facets.values().iterator(); itr.hasNext();)
            {
                UIComponent fc = itr.next();
                if (fc != null && fc.isTransient() &&
                    fc.getAttributes().get(ComponentSupport.MARK_CREATED) == null)
                {
                    itr.remove();
                }
                else
                {
                    if (fc.getChildCount() > 0 || !fc.getFacets().isEmpty())
                    {
                        clearTransientAndNonFaceletComponents(context, fc);
                    }
                }
            }
        }
    }

    private void clearTransientAndRemoveNonResetableComponents(final FacesContext context, 
        final ClearPartialTreeContext ptc, final UIViewRoot root, 
        ViewStructureMetadata viewStructureMetadata)
    {
        //Scan children
        int childCount = root.getChildCount();

        try
        {
            root.getAttributes().put(ViewPoolProcessor.RESET_SAVE_STATE_MODE_KEY, ViewPoolProcessor.RESET_MODE_HARD);
            if (childCount > 0)
            {
                for (int i = 0; i < childCount; i++)
                {
                    UIComponent child = root.getChildren().get(i);
                    boolean containsFaceletId = child.getAttributes().containsKey(ComponentSupport.MARK_CREATED);
                    if (child != null && child.isTransient() && !containsFaceletId)
                    {
                        //Transient and not bound to facelets tag, remove it!.
                        root.getChildren().remove(i);
                        i--;
                        childCount--;
                    }
                    else
                    {
                        if (child.getAttributes().containsKey(ComponentSupport.COMPONENT_ADDED_BY_HANDLER_MARKER))
                        {
                            //Dynamically added or moved, remove it!
                            root.getChildren().remove(i);
                            i--;
                            childCount--;

                        }
                        else if (containsFaceletId ||
                            child.getAttributes().containsKey(ComponentSupport.COMPONENT_ADDED_BY_HANDLER_MARKER))
                        {
                            // Bound to a facelet tag or created by facelets, we have two options:
                            // 1. If is not transient, check its state and try to clear it, if fails remove it
                            // 2. If is transient, assume stateless, continue.
                            if (!child.isTransient())
                            {
                                // Remember that hard reset is already enabled.
                                Object state = child.saveState(context);
                                if (state == null)
                                {
                                    if (child.getChildCount() > 0 || !child.getFacets().isEmpty())
                                    {
                                        clearTransientAndRemoveNonResetableComponents(context, ptc, child);
                                    }
                                    ptc.incrementCount();
                                }
                                else
                                {
                                    root.getChildren().remove(i);
                                    i--;
                                    childCount--;
                                }
                            }
                            else
                            {
                                ptc.incrementCount();
                            }
                        }
                        else
                        {
                            // Non facelets component, remove it!.
                            root.getChildren().remove(i);
                            i--;
                            childCount--;
                        }
                    }
                }
            }

            clearTransientAndNonFaceletComponentsForDynamicViewUIViewRootFacets(
                context, root, viewStructureMetadata);
        }
        finally
        {
            root.getAttributes().put(ViewPoolProcessor.RESET_SAVE_STATE_MODE_KEY, 
                        ViewPoolProcessor.RESET_MODE_OFF);
        }
    }
    
    private void clearTransientAndRemoveNonResetableComponents(final FacesContext context,
        final ClearPartialTreeContext ptc, final UIComponent component)
    {
        //Scan children
        int childCount = component.getChildCount();
        if (childCount > 0)
        {
            for (int i = 0; i < childCount; i++)
            {
                UIComponent child = component.getChildren().get(i);
                boolean containsFaceletId = child.getAttributes().containsKey(ComponentSupport.MARK_CREATED);
                if (child.isTransient() && !containsFaceletId)
                {
                    //Transient and not bound to facelets tag, remove it!.
                    component.getChildren().remove(i);
                    i--;
                    childCount--;
                }
                else
                {
                    if (child.getAttributes().containsKey(ComponentSupport.COMPONENT_ADDED_BY_HANDLER_MARKER))
                    {
                        //Dynamically added or moved, remove it!
                        component.getChildren().remove(i);
                        i--;
                        childCount--;

                    }
                    else if (containsFaceletId ||
                        child.getAttributes().containsKey(ComponentSupport.COMPONENT_ADDED_BY_HANDLER_MARKER))
                    {
                        // Bound to a facelet tag or created by facelets, we have two options:
                        // 1. If is not transient, check its state and try to clear it, if fails remove it
                        // 2. If is transient, assume stateless, continue.
                        if (!child.isTransient())
                        {
                            // Remember that hard reset is already enabled.
                            Object state = child.saveState(context);
                            if (state == null)
                            {
                                if (child.getChildCount() > 0 || !child.getFacets().isEmpty())
                                {
                                    clearTransientAndRemoveNonResetableComponents(context, ptc, child);
                                }
                                ptc.incrementCount();
                            }
                            else
                            {
                                component.getChildren().remove(i);
                                i--;
                                childCount--;
                            }
                        }
                        else
                        {
                            ptc.incrementCount();
                        }
                    }
                    else
                    {
                        // Non facelets component, remove it!.
                        component.getChildren().remove(i);
                        i--;
                        childCount--;
                    }
                }
            }
        }

        //Scan facets
        if (component.getFacetCount() > 0)
        {
            Map<String, UIComponent> facets = component.getFacets();
            for (Iterator<UIComponent> itr = facets.values().iterator(); itr.hasNext();)
            {
                UIComponent fc = itr.next();
                boolean containsFaceletId = fc.getAttributes().containsKey(ComponentSupport.MARK_CREATED);
                if (fc.isTransient() && !containsFaceletId)
                {
                    //Transient and not bound to facelets tag, remove it!.
                    itr.remove();
                }
                else
                {
                    if (fc.getAttributes().containsKey(ComponentSupport.COMPONENT_ADDED_BY_HANDLER_MARKER))
                    {
                        //Dynamically added or moved, remove it!
                        itr.remove();

                    }
                    else if (containsFaceletId ||
                        fc.getAttributes().containsKey(ComponentSupport.COMPONENT_ADDED_BY_HANDLER_MARKER))
                    {
                        // Bound to a facelet tag or created by facelets, we have two options:
                        // 1. If is not transient, check its state and try to clear it, if fails remove it
                        // 2. If is transient, assume stateless, continue.
                        if (!fc.isTransient())
                        {
                            // Remember that hard reset is already enabled.
                            Object state = fc.saveState(context);
                            if (state == null)
                            {
                                if (fc.getChildCount() > 0 || !fc.getFacets().isEmpty())
                                {
                                    clearTransientAndRemoveNonResetableComponents(context, ptc, fc);
                                }
                                ptc.incrementCount();
                            }
                            else
                            {
                                itr.remove();
                            }
                        }
                        else
                        {
                            ptc.incrementCount();
                        }
                    }
                    else
                    {
                        // Non facelets component, remove it!.
                        itr.remove();
                    }
                }
            }
        }
    }
    
    public void processDeferredNavigation(FacesContext facesContext)
    {
        Object[] command = (Object[]) facesContext.getAttributes().get(
            ViewPoolProcessor.INVOKE_DEFERRED_NAVIGATION);
        if (command != null)
        {
            try
            {
                facesContext.getAttributes().put(ViewPoolProcessor.DISPOSE_VIEW_NAVIGATION, Boolean.TRUE);
                NavigationHandler navigationHandler = facesContext.getApplication().getNavigationHandler();
                if (command.length == 3)
                {
                    navigationHandler.handleNavigation(facesContext, (String) command[0], (String) command[1], 
                        (String) command[2]);
                }
                else
                {
                    navigationHandler.handleNavigation(facesContext, (String) command[0], (String) command[1]);
                }
                //Render Response if needed
                facesContext.renderResponse();
                facesContext.getAttributes().remove(ViewPoolProcessor.INVOKE_DEFERRED_NAVIGATION);
            }
            finally
            {
                facesContext.getAttributes().remove(ViewPoolProcessor.DISPOSE_VIEW_NAVIGATION);
            }
        }
    }
    
    public void disposeView(FacesContext facesContext, UIViewRoot root)
    {
        if (root == null)
        {
            return;
        }

        String viewId = root.getViewId();
        if (viewId == null)
        {
            return;
        }
        Application app = facesContext.getApplication();
        if (app == null)
        {
            return;
        }
        ViewHandler viewHandler = app.getViewHandler();
        if (viewHandler == null)
        {
            return;
        }

        if (Boolean.TRUE.equals(facesContext.getAttributes().get(ViewPoolProcessor.DISPOSE_VIEW_NAVIGATION)))
        {
            ViewDeclarationLanguage vdl = facesContext.getApplication().
                    getViewHandler().getViewDeclarationLanguage(
                        facesContext, root.getViewId());

            if (vdl != null && ViewDeclarationLanguage.FACELETS_VIEW_DECLARATION_LANGUAGE_ID.equals(vdl.getId()))
            {
                StateManagementStrategy sms = vdl.getStateManagementStrategy(facesContext, root.getId());
                if (sms != null)
                {
                    // Force indirectly to store the map in the pool
                    facesContext.getAttributes().put(ViewPoolProcessor.FORCE_HARD_RESET, Boolean.TRUE);

                    try
                    {
                        Object state = sms.saveView(facesContext);
                    }
                    finally
                    {
                        facesContext.getAttributes().remove(ViewPoolProcessor.FORCE_HARD_RESET);
                    }

                    // Clear the calculated value from the application map
                    facesContext.getAttributes().remove(StateManagerImpl.SERIALIZED_VIEW_REQUEST_ATTR);
                }
            }
        }
    }
    
    private static class ClearPartialTreeContext 
    {
        private int count;
        
        public ClearPartialTreeContext()
        {
            count = 0;
        }

        public int getCount()
        {
            return count;
        }

        public int incrementCount()
        {
            return count++;
        }

        public void setCount(int count)
        {
            this.count = count;
        }
    }
}
