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<String>();
                facetKeys.addAll(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 cloneAndRestoreView ( FacesContext context , UIViewRoot newView , ViewEntry entry , ViewStructureMetadata metadata ) { UIViewRoot oldView = entry . getViewRoot ( ) ; Object viewState = metadata . getViewRootState ( ) ; Object newViewState ; UIComponent metadataFacet = newView . getFacet ( UIViewRoot . METADATA_FACET_NAME ) ; if ( viewState == null ) { 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 < String > ( ) ; facetKeys . addAll ( oldView . getFacets ( ) . keySet ( ) ) ; for ( String facetKey : facetKeys ) { if ( metadataFacet != null && UIViewRoot . METADATA_FACET_NAME . equals ( facetKey ) && ! PhaseId . RESTORE_VIEW . equals ( context . getCurrentPhaseId ( ) ) ) { newView . getFacets ( ) . put ( facetKey , metadataFacet ) ; } else { UIComponent facet = oldView . getFacets ( ) . remove ( facetKey ) ; newView . getFacets ( ) . put ( facetKey , facet ) ; } } } if ( oldView . getChildCount ( ) > 0 ) { for ( Iterator < UIComponent > it = oldView . getChildren ( ) . iterator ( ) ; it . hasNext ( ) ; ) { UIComponent c = it . next ( ) ; it . remove ( ) ; newView . getChildren ( ) . add ( c ) ; } } newView . restoreState ( context , viewState ) ; newView . markInitialState ( ) ; if ( ! PhaseId . RESTORE_VIEW . equals ( context . getCurrentPhaseId ( ) ) ) { restoreViewSupport . processComponentBinding ( context , newView ) ; if ( viewScopeMap != null && ! viewScopeMap . isEmpty ( ) ) { Map < String , Object > newViewScopeMap = newView . getViewMap ( false ) ; if ( newViewScopeMap == null ) { newView . restoreViewScopeState ( context , newViewState ) ; } else { for ( Map . Entry < String , Object > entry2 : viewScopeMap . entrySet ( ) ) { newViewScopeMap . put ( entry2 . getKey ( ) , entry2 . getValue ( ) ) ; } } } } 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 ) ; } }
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