myfaces-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tandrasc...@apache.org
Subject [myfaces] branch master updated: refactored
Date Mon, 24 Dec 2018 14:19:17 GMT
This is an automated email from the ASF dual-hosted git repository.

tandraschko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/myfaces.git


The following commit(s) were added to refs/heads/master by this push:
     new 575061d  refactored
575061d is described below

commit 575061d8c4a867bc3be3ad462533125a2b30f9de
Author: Thomas Andraschko <tandraschko@apache.org>
AuthorDate: Mon Dec 24 15:19:27 2018 +0100

    refactored
---
 impl/pom.xml                                       |   5 +
 .../DefaultNavigationHandlerSupport.java           |  49 ---
 .../application/FacesServletMappingUtils.java      |  23 ++
 .../myfaces/application/NavigationHandlerImpl.java |  45 +--
 .../myfaces/application/ViewHandlerImpl.java       |  32 +-
 .../myfaces/application/ViewHandlerSupport.java    |  46 ---
 ...tViewHandlerSupport.java => ViewIdSupport.java} | 433 +++++++++++----------
 .../org/apache/myfaces/config/MyfacesConfig.java   |  88 +++--
 .../apache/myfaces/context/RequestViewContext.java |  17 +-
 .../myfaces/lifecycle/CheckedViewIdsCache.java     |  92 -----
 .../lifecycle/DefaultRestoreViewSupport.java       | 266 -------------
 .../myfaces/lifecycle/RestoreViewExecutor.java     |  42 +-
 .../myfaces/lifecycle/RestoreViewSupport.java      | 189 +++++----
 .../resource/BaseResourceHandlerSupport.java       |  41 +-
 .../apache/myfaces/util/ViewProtectionUtils.java   |  25 +-
 .../VisitHintsHelper.java}                         |  27 +-
 .../org/apache/myfaces/view/ViewScopeProxyMap.java |   2 +-
 .../DefaultFaceletsStateManagementStrategy.java    |  26 +-
 .../facelets/FaceletViewDeclarationLanguage.java   |   9 +-
 .../myfaces/view/facelets/ViewPoolProcessor.java   |   3 +-
 .../view/jsp/JspViewDeclarationLanguageBase.java   |  11 +-
 .../myfaces/application/ViewIdSupportMockTest.java | 105 +++++
 .../ViewIdSupportTest.java}                        |  58 ++-
 .../lifecycle/DefaultRestoreViewSupport2Test.java  |  72 ----
 .../lifecycle/DefaultRestoreViewSupportTest.java   | 209 ----------
 .../myfaces/lifecycle/RestoreViewExecutorTest.java | 146 +------
 .../html/HtmlResponseStateManagerTest.java         |  58 +++
 .../org/apache/myfaces/test/FacesTestCase.java     |  13 +-
 .../facelets/FaceletMultipleRequestsTestCase.java  |   4 +-
 .../myfaces/view/facelets/FaceletTestCase.java     |   4 +-
 .../org/apache/myfaces/application/view1.jsp       |  27 ++
 .../org/apache/myfaces/application/view2.xhtml     |  25 ++
 parent/pom.xml                                     |   7 +
 33 files changed, 810 insertions(+), 1389 deletions(-)

diff --git a/impl/pom.xml b/impl/pom.xml
index 966d1b7..d0a8cb8 100644
--- a/impl/pom.xml
+++ b/impl/pom.xml
@@ -1089,6 +1089,11 @@
             <artifactId>easymockclassextension</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+        </dependency>
+
         <!-- jmock -->
         <dependency>
             <groupId>jmock</groupId>
diff --git a/impl/src/main/java/org/apache/myfaces/application/DefaultNavigationHandlerSupport.java b/impl/src/main/java/org/apache/myfaces/application/DefaultNavigationHandlerSupport.java
deleted file mode 100644
index 42c242f..0000000
--- a/impl/src/main/java/org/apache/myfaces/application/DefaultNavigationHandlerSupport.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.application;
-
-import javax.faces.context.FacesContext;
-import org.apache.myfaces.lifecycle.DefaultRestoreViewSupport;
-import org.apache.myfaces.lifecycle.RestoreViewSupport;
-
-/**
- *
- * @author lu4242
- */
-public class DefaultNavigationHandlerSupport extends NavigationHandlerSupport
-{
-    
-    private RestoreViewSupport restoreViewSupport;
-  
-    public DefaultNavigationHandlerSupport()
-    {
-        restoreViewSupport = new DefaultRestoreViewSupport();
-    }
-  
-    private RestoreViewSupport getRestoreViewSupport()
-    {
-        return restoreViewSupport;
-    }
-    
-    public String calculateViewId(FacesContext facesContext)
-    {
-        //Delegate to 
-        return getRestoreViewSupport().calculateViewId(facesContext);
-    }
-}
diff --git a/impl/src/main/java/org/apache/myfaces/application/FacesServletMappingUtils.java b/impl/src/main/java/org/apache/myfaces/application/FacesServletMappingUtils.java
index b790dab..be56321 100644
--- a/impl/src/main/java/org/apache/myfaces/application/FacesServletMappingUtils.java
+++ b/impl/src/main/java/org/apache/myfaces/application/FacesServletMappingUtils.java
@@ -21,6 +21,7 @@ package org.apache.myfaces.application;
 
 import java.util.Collection;
 import java.util.Map;
+import javax.faces.context.ExternalContext;
 
 import javax.faces.context.FacesContext;
 import javax.faces.webapp.FacesServlet;
@@ -36,6 +37,28 @@ public class FacesServletMappingUtils
     private static final String FACES_SERVLET_REGISTRATION = "org.apache.myfaces.FACES_SERVLET_REGISTRATION";
     private static final String FACES_SERVLET_MAPPINGS = "org.apache.myfaces.FACES_SERVLET_MAPPINGS";
     
+    private static final String CURRENT_REQUEST_FACES_SERVLET = "org.apache.myfaces.CURRENT_FACES_SERVLET_MAPPING";
+    
+    public static FacesServletMapping getCurrentRequestFacesServletMapping(FacesContext context)
+    {
+        Map<Object, Object> attributes = context.getAttributes();
+
+        // Has the mapping already been determined during this request?
+        FacesServletMapping mapping = (FacesServletMapping) attributes.get(CURRENT_REQUEST_FACES_SERVLET);
+        if (mapping == null)
+        {
+            ExternalContext externalContext = context.getExternalContext();
+            mapping = FacesServletMappingUtils.calculateFacesServletMapping(
+                    context,
+                    externalContext.getRequestServletPath(),
+                    externalContext.getRequestPathInfo(),
+                    true);
+
+            attributes.put(CURRENT_REQUEST_FACES_SERVLET, mapping);
+        }
+        return mapping;
+    }
+    
     public static ServletRegistration getFacesServletRegistration(FacesContext facesContext,
             ServletContext servletContext)
     {
diff --git a/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java b/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java
index e1c7ced..aae6f48 100755
--- a/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java
+++ b/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java
@@ -23,7 +23,6 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -46,7 +45,6 @@ import javax.faces.component.UIViewAction;
 import javax.faces.component.UIViewRoot;
 import javax.faces.component.visit.VisitCallback;
 import javax.faces.component.visit.VisitContext;
-import javax.faces.component.visit.VisitHint;
 import javax.faces.component.visit.VisitResult;
 import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
@@ -73,6 +71,7 @@ import org.apache.myfaces.util.HashMapUtils;
 import org.apache.myfaces.util.StringUtils;
 import org.apache.myfaces.util.FilenameUtils;
 import org.apache.myfaces.util.LangUtils;
+import org.apache.myfaces.util.VisitHintsHelper;
 import org.apache.myfaces.view.facelets.ViewPoolProcessor;
 import org.apache.myfaces.view.facelets.tag.jsf.PreDisposeViewEvent;
 
@@ -81,16 +80,10 @@ import org.apache.myfaces.view.facelets.tag.jsf.PreDisposeViewEvent;
  * @author Anton Koinov
  * @version $Revision$ $Date$
  */
-public class NavigationHandlerImpl
-    extends ConfigurableNavigationHandler
+public class NavigationHandlerImpl extends ConfigurableNavigationHandler
 {
     private static final Logger log = Logger.getLogger(NavigationHandlerImpl.class.getName());
 
-    private static final String SKIP_ITERATION_HINT = "javax.faces.visit.SKIP_ITERATION";
-    
-    private static final Set<VisitHint> VISIT_HINTS = Collections.unmodifiableSet(
-            EnumSet.of(VisitHint.SKIP_ITERATION));    
-    
     private static final String OUTCOME_NAVIGATION_SB = "oam.navigation.OUTCOME_NAVIGATION_SB";
     
     private static final Pattern AMP_PATTERN = Pattern.compile("&(amp;)?"); // "&" or "&amp;"
@@ -104,7 +97,7 @@ public class NavigationHandlerImpl
     private Map<String, _FlowNavigationStructure> _flowNavigationStructureMap = 
         new ConcurrentHashMap<String, _FlowNavigationStructure>();
     
-    private NavigationHandlerSupport navigationHandlerSupport;
+    private ViewIdSupport viewIdSupport;
 
     public NavigationHandlerImpl()
     {
@@ -317,14 +310,15 @@ public class NavigationHandlerImpl
                 {
                     try
                     {
-                        facesContext.getAttributes().put(SKIP_ITERATION_HINT, Boolean.TRUE);
+                        facesContext.getAttributes().put(VisitHintsHelper.SKIP_ITERATION_HINT, Boolean.TRUE);
 
-                        VisitContext visitContext = VisitContext.createVisitContext(facesContext, null, VISIT_HINTS);
+                        VisitContext visitContext = VisitContext.createVisitContext(facesContext,
+                                null, VisitHintsHelper.SKIP_ITERATION_VISIT_HINTS);
                         facesContext.getViewRoot().visitTree(visitContext, PreDisposeViewCallback.INSTANCE);
                     }
                     finally
                     {
-                        facesContext.getAttributes().remove(SKIP_ITERATION_HINT);
+                        facesContext.getAttributes().remove(VisitHintsHelper.SKIP_ITERATION_HINT);
                     }
                 }
                 
@@ -405,27 +399,28 @@ public class NavigationHandlerImpl
         }
     }
 
-    /**
-    * @return the navigationHandlerSupport
-    */
-    protected NavigationHandlerSupport getNavigationHandlerSupport()
+    protected ViewIdSupport getViewIdSupport()
     {
-        if (navigationHandlerSupport == null)
+        if (viewIdSupport == null)
         {
-            navigationHandlerSupport = new DefaultNavigationHandlerSupport();
+            viewIdSupport = ViewIdSupport.getInstance(FacesContext.getCurrentInstance());
         }
-        return navigationHandlerSupport;
+        return viewIdSupport;
     }
 
-    public void setNavigationHandlerSupport(NavigationHandlerSupport navigationHandlerSupport)
+    public void setViewIdSupport(ViewIdSupport viewIdSupport)
     {
-        this.navigationHandlerSupport = navigationHandlerSupport;
+        this.viewIdSupport = viewIdSupport;
     }
 
     private static class PreDisposeViewCallback implements VisitCallback
     {
         public static final PreDisposeViewCallback INSTANCE = new PreDisposeViewCallback();
         
+        private PreDisposeViewCallback()
+        {
+        }
+        
         @Override
         public VisitResult visit(VisitContext context, UIComponent target)
         {
@@ -439,6 +434,7 @@ public class NavigationHandlerImpl
     /**
      * Returns the navigation case that applies for the given action and outcome
      */
+    @Override
     public NavigationCase getNavigationCase(FacesContext facesContext, String fromAction, String outcome)
     {
         NavigationContext navigationContext = new NavigationContext();
@@ -1068,7 +1064,7 @@ public class NavigationHandlerImpl
                 // In this case, it should try to derive the viewId of the view that was
                 // not able to restore, to get the extension and apply it to
                 // the implicit navigation.
-                String tempViewId = getNavigationHandlerSupport().calculateViewId(facesContext);
+                String tempViewId = getViewIdSupport().calculateViewId(facesContext);
                 if (tempViewId != null)
                 {
                     index = tempViewId.lastIndexOf('.');
@@ -1158,8 +1154,7 @@ public class NavigationHandlerImpl
             if (queryString != null && LangUtils.isNotBlank(queryString))
             {
                 String[] splitQueryParams = AMP_PATTERN.split(queryString); // "&" or "&amp;"
-                params = new HashMap<String, List<String>>(splitQueryParams.length, 
-                        (splitQueryParams.length* 4 + 3) / 3);
+                params = new HashMap<>(splitQueryParams.length, (splitQueryParams.length* 4 + 3) / 3);
                 for (String queryParam : splitQueryParams)
                 {
                     String[] splitParam = StringUtils.splitShortString(queryParam, '=');
diff --git a/impl/src/main/java/org/apache/myfaces/application/ViewHandlerImpl.java b/impl/src/main/java/org/apache/myfaces/application/ViewHandlerImpl.java
index 22d17e9..1846cb6 100644
--- a/impl/src/main/java/org/apache/myfaces/application/ViewHandlerImpl.java
+++ b/impl/src/main/java/org/apache/myfaces/application/ViewHandlerImpl.java
@@ -64,7 +64,7 @@ public class ViewHandlerImpl extends ViewHandler
     private static final Logger log = Logger.getLogger(ViewHandlerImpl.class.getName());
     
     public static final String FORM_STATE_MARKER = "<!--@@JSF_FORM_STATE_MARKER@@-->";
-    private ViewHandlerSupport _viewHandlerSupport;
+    private ViewIdSupport _viewIdSupport;
     private ViewDeclarationLanguageFactory _vdlFactory;
     
     private Set<String> _protectedViewsSet;
@@ -96,20 +96,20 @@ public class ViewHandlerImpl extends ViewHandler
     }
 
     @Override
-    public String deriveViewId(FacesContext context, String input)
+    public String deriveViewId(FacesContext context, String rawViewId)
     {
-        if(input != null)
+        if(rawViewId != null)
         {
             try
             {
-                return getViewHandlerSupport(context).deriveViewId(context, input);
+                return getViewIdSupport(context).deriveViewId(context, rawViewId);
             }
             catch (InvalidViewIdException e)
             {
                 sendSourceNotFound(context, e.getMessage());
             }
         }
-        return input;   // If the argument input is null, return null.
+        return rawViewId;   // If the argument input is null, return null.
     }
     
     @Override
@@ -119,7 +119,7 @@ public class ViewHandlerImpl extends ViewHandler
         {
             try
             {
-                return getViewHandlerSupport(context).deriveLogicalViewId(context, rawViewId);
+                return getViewIdSupport(context).deriveLogicalViewId(context, rawViewId);
             }
             catch (InvalidViewIdException e)
             {
@@ -245,7 +245,7 @@ public class ViewHandlerImpl extends ViewHandler
     public UIViewRoot createView(FacesContext context, String viewId)
     {
         Assert.notNull(context, "facesContext");
-        String calculatedViewId = getViewHandlerSupport(context).deriveLogicalViewId(context, viewId);
+        String calculatedViewId = getViewIdSupport(context).deriveLogicalViewId(context, viewId);
        
         // we cannot use this.getVDL() directly (see getViewHandler())
         //return getViewHandler(context)
@@ -267,7 +267,7 @@ public class ViewHandlerImpl extends ViewHandler
     {
         Assert.notNull(context, "facesContext");
         Assert.notNull(viewId, "viewId");
-        return getViewHandlerSupport(context).calculateActionURL(context, viewId);
+        return getViewIdSupport(context).calculateActionURL(context, viewId);
     }
 
     @Override
@@ -318,7 +318,7 @@ public class ViewHandlerImpl extends ViewHandler
     {
         Assert.notNull(context, "context");
     
-        String calculatedViewId = getViewHandlerSupport(context).deriveLogicalViewId(context, viewId);
+        String calculatedViewId = getViewIdSupport(context).deriveLogicalViewId(context, viewId);
         
         // we cannot use this.getVDL() directly (see getViewHandler())
         //return getViewHandler(context)
@@ -448,7 +448,7 @@ public class ViewHandlerImpl extends ViewHandler
         }
         else
         {
-            String calculatedViewId = getViewHandlerSupport(context).deriveLogicalViewId(context, viewId);  
+            String calculatedViewId = getViewIdSupport(context).deriveLogicalViewId(context, viewId);  
             // we cannot use this.getVDL() directly (see getViewHandler())
             //ViewDeclarationLanguage vdl = getViewHandler(context).
             //        getViewDeclarationLanguage(context, calculatedViewId);
@@ -531,18 +531,18 @@ public class ViewHandlerImpl extends ViewHandler
         }
     }
     
-    public void setViewHandlerSupport(ViewHandlerSupport viewHandlerSupport)
+    public void setViewIdSupport(ViewIdSupport viewIdSupport)
     {
-        _viewHandlerSupport = viewHandlerSupport;
+        _viewIdSupport = viewIdSupport;
     }    
 
-    protected ViewHandlerSupport getViewHandlerSupport(FacesContext context)
+    protected ViewIdSupport getViewIdSupport(FacesContext context)
     {
-        if (_viewHandlerSupport == null)
+        if (_viewIdSupport == null)
         {
-            _viewHandlerSupport = new DefaultViewHandlerSupport(context);
+            _viewIdSupport = ViewIdSupport.getInstance(context);
         }
-        return _viewHandlerSupport;
+        return _viewIdSupport;
     }
 
     @Override
diff --git a/impl/src/main/java/org/apache/myfaces/application/ViewHandlerSupport.java b/impl/src/main/java/org/apache/myfaces/application/ViewHandlerSupport.java
deleted file mode 100644
index b3c0b09..0000000
--- a/impl/src/main/java/org/apache/myfaces/application/ViewHandlerSupport.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.application;
-
-import javax.faces.context.FacesContext;
-
-/**
- * TODO: RENAME - This class is now used by ViewDeclarationLanguageBase
- * 
- * A utility class to isolate a ViewHandler implementation from the underlying 
- * request/response framework.
- * <p>
- * For example, an implementation of this interface might support javax.servlet,
- * javax.portlet, or some other mechanism.
- */
-public interface ViewHandlerSupport
-{
-    String deriveLogicalViewId(FacesContext context, String viewId);
-    
-    String deriveViewId(FacesContext context, String viewId);
-
-    /**
-     * Return a string containing a webapp-relative URL that the user can invoke
-     * to render the specified view.
-     * <p>
-     * URLs and ViewIds are not quite the same; for example a url of "/foo.jsf"
-     * or "/faces/foo.jsp" may be needed to access the view "/foo.jsp". 
-     */
-    String calculateActionURL(FacesContext facesContext, String viewId); 
-}
diff --git a/impl/src/main/java/org/apache/myfaces/application/DefaultViewHandlerSupport.java b/impl/src/main/java/org/apache/myfaces/application/ViewIdSupport.java
similarity index 63%
rename from impl/src/main/java/org/apache/myfaces/application/DefaultViewHandlerSupport.java
rename to impl/src/main/java/org/apache/myfaces/application/ViewIdSupport.java
index 545fc0c..2a9d9b8 100644
--- a/impl/src/main/java/org/apache/myfaces/application/DefaultViewHandlerSupport.java
+++ b/impl/src/main/java/org/apache/myfaces/application/ViewIdSupport.java
@@ -20,174 +20,172 @@ package org.apache.myfaces.application;
 
 import java.net.MalformedURLException;
 import java.util.Map;
+import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import javax.faces.FacesException;
 
-import javax.faces.application.ViewHandler;
 import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
 import javax.faces.render.ResponseStateManager;
 import javax.faces.view.ViewDeclarationLanguage;
+import org.apache.myfaces.config.MyfacesConfig;
 
-import org.apache.myfaces.lifecycle.CheckedViewIdsCache;
+import org.apache.myfaces.util.ConcurrentLRUCache;
 import org.apache.myfaces.util.SharedStringBuilder;
 import org.apache.myfaces.util.ExternalContextUtils;
 import org.apache.myfaces.util.LangUtils;
-import org.apache.myfaces.util.StringUtils;
 import org.apache.myfaces.util.ViewProtectionUtils;
 
 /**
  * A ViewHandlerSupport implementation for use with standard Java Servlet engines,
  * ie an engine that supports javax.servlet, and uses a standard web.xml file.
  */
-public class DefaultViewHandlerSupport implements ViewHandlerSupport
+public class ViewIdSupport
 {
+    private static final String INSTANCE_KEY = ViewIdSupport.class.getName();
+    
+    private static final String JAVAX_SERVLET_INCLUDE_SERVLET_PATH = "javax.servlet.include.servlet_path";
+
+    private static final String JAVAX_SERVLET_INCLUDE_PATH_INFO = "javax.servlet.include.path_info";
+    
     /**
-     * Identifies the FacesServlet mapping in the current request map.
+     * Constant defined on javax.portlet.faces.Bridge class that helps to 
+     * define if the current request is a portlet request or not.
      */
-    private static final String CACHED_SERVLET_MAPPING =
-        DefaultViewHandlerSupport.class.getName() + ".CACHED_SERVLET_MAPPING";
-
-    private static final Logger log = Logger.getLogger(DefaultViewHandlerSupport.class.getName());
+    private static final String PORTLET_LIFECYCLE_PHASE = "javax.portlet.faces.phase";    
+    
+    private static final Logger log = Logger.getLogger(ViewIdSupport.class.getName());
     
     private static final String VIEW_HANDLER_SUPPORT_SB = "oam.viewhandler.SUPPORT_SB";
     
-    private final String[] _faceletsViewMappings;
-    private final String[] _contextSuffixes;
-    private final String _faceletsContextSufix;
-    private final boolean _initialized;
-    private CheckedViewIdsCache checkedViewIdsCache = null;
+    private MyfacesConfig config;
     
-    public DefaultViewHandlerSupport()
+    private volatile ConcurrentLRUCache<String, Boolean> viewIdExistsCache;
+    private volatile ConcurrentLRUCache<String, String> viewIdDeriveCache;
+    private volatile ConcurrentLRUCache<String, Boolean> viewIdProtectedCache;
+
+    public static ViewIdSupport getInstance(FacesContext facesContext)
     {
-        _faceletsViewMappings = null;
-        _contextSuffixes = null;
-        _faceletsContextSufix = null;
-        _initialized = false;
+        ViewIdSupport instance = (ViewIdSupport)
+                facesContext.getExternalContext().getApplicationMap().get(INSTANCE_KEY);
+        if (instance == null)
+        {
+            instance = new ViewIdSupport(facesContext);
+            facesContext.getExternalContext().getApplicationMap().put(INSTANCE_KEY, instance);
+        }
+
+        return instance;
     }
     
-    public DefaultViewHandlerSupport(FacesContext facesContext)
+    protected ViewIdSupport(FacesContext facesContext)
     {
-        _faceletsViewMappings = getFaceletsViewMappings(facesContext);
-        _contextSuffixes = getContextSuffix(facesContext);
-        _faceletsContextSufix = getFaceletsContextSuffix(facesContext);
-        _initialized = true;
-    }
+        config = MyfacesConfig.getCurrentInstance(facesContext);
 
-    @Override
-    public String deriveLogicalViewId(FacesContext context, String viewId)
-    {
-        //If no viewId found, don't try to derive it, just continue.
-        if (viewId == null)
+        int viewIdCacheSize = config.getViewIdCacheSize();
+        if (config.isViewIdExistsCacheEnabled())
         {
-            return null;
+            viewIdExistsCache = new ConcurrentLRUCache<>((viewIdCacheSize * 4 + 3) / 3, viewIdCacheSize);
         }
-
-        FacesServletMapping mapping = getFacesServletMapping(context);
-        if (mapping == null || mapping.isExtensionMapping())
+        if (config.isViewIdDeriveCacheEnabled())
         {
-            viewId = handleSuffixMapping(context, viewId);
+            viewIdDeriveCache = new ConcurrentLRUCache<>((viewIdCacheSize * 4 + 3) / 3, viewIdCacheSize);
         }
-        else if (mapping.isExactMapping())
+        if (config.isViewIdProtectedCacheEnabled())
         {
-            if (viewId.equals(mapping.getExact()))
-            {
-                viewId = handleSuffixMapping(context, viewId + ".jsf");
-            }
-        }
-        else if (mapping.isPrefixMapping())
-        {
-            viewId = handlePrefixMapping(viewId, mapping.getPrefix());
-            
-            // A viewId that is equals to the prefix mapping on servlet mode is
-            // considered invalid, because jsp vdl will use RequestDispatcher and cause
-            // a loop that ends in a exception. Note in portlet mode the view
-            // could be encoded as a query param, so the viewId could be valid.
-            if (viewId != null && viewId.equals(mapping.getPrefix()) &&
-                !ExternalContextUtils.isPortlet(context.getExternalContext()))
-            {
-                throw new InvalidViewIdException();
-            }
-
-            // In JSF 2.3 some changes were done in the VDL to avoid the jsp vdl
-            // RequestDispatcher redirection (only accept viewIds with jsp extension).
-            // If we have this case
-            if (viewId != null && viewId.equals(mapping.getPrefix()))
-            {
-                viewId = handleSuffixMapping(context, viewId+".jsf");
-            }
-        }
-        else if (mapping.getUrlPattern().startsWith(viewId))
-        {
-            throw new InvalidViewIdException(viewId);
+            viewIdProtectedCache = new ConcurrentLRUCache<>((viewIdCacheSize * 4 + 3) / 3, viewIdCacheSize);
         }
+    }
 
-        return viewId; // return null if no physical resource exists
+    public String deriveLogicalViewId(FacesContext context, String rawViewId)
+    {
+        return deriveViewId(context, rawViewId, false);
     }
     
-    @Override
     public String deriveViewId(FacesContext context, String viewId)
     {
+        return deriveViewId(context, viewId, true);
+    }
+    
+    protected String deriveViewId(FacesContext context, String rawViewId, boolean checkViewExists)
+    {
         //If no viewId found, don't try to derive it, just continue.
-        if (viewId == null)
+        if (rawViewId == null)
         {
             return null;
         }
-        FacesServletMapping mapping = getFacesServletMapping(context);
-        if (mapping == null || mapping.isExtensionMapping())
+
+        String viewId = null;
+        if (viewIdDeriveCache != null)
         {
-            viewId = handleSuffixMapping(context, viewId);
+            viewId = viewIdDeriveCache.get(rawViewId);
         }
-        else if (mapping.isExactMapping())
+
+        if (viewId == null)
         {
-            if (viewId.equals(mapping.getExact()))
+            FacesServletMapping mapping = FacesServletMappingUtils.getCurrentRequestFacesServletMapping(context);
+            if (mapping == null || mapping.isExtensionMapping())
             {
-                viewId = handleSuffixMapping(context, viewId + ".jsf");
+                viewId = handleSuffixMapping(context, rawViewId);
             }
-        }
-        else if (mapping.isPrefixMapping())
-        {
-            viewId = handlePrefixMapping(viewId, mapping.getPrefix());
-
-            if (viewId != null)
+            else if (mapping.isExactMapping())
             {
+                if (rawViewId.equals(mapping.getExact()))
+                {
+                    viewId = handleSuffixMapping(context, rawViewId + ".jsf");
+                }
+            }
+            else if (mapping.isPrefixMapping())
+            {
+                viewId = handlePrefixMapping(rawViewId, mapping.getPrefix());
+
                 // A viewId that is equals to the prefix mapping on servlet mode is
                 // considered invalid, because jsp vdl will use RequestDispatcher and cause
                 // a loop that ends in a exception. Note in portlet mode the view
                 // could be encoded as a query param, so the viewId could be valid.
-                //if (viewId.equals(mapping.getPrefix()) &&
-                //    !ExternalContextUtils.isPortlet(context.getExternalContext()))
-                //{
-                //    throw new InvalidViewIdException();
-                //}
-            
+                if (viewId != null
+                        && viewId.equals(mapping.getPrefix())
+                        && !ExternalContextUtils.isPortlet(context.getExternalContext()))
+                {
+                    throw new InvalidViewIdException();
+                }
+
                 // In JSF 2.3 some changes were done in the VDL to avoid the jsp vdl
                 // RequestDispatcher redirection (only accept viewIds with jsp extension).
                 // If we have this case
                 if (viewId != null && viewId.equals(mapping.getPrefix()))
                 {
-                    viewId = handleSuffixMapping(context, viewId+".jsf");
+                    viewId = handleSuffixMapping(context, viewId + ".jsf");
                 }
-
-                return (checkViewExists(context,viewId) ? viewId : null);
             }
-        }
-        else if (mapping.getUrlPattern().startsWith(viewId))
-        {
-            throw new InvalidViewIdException(viewId);
-        }
-        else
-        {
-            if(viewId != null)
+            else if (mapping.getUrlPattern().startsWith(rawViewId))
+            {
+                throw new InvalidViewIdException(rawViewId);
+            }
+            
+            if (viewId != null && viewIdDeriveCache != null)
             {
-                return (checkViewExists(context,viewId) ? viewId : null);
+                viewIdDeriveCache.put(rawViewId, viewId);
             }
         }
-
-        return viewId;    // return null if no physical resource exists
+        
+        if (viewId != null && checkViewExists)
+        {
+            return isViewExistent(context, viewId) ? viewId : null;
+        }
+        
+        return viewId; // return null if no physical resource exists
     }
-
-    @Override
+    
+    
+    
+    /**
+     * Return a string containing a webapp-relative URL that the user can invoke
+     * to render the specified view.
+     * <p>
+     * URLs and ViewIds are not quite the same; for example a url of "/foo.jsf"
+     * or "/faces/foo.jsp" may be needed to access the view "/foo.jsp". 
+     */
     public String calculateActionURL(FacesContext context, String viewId)
     {
         if (viewId == null || !viewId.startsWith("/"))
@@ -195,7 +193,7 @@ public class DefaultViewHandlerSupport implements ViewHandlerSupport
             throw new IllegalArgumentException("ViewId must start with a '/': " + viewId);
         }
 
-        FacesServletMapping mapping = getFacesServletMapping(context);
+        FacesServletMapping mapping = FacesServletMappingUtils.getCurrentRequestFacesServletMapping(context);
         ExternalContext externalContext = context.getExternalContext();
         String contextPath = externalContext.getRequestContextPath();
         StringBuilder builder = SharedStringBuilder.get(context, VIEW_HANDLER_SUPPORT_SB);
@@ -206,7 +204,6 @@ public class DefaultViewHandlerSupport implements ViewHandlerSupport
             builder.append(contextPath);
         }
         
-        
         // In JSF 2.3 we could have cases where the viewId can be bound to an url-pattern that is not
         // prefix or suffix, but exact mapping. In this part we need to take the viewId and check if
         // the viewId is bound or not with a mapping.
@@ -246,9 +243,8 @@ public class DefaultViewHandlerSupport implements ViewHandlerSupport
             else if (mapping.isExtensionMapping())
             {
                 //See JSF 2.0 section 7.5.2 
-                String[] contextSuffixes = _initialized ? _contextSuffixes : getContextSuffix(context); 
                 boolean founded = false;
-                for (String contextSuffix : contextSuffixes)
+                for (String contextSuffix : config.getViewSuffix())
                 {
                     if (viewId.endsWith(contextSuffix))
                     {
@@ -278,12 +274,12 @@ public class DefaultViewHandlerSupport implements ViewHandlerSupport
                     else if(viewId.lastIndexOf('.') != -1 )
                     {
                         builder.append(viewId.substring(0, viewId.lastIndexOf('.')));
-                        builder.append(contextSuffixes[0]);
+                        builder.append(config.getViewSuffix()[0]);
                     }
                     else
                     {
                         builder.append(viewId);
-                        builder.append(contextSuffixes[0]);
+                        builder.append(config.getViewSuffix()[0]);
                     }
                 }
             }
@@ -300,7 +296,7 @@ public class DefaultViewHandlerSupport implements ViewHandlerSupport
         
         
         //JSF 2.2 check view protection.
-        if (ViewProtectionUtils.isViewProtected(context, viewId))
+        if (isViewProtected(context, viewId))
         {
             int index = builder.indexOf("?");
             if (index >= 0)
@@ -327,9 +323,8 @@ public class DefaultViewHandlerSupport implements ViewHandlerSupport
     
     private String calculatePrefixedExactMapping(FacesContext context, String viewId)
     {
-        String[] contextSuffixes = _initialized ? _contextSuffixes : getContextSuffix(context); 
         String prefixedExactMapping = null;
-        for (String contextSuffix : contextSuffixes)
+        for (String contextSuffix : config.getViewSuffix())
         {
             if (viewId.endsWith(contextSuffix))
             {
@@ -339,65 +334,6 @@ public class DefaultViewHandlerSupport implements ViewHandlerSupport
         }
         return prefixedExactMapping == null ? viewId : prefixedExactMapping;
     }
-            
-
-    /**
-     * Read the web.xml file that is in the classpath and parse its internals to
-     * figure out how the FacesServlet is mapped for the current webapp.
-     */
-    protected FacesServletMapping getFacesServletMapping(FacesContext context)
-    {
-        Map<Object, Object> attributes = context.getAttributes();
-
-        // Has the mapping already been determined during this request?
-        FacesServletMapping mapping = (FacesServletMapping) attributes.get(CACHED_SERVLET_MAPPING);
-        if (mapping == null)
-        {
-            ExternalContext externalContext = context.getExternalContext();
-            mapping = FacesServletMappingUtils.calculateFacesServletMapping(
-                    context,
-                    externalContext.getRequestServletPath(),
-                    externalContext.getRequestPathInfo(),
-                    true);
-
-            attributes.put(CACHED_SERVLET_MAPPING, mapping);
-        }
-        return mapping;
-    }
-
-    protected String[] getContextSuffix(FacesContext context)
-    {
-        String defaultSuffix = context.getExternalContext().getInitParameter(ViewHandler.DEFAULT_SUFFIX_PARAM_NAME);
-        if (defaultSuffix == null)
-        {
-            defaultSuffix = ViewHandler.DEFAULT_SUFFIX;
-        }
-        return StringUtils.splitShortString(defaultSuffix, ' ');
-    }
-    
-    protected String getFaceletsContextSuffix(FacesContext context)
-    {
-        String defaultSuffix = context.getExternalContext().getInitParameter(ViewHandler.FACELETS_SUFFIX_PARAM_NAME);
-        if (defaultSuffix == null)
-        {
-            defaultSuffix = ViewHandler.DEFAULT_FACELETS_SUFFIX;
-        }
-        return defaultSuffix;
-    }
-    
-    
-    
-    protected String[] getFaceletsViewMappings(FacesContext context)
-    {
-        String faceletsViewMappings= context.getExternalContext().getInitParameter(
-                ViewHandler.FACELETS_VIEW_MAPPINGS_PARAM_NAME);
-        if(faceletsViewMappings == null)    //consider alias facelets.VIEW_MAPPINGS
-        {
-            faceletsViewMappings= context.getExternalContext().getInitParameter("facelets.VIEW_MAPPINGS");
-        }
-        
-        return faceletsViewMappings == null ? null : StringUtils.splitShortString(faceletsViewMappings, ';');
-    }
 
     /**
      * Return the normalized viewId according to the algorithm specified in 7.5.2 
@@ -456,17 +392,14 @@ public class DefaultViewHandlerSupport implements ViewHandlerSupport
      * </p>
      */
     protected String handleSuffixMapping(FacesContext context, String requestViewId)
-    {
-        String[] faceletsViewMappings = _initialized ? _faceletsViewMappings : getFaceletsViewMappings(context);
-        String[] jspDefaultSuffixes = _initialized ? _contextSuffixes : getContextSuffix(context);
-        
+    {        
         int slashPos = requestViewId.lastIndexOf('/');
         int extensionPos = requestViewId.lastIndexOf('.');
         
         StringBuilder builder = SharedStringBuilder.get(context, VIEW_HANDLER_SUPPORT_SB);
         
         //Try to locate any resource that match with the expected id
-        for (String defaultSuffix : jspDefaultSuffixes)
+        for (String defaultSuffix : config.getViewSuffix())
         {
             builder.setLength(0);
             builder.append(requestViewId);
@@ -482,9 +415,9 @@ public class DefaultViewHandlerSupport implements ViewHandlerSupport
 
             String candidateViewId = builder.toString();
             
-            if (faceletsViewMappings != null && faceletsViewMappings.length > 0 )
+            if (config.getFaceletsViewMappings() != null && config.getFaceletsViewMappings().length > 0 )
             {
-                for (String mapping : faceletsViewMappings)
+                for (String mapping : config.getFaceletsViewMappings())
                 {
                     if (mapping.startsWith("/"))
                     {
@@ -500,7 +433,7 @@ public class DefaultViewHandlerSupport implements ViewHandlerSupport
                         builder.append(candidateViewId); 
                         builder.replace(candidateViewId.lastIndexOf('.'), candidateViewId.length(), mapping);
                         String tempViewId = builder.toString();
-                        if (checkViewExists(context, tempViewId))
+                        if (isViewExistent(context, tempViewId))
                         {
                             return tempViewId;
                         }
@@ -509,18 +442,17 @@ public class DefaultViewHandlerSupport implements ViewHandlerSupport
             }
 
             // forced facelets mappings did not match or there were no entries in faceletsViewMappings array
-            if (checkViewExists(context,candidateViewId))
+            if (isViewExistent(context,candidateViewId))
             {
                 return candidateViewId;
             }
-        
         }
         
         //jsp suffixes didn't match, try facelets suffix
-        String faceletsDefaultSuffix = _initialized ? _faceletsContextSufix : this.getFaceletsContextSuffix(context);
+        String faceletsDefaultSuffix = config.getFaceletsViewSuffix();
         if (faceletsDefaultSuffix != null)
         {
-            for (String defaultSuffix : jspDefaultSuffixes)
+            for (String defaultSuffix : config.getViewSuffix())
             {
                 if (faceletsDefaultSuffix.equals(defaultSuffix))
                 {
@@ -544,14 +476,14 @@ public class DefaultViewHandlerSupport implements ViewHandlerSupport
             }
             
             String candidateViewId = builder.toString();
-            if (checkViewExists(context,candidateViewId))
+            if (isViewExistent(context,candidateViewId))
             {
                 return candidateViewId;
             }
         }
 
         // Otherwise, if a physical resource exists with the name requestViewId let that value be viewId.
-        if (checkViewExists(context,requestViewId))
+        if (isViewExistent(context,requestViewId))
         {
             return requestViewId;
         }
@@ -560,19 +492,21 @@ public class DefaultViewHandlerSupport implements ViewHandlerSupport
         return null;
     }
     
-    protected boolean checkViewExists(FacesContext facesContext, String viewId)
+    /**
+     * Check if a view exists
+     * 
+     * @param facesContext
+     * @param viewId
+     * @return 
+     */
+    public boolean isViewExistent(FacesContext facesContext, String viewId)
     {
-        if (checkedViewIdsCache == null)
-        {
-            checkedViewIdsCache = CheckedViewIdsCache.getInstance(facesContext);
-        }
-        
-        try
+       try
         {
             Boolean resourceExists = null;
-            if (checkedViewIdsCache.isEnabled())
+            if (viewIdExistsCache != null)
             {
-                resourceExists = checkedViewIdsCache.get(viewId);
+                resourceExists = viewIdExistsCache.get(viewId);
             }
 
             if (resourceExists == null)
@@ -589,9 +523,9 @@ public class DefaultViewHandlerSupport implements ViewHandlerSupport
                     resourceExists = facesContext.getExternalContext().getResource(viewId) != null;
                 }
 
-                if (checkedViewIdsCache.isEnabled())
+                if (viewIdExistsCache != null)
                 {
-                    checkedViewIdsCache.put(viewId, resourceExists);
+                    viewIdExistsCache.put(viewId, resourceExists);
                 }
             }
 
@@ -604,4 +538,111 @@ public class DefaultViewHandlerSupport implements ViewHandlerSupport
         return false;
     }
 
+    /**
+     * <p>
+     * Calculates the view id from the given faces context by the following algorithm
+     * </p>
+     * <ul>
+     * <li>lookup the viewid from the request attribute "javax.servlet.include.path_info"
+     * <li>if null lookup the value for viewid by {@link javax.faces.context.ExternalContext#getRequestPathInfo()}
+     * <li>if null lookup the value for viewid from the request attribute "javax.servlet.include.servlet_path"
+     * <li>if null lookup the value for viewid by {@link javax.faces.context.ExternalContext#getRequestServletPath()}
+     * <li>if null throw a {@link javax.faces.FacesException}
+     * </ul>
+     */
+    public String calculateViewId(FacesContext facesContext)
+    {
+        ExternalContext externalContext = facesContext.getExternalContext();
+        Map<String, Object> requestMap = externalContext.getRequestMap();
+
+        boolean traceEnabled = log.isLoggable(Level.FINEST);
+        
+        String viewId = null;
+        if (requestMap.containsKey(PORTLET_LIFECYCLE_PHASE))
+        {
+            viewId = (String) externalContext.getRequestPathInfo();
+        }
+        else
+        {
+            viewId = (String) requestMap.get(JAVAX_SERVLET_INCLUDE_PATH_INFO);
+            if (viewId != null)
+            {
+                if (traceEnabled)
+                {
+                    log.finest("Calculated viewId '" + viewId + "' from request param '"
+                            + JAVAX_SERVLET_INCLUDE_PATH_INFO + '\'');
+                }
+            }
+            else
+            {
+                viewId = externalContext.getRequestPathInfo();
+                if (viewId != null && traceEnabled)
+                {
+                    log.finest("Calculated viewId '" + viewId + "' from request path info");
+                }
+            }
+    
+            if (viewId == null)
+            {
+                viewId = (String) requestMap.get(JAVAX_SERVLET_INCLUDE_SERVLET_PATH);
+                if (viewId != null && traceEnabled)
+                {
+                    log.finest("Calculated viewId '" + viewId + "' from request param '"
+                            + JAVAX_SERVLET_INCLUDE_SERVLET_PATH + '\'');
+                }
+            }
+        }
+        
+        if (viewId == null)
+        {
+            viewId = externalContext.getRequestServletPath();
+            if (viewId != null && traceEnabled)
+            {
+                log.finest("Calculated viewId '" + viewId + "' from request servlet path");
+            }
+        }
+
+        if (viewId == null)
+        {
+            throw new FacesException("Could not determine view id.");
+        }
+
+        return viewId;
+    }
+    
+    
+    
+    public boolean isViewProtected(FacesContext context, String viewId)
+    {
+        Boolean protectedView = null;
+        if (viewIdProtectedCache != null)
+        {
+            protectedView = viewIdProtectedCache.get(viewId);
+        }
+        
+        if (protectedView == null)
+        {
+            protectedView = false;
+            
+            Set<String> protectedViews = context.getApplication().getViewHandler().getProtectedViewsUnmodifiable();
+            if (!protectedViews.isEmpty())
+            {
+                for (String urlPattern : protectedViews)
+                {
+                    if (ViewProtectionUtils.matchPattern(viewId, urlPattern))
+                    {
+                        protectedView = true;
+                        break;
+                    }
+                }
+            }
+            
+            if (viewIdProtectedCache != null)
+            {
+                viewIdProtectedCache.put(viewId, protectedView);
+            }
+        }
+         
+        return protectedView;
+    }
 }
diff --git a/impl/src/main/java/org/apache/myfaces/config/MyfacesConfig.java b/impl/src/main/java/org/apache/myfaces/config/MyfacesConfig.java
index dfa9ba3..bf2e0ac 100755
--- a/impl/src/main/java/org/apache/myfaces/config/MyfacesConfig.java
+++ b/impl/src/main/java/org/apache/myfaces/config/MyfacesConfig.java
@@ -629,26 +629,33 @@ public class MyfacesConfig
              + "ELResolvers chain. Use with caution - can break functionality defined in JSF specification "
              + "'ELResolver Instances Provided by Faces'")
     public static final String EL_RESOLVER_PREDICATE = "org.apache.myfaces.EL_RESOLVER_PREDICATE";
-    
-    /**
-     * Controls the size of the cache used to "remember" if a view exists or not.
-     */
+
     @JSFWebConfigParam(defaultValue = "500", since = "2.0.2", group="viewhandler", tags="performance", 
             classType="java.lang.Integer",
-            desc="Controls the size of the cache used to 'remember' if a view exists or not.")
-    private static final String CHECKED_VIEWID_CACHE_SIZE = "org.apache.myfaces.CHECKED_VIEWID_CACHE_SIZE";
-    private static final int CHECKED_VIEWID_CACHE_SIZE_DEFAULT = 500;
+            desc="Controls the size of the viewId related caches: " + 
+                    "VIEWID_EXISTS_CACHE_ENABLED, VIEWID_PROTECTED_CACHE_ENABLED, VIEWID_DERIVE_CACHE_ENABLED")
+    private static final String VIEWID_CACHE_SIZE = "org.apache.myfaces.VIEWID_CACHE_SIZE";
+    private static final int VIEWID_CACHE_SIZE_DEFAULT = 500;
 
-    /**
-     * Enable or disable a cache used to "remember" if a view exists or not and reduce the impact of
-     * sucesive calls to ExternalContext.getResource().
-     */
     @JSFWebConfigParam(defaultValue = "true", since = "2.0.2", expectedValues="true, false", group="viewhandler", 
             tags="performance",
-            desc="Enable or disable a cache used to 'remember' if a view exists or not and reduce the impact " +
+            desc="Enable or disable the cache used to 'remember' if a view exists or not and reduce the impact " +
                  "of sucesive calls to ExternalContext.getResource().")
-    private static final String CHECKED_VIEWID_CACHE_ENABLED = "org.apache.myfaces.CHECKED_VIEWID_CACHE_ENABLED";
-    private static final boolean CHECKED_VIEWID_CACHE_ENABLED_DEFAULT = true;
+    private static final String VIEWID_EXISTS_CACHE_ENABLED = "org.apache.myfaces.VIEWID_EXISTS_CACHE_ENABLED";
+    private static final boolean VIEWID_EXISTS_CACHE_ENABLED_DEFAULT = true;
+    
+
+    @JSFWebConfigParam(defaultValue = "true", since = "3.0.0", expectedValues="true, false", group="viewhandler", 
+            tags="performance",
+            desc="Enable or disable the cache used to 'remember' if a view is protected or not.")
+    private static final String VIEWID_PROTECTED_CACHE_ENABLED = "org.apache.myfaces.VIEWID_PROTECTED_CACHE_ENABLED";
+    private static final boolean VIEWID_PROTECTED_CACHE_ENABLED_DEFAULT = true;
+    
+    @JSFWebConfigParam(defaultValue = "true", since = "3.0.0", expectedValues="true, false", group="viewhandler", 
+            tags="performance",
+            desc="Enable or disable the cache used to 'remember' the derived viewId from the rawViewId.")
+    private static final String VIEWID_DERIVE_CACHE_ENABLED = "org.apache.myfaces.VIEWID_DERIVE_CACHE_ENABLED";
+    private static final boolean VIEWID_DERIVE_CACHE_ENABLED_DEFAULT = true;
     
     @JSFWebConfigParam(defaultValue=".jsp", since="2.3", group="viewhandler")
     public static final String JSP_SUFFIX = "org.apache.myfaces.JSP_SUFFIX";
@@ -782,8 +789,10 @@ public class MyfacesConfig
     private boolean lazyLoadConfigObjects = LAZY_LOAD_CONFIG_OBJECTS_DEFAULT;
     private String elResolverComparator;
     private String elResolverPredicate;
-    private boolean checkedViewIdCacheEnabled = CHECKED_VIEWID_CACHE_ENABLED_DEFAULT;
-    private int checkedViewIdCacheSize = CHECKED_VIEWID_CACHE_SIZE_DEFAULT;
+    private boolean viewIdExistsCacheEnabled = VIEWID_EXISTS_CACHE_ENABLED_DEFAULT;
+    private boolean viewIdProtectedCacheEnabled = VIEWID_PROTECTED_CACHE_ENABLED_DEFAULT;
+    private boolean viewIdDeriveCacheEnabled = VIEWID_DERIVE_CACHE_ENABLED_DEFAULT;
+    private int viewIdCacheSize = VIEWID_CACHE_SIZE_DEFAULT;
     private String jspSuffix = JSP_SUFFIX_DEFAULT;
     private boolean beanBeforeJsfValidation = BEAN_BEFORE_JSF_VALIDATION_DEFAULT;
     private String facesInitPlugins;
@@ -1114,15 +1123,29 @@ public class MyfacesConfig
         cfg.elResolverPredicate = getString(extCtx, EL_RESOLVER_PREDICATE,
                 null);
         
-        cfg.checkedViewIdCacheEnabled = getBoolean(extCtx, CHECKED_VIEWID_CACHE_ENABLED,
-                CHECKED_VIEWID_CACHE_ENABLED_DEFAULT);
+        cfg.viewIdExistsCacheEnabled = getBoolean(extCtx, VIEWID_EXISTS_CACHE_ENABLED,
+                VIEWID_EXISTS_CACHE_ENABLED_DEFAULT);
+        if (cfg.projectStage == ProjectStage.Development)
+        {
+            cfg.viewIdExistsCacheEnabled = false;
+        }
+        
+        cfg.viewIdProtectedCacheEnabled = getBoolean(extCtx, VIEWID_PROTECTED_CACHE_ENABLED,
+                VIEWID_PROTECTED_CACHE_ENABLED_DEFAULT);
         if (cfg.projectStage == ProjectStage.Development)
         {
-            cfg.checkedViewIdCacheEnabled = false;
+            cfg.viewIdProtectedCacheEnabled = false;
         }
 
-        cfg.checkedViewIdCacheSize = getInt(extCtx, CHECKED_VIEWID_CACHE_SIZE,
-                CHECKED_VIEWID_CACHE_SIZE_DEFAULT);
+        cfg.viewIdDeriveCacheEnabled = getBoolean(extCtx, VIEWID_DERIVE_CACHE_ENABLED,
+                VIEWID_DERIVE_CACHE_ENABLED_DEFAULT);
+        if (cfg.projectStage == ProjectStage.Development)
+        {
+            cfg.viewIdDeriveCacheEnabled = false;
+        }
+        
+        cfg.viewIdCacheSize = getInt(extCtx, VIEWID_CACHE_SIZE,
+                VIEWID_CACHE_SIZE_DEFAULT);
         
         cfg.jspSuffix = getString(extCtx, JSP_SUFFIX,
                 JSP_SUFFIX_DEFAULT);
@@ -1517,14 +1540,9 @@ public class MyfacesConfig
         return elResolverPredicate;
     }
 
-    public boolean isCheckedViewIdCacheEnabled()
+    public int getViewIdCacheSize()
     {
-        return checkedViewIdCacheEnabled;
-    }
-
-    public int getCheckedViewIdCacheSize()
-    {
-        return checkedViewIdCacheSize;
+        return viewIdCacheSize;
     }
 
     public String getJspSuffix()
@@ -1602,8 +1620,20 @@ public class MyfacesConfig
         return faceletsViewSuffix;
     }
 
+    public boolean isViewIdExistsCacheEnabled()
+    {
+        return viewIdExistsCacheEnabled;
+    }
 
- 
+    public boolean isViewIdProtectedCacheEnabled()
+    {
+        return viewIdProtectedCacheEnabled;
+    }
+
+    public boolean isViewIdDeriveCacheEnabled()
+    {
+        return viewIdDeriveCacheEnabled;
+    }
 
     
 }
diff --git a/impl/src/main/java/org/apache/myfaces/context/RequestViewContext.java b/impl/src/main/java/org/apache/myfaces/context/RequestViewContext.java
index 2db3b70..31c7794 100644
--- a/impl/src/main/java/org/apache/myfaces/context/RequestViewContext.java
+++ b/impl/src/main/java/org/apache/myfaces/context/RequestViewContext.java
@@ -20,20 +20,18 @@ package org.apache.myfaces.context;
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import javax.faces.application.ResourceDependency;
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIViewRoot;
 import javax.faces.component.visit.VisitCallback;
 import javax.faces.component.visit.VisitContext;
-import javax.faces.component.visit.VisitHint;
 import javax.faces.component.visit.VisitResult;
 import javax.faces.context.FacesContext;
+import org.apache.myfaces.util.VisitHintsHelper;
 
 /**
  *
@@ -43,15 +41,9 @@ import javax.faces.context.FacesContext;
  */
 public class RequestViewContext
 {
-
     public static final String VIEW_CONTEXT_KEY = "oam.VIEW_CONTEXT";
     
     public static final String RESOURCE_DEPENDENCY_INSPECTED_CLASS = "oam.RDClass";
-    
-    private static final String SKIP_ITERATION_HINT = "javax.faces.visit.SKIP_ITERATION";
-    
-    private static final Set<VisitHint> VISIT_HINTS = Collections.unmodifiableSet( 
-            EnumSet.of(VisitHint.SKIP_ITERATION));
 
     private RequestViewMetadata requestViewMetadata;
     
@@ -222,16 +214,17 @@ public class RequestViewContext
             {
                 try
                 {
-                    facesContext.getAttributes().put(SKIP_ITERATION_HINT, Boolean.TRUE);
+                    facesContext.getAttributes().put(VisitHintsHelper.SKIP_ITERATION_HINT, Boolean.TRUE);
 
-                    VisitContext visitContext = VisitContext.createVisitContext(facesContext, null, VISIT_HINTS);
+                    VisitContext visitContext = VisitContext.createVisitContext(facesContext,
+                            null, VisitHintsHelper.SKIP_ITERATION_VISIT_HINTS);
                     facet.visitTree(visitContext, new RefreshViewContext());
                 }
                 finally
                 {
                     // We must remove hint in finally, because an exception can break this phase,
                     // but lifecycle can continue, if custom exception handler swallows the exception
-                    facesContext.getAttributes().remove(SKIP_ITERATION_HINT);
+                    facesContext.getAttributes().remove(VisitHintsHelper.SKIP_ITERATION_HINT);
                 }
             }
         }
diff --git a/impl/src/main/java/org/apache/myfaces/lifecycle/CheckedViewIdsCache.java b/impl/src/main/java/org/apache/myfaces/lifecycle/CheckedViewIdsCache.java
deleted file mode 100644
index ce4ef2c..0000000
--- a/impl/src/main/java/org/apache/myfaces/lifecycle/CheckedViewIdsCache.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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.lifecycle;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.faces.application.ProjectStage;
-import javax.faces.context.FacesContext;
-import org.apache.myfaces.config.MyfacesConfig;
-import org.apache.myfaces.util.ConcurrentLRUCache;
-
-public class CheckedViewIdsCache
-{
-    private static final Logger LOG = Logger.getLogger(CheckedViewIdsCache.class.getName());
-    private static final String INSTANCE_KEY = CheckedViewIdsCache.class.getName();
-
-    private volatile ConcurrentLRUCache<String, Boolean> cache = null;
-    private boolean enabled;
-    private int size;
-    
-    private CheckedViewIdsCache()
-    {
-    }
-    
-    public void init(FacesContext facesContext)
-    {
-        // first, check if the ProjectStage is development and skip caching in this case
-        if (facesContext.isProjectStage(ProjectStage.Development))
-        {
-            enabled = false;
-        }
-        else
-        {
-            // in all ohter cases, make sure that the cache is not explicitly disabled via context param
-            enabled = MyfacesConfig.getCurrentInstance(facesContext).isCheckedViewIdCacheEnabled();
-        }
-        
-        size = MyfacesConfig.getCurrentInstance(facesContext).getCheckedViewIdCacheSize();
-
-        cache = new ConcurrentLRUCache<>((size * 4 + 3) / 3, size);
-        
-        if (LOG.isLoggable(Level.FINE))
-        {
-            LOG.log(Level.FINE, "MyFaces CheckedViewIdsCache enabled=" + enabled + ", size=" + size);
-        }
-    }
-    
-    public boolean isEnabled()
-    {
-        return enabled;
-    }
-    
-    public Boolean get(String viewId)
-    {
-        return cache.get(viewId);
-    }
-    
-    public Boolean put(String viewId, Boolean exists)
-    {
-        return cache.put(viewId, exists);
-    }
-    
-    public static CheckedViewIdsCache getInstance(FacesContext facesContext)
-    {
-        CheckedViewIdsCache instance = (CheckedViewIdsCache)
-                facesContext.getExternalContext().getApplicationMap().get(INSTANCE_KEY);
-        if (instance == null)
-        {
-            instance = new CheckedViewIdsCache();
-            instance.init(facesContext);
-            facesContext.getExternalContext().getApplicationMap().put(INSTANCE_KEY, instance);
-        }
-        
-        return instance;
-    }
-}
diff --git a/impl/src/main/java/org/apache/myfaces/lifecycle/DefaultRestoreViewSupport.java b/impl/src/main/java/org/apache/myfaces/lifecycle/DefaultRestoreViewSupport.java
deleted file mode 100644
index 10cc20c..0000000
--- a/impl/src/main/java/org/apache/myfaces/lifecycle/DefaultRestoreViewSupport.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- * 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.lifecycle;
-
-import java.net.MalformedURLException;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.faces.FacesException;
-import javax.faces.FactoryFinder;
-import javax.faces.application.ViewHandler;
-import javax.faces.component.UIComponent;
-import javax.faces.component.visit.VisitCallback;
-import javax.faces.component.visit.VisitContext;
-import javax.faces.component.visit.VisitContextFactory;
-import javax.faces.component.visit.VisitHint;
-import javax.faces.component.visit.VisitResult;
-import javax.faces.context.ExternalContext;
-import javax.faces.context.FacesContext;
-import javax.faces.event.PostRestoreStateEvent;
-import javax.faces.render.RenderKitFactory;
-import javax.faces.render.ResponseStateManager;
-import javax.faces.view.ViewDeclarationLanguage;
-
-import org.apache.myfaces.util.Assert;
-
-/**
- * @author Mathias Broekelmann (latest modification by $Author$)
- * @version $Revision$ $Date$
- */
-public class DefaultRestoreViewSupport implements RestoreViewSupport
-{
-    private static final String JAVAX_SERVLET_INCLUDE_SERVLET_PATH = "javax.servlet.include.servlet_path";
-
-    private static final String JAVAX_SERVLET_INCLUDE_PATH_INFO = "javax.servlet.include.path_info";
-    
-    /**
-     * Constant defined on javax.portlet.faces.Bridge class that helps to 
-     * define if the current request is a portlet request or not.
-     */
-    private static final String PORTLET_LIFECYCLE_PHASE = "javax.portlet.faces.phase";
-
-    private final Logger log = Logger.getLogger(DefaultRestoreViewSupport.class.getName());
-
-    private static final String SKIP_ITERATION_HINT = "javax.faces.visit.SKIP_ITERATION";
-    
-    private static final Set<VisitHint> VISIT_HINTS = Collections.unmodifiableSet( 
-            EnumSet.of(VisitHint.SKIP_ITERATION));
-
-    private RenderKitFactory _renderKitFactory = null;
-    private VisitContextFactory _visitContextFactory = null;
-    private CheckedViewIdsCache checkedViewIdsCache = null;
-    
-    public DefaultRestoreViewSupport()
-    {
-    }
-    
-    public DefaultRestoreViewSupport(FacesContext facesContext)
-    {
-    }
-
-    @Override
-    public void processComponentBinding(FacesContext facesContext, UIComponent component)
-    {
-        // JSF 2.0: Old hack related to t:aliasBean was fixed defining a event that traverse
-        // whole tree and let components to override UIComponent.processEvent() method to include it.
-        
-        // Remove this hack SKIP_ITERATION_HINT and use VisitHints.SKIP_ITERATION in JSF 2.1 only
-        // is not possible, because jsf 2.0 API-based libraries can use the String
-        // hint, JSF21-based libraries can use both.
-        try
-        {
-            facesContext.getAttributes().put(SKIP_ITERATION_HINT, Boolean.TRUE);
-
-            VisitContext visitContext = (VisitContext) getVisitContextFactory().
-                    getVisitContext(facesContext, null, VISIT_HINTS);
-            component.visitTree(visitContext, new RestoreStateCallback());
-        }
-        finally
-        {
-            // We must remove hint in finally, because an exception can break this phase,
-            // but lifecycle can continue, if custom exception handler swallows the exception
-            facesContext.getAttributes().remove(SKIP_ITERATION_HINT);
-        }
-    }
-
-    @Override
-    public String calculateViewId(FacesContext facesContext)
-    {
-        Assert.notNull(facesContext);
-        ExternalContext externalContext = facesContext.getExternalContext();
-        Map<String, Object> requestMap = externalContext.getRequestMap();
-
-        String viewId = null;
-        boolean traceEnabled = log.isLoggable(Level.FINEST);
-        
-        if (requestMap.containsKey(PORTLET_LIFECYCLE_PHASE))
-        {
-            viewId = (String) externalContext.getRequestPathInfo();
-        }
-        else
-        {
-            viewId = (String) requestMap.get(JAVAX_SERVLET_INCLUDE_PATH_INFO);
-            if (viewId != null)
-            {
-                if (traceEnabled)
-                {
-                    log.finest("Calculated viewId '" + viewId + "' from request param '"
-                               + JAVAX_SERVLET_INCLUDE_PATH_INFO + '\'');
-                }
-            }
-            else
-            {
-                viewId = externalContext.getRequestPathInfo();
-                if (viewId != null && traceEnabled)
-                {
-                    log.finest("Calculated viewId '" + viewId + "' from request path info");
-                }
-            }
-    
-            if (viewId == null)
-            {
-                viewId = (String) requestMap.get(JAVAX_SERVLET_INCLUDE_SERVLET_PATH);
-                if (viewId != null && traceEnabled)
-                {
-                    log.finest("Calculated viewId '" + viewId + "' from request param '"
-                            + JAVAX_SERVLET_INCLUDE_SERVLET_PATH + '\'');
-                }
-            }
-        }
-        
-        if (viewId == null)
-        {
-            viewId = externalContext.getRequestServletPath();
-            if (viewId != null && traceEnabled)
-            {
-                log.finest("Calculated viewId '" + viewId + "' from request servlet path");
-            }
-        }
-
-        if (viewId == null)
-        {
-            throw new FacesException("Could not determine view id.");
-        }
-
-        return viewId;
-    }
-
-    @Override
-    public boolean isPostback(FacesContext facesContext)
-    {
-        ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
-        String renderkitId = viewHandler.calculateRenderKitId(facesContext);
-        ResponseStateManager rsm
-                = getRenderKitFactory().getRenderKit(facesContext, renderkitId).getResponseStateManager();
-        return rsm.isPostback(facesContext);
-    }
-    
-    protected RenderKitFactory getRenderKitFactory()
-    {
-        if (_renderKitFactory == null)
-        {
-            _renderKitFactory = (RenderKitFactory)FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
-        }
-        return _renderKitFactory;
-    }
-    
-    protected VisitContextFactory getVisitContextFactory()
-    {
-        if (_visitContextFactory == null)
-        {
-            _visitContextFactory = (VisitContextFactory)FactoryFinder.getFactory(FactoryFinder.VISIT_CONTEXT_FACTORY);
-        }
-        return _visitContextFactory;
-    }
-
-    private static class RestoreStateCallback implements VisitCallback
-    {
-        private PostRestoreStateEvent event;
-
-        @Override
-        public VisitResult visit(VisitContext context, UIComponent target)
-        {
-            if (event == null)
-            {
-                event = new PostRestoreStateEvent(target);
-            }
-            else
-            {
-                event.setComponent(target);
-            }
-
-            // call the processEvent method of the current component.
-            // The argument event must be an instance of AfterRestoreStateEvent whose component
-            // property is the current component in the traversal.
-            target.processEvent(event);
-            
-            return VisitResult.ACCEPT;
-        }
-    }
-
-    @Override
-    public boolean checkViewExists(FacesContext facesContext, String viewId)
-    {
-        if (checkedViewIdsCache == null)
-        {
-            checkedViewIdsCache = CheckedViewIdsCache.getInstance(facesContext);
-        }
-        
-        try
-        {
-            Boolean resourceExists = null;
-            if (checkedViewIdsCache.isEnabled())
-            {
-                resourceExists = checkedViewIdsCache.get(viewId);
-            }
-
-            if (resourceExists == null)
-            {
-                ViewDeclarationLanguage vdl = facesContext.getApplication().getViewHandler()
-                        .getViewDeclarationLanguage(facesContext, viewId);
-                if (vdl != null)
-                {
-                    resourceExists = vdl.viewExists(facesContext, viewId);
-                }
-                else
-                {
-                    // Fallback to default strategy
-                    resourceExists = facesContext.getExternalContext().getResource(viewId) != null;
-                }
-
-                if (checkedViewIdsCache.isEnabled())
-                {
-                    checkedViewIdsCache.put(viewId, resourceExists);
-                }
-            }
-
-            return resourceExists;
-        }
-        catch (MalformedURLException e)
-        {
-            //ignore and move on
-        }     
-        return false;
-    }
-}
diff --git a/impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewExecutor.java b/impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewExecutor.java
index 750c48f..de3b6a4 100644
--- a/impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewExecutor.java
+++ b/impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewExecutor.java
@@ -49,12 +49,12 @@ import javax.faces.view.ViewDeclarationLanguage;
 import javax.faces.view.ViewMetadata;
 import javax.faces.webapp.FacesServlet;
 import javax.servlet.http.HttpServletResponse;
+import org.apache.myfaces.application.ViewIdSupport;
 import org.apache.myfaces.event.PostClientWindowAndViewInitializedEvent;
 
 import org.apache.myfaces.renderkit.ErrorPageWriter;
 import org.apache.myfaces.config.MyfacesConfig;
 import org.apache.myfaces.util.ExternalContextUtils;
-import org.apache.myfaces.util.ViewProtectionUtils;
 
 /**
  * Implements the Restore View Phase (JSF Spec 2.2.1)
@@ -68,6 +68,7 @@ class RestoreViewExecutor extends PhaseExecutor
     private static final Logger log = Logger.getLogger(RestoreViewExecutor.class.getName());
     
     private RestoreViewSupport _restoreViewSupport;
+    private ViewIdSupport _viewIdSupport;
     
     private Boolean _viewNotFoundCheck;
     
@@ -94,10 +95,11 @@ class RestoreViewExecutor extends PhaseExecutor
         // get some required Objects
         Application application = facesContext.getApplication();
         ViewHandler viewHandler = application.getViewHandler();
-        UIViewRoot viewRoot = facesContext.getViewRoot();
         RestoreViewSupport restoreViewSupport = getRestoreViewSupport(facesContext);
+        ViewIdSupport viewHandlerSupport = getViewIdSupport(facesContext);
 
         // Examine the FacesContext instance for the current request. If it already contains a UIViewRoot
+        UIViewRoot viewRoot = facesContext.getViewRoot();
         if (viewRoot != null)
         {
             if (log.isLoggable(Level.FINEST))
@@ -117,7 +119,7 @@ class RestoreViewExecutor extends PhaseExecutor
             return false;
         }
         
-        String viewId = restoreViewSupport.calculateViewId(facesContext);
+        String viewId = viewHandlerSupport.calculateViewId(facesContext);
 
         // Determine if the current request is an attempt by the 
         // servlet container to display an error page.
@@ -153,7 +155,7 @@ class RestoreViewExecutor extends PhaseExecutor
                     sendSourceNotFound(facesContext, viewId);
                     return true;
                 }
-                else if (!restoreViewSupport.checkViewExists(facesContext, derivedViewId))
+                else if (!viewHandlerSupport.isViewExistent(facesContext, derivedViewId))
                 {
                     sendSourceNotFound(facesContext, viewId);
                     return true;
@@ -236,7 +238,7 @@ class RestoreViewExecutor extends PhaseExecutor
                     sendSourceNotFound(facesContext, viewId);
                     return true;
                 }
-                else if (!restoreViewSupport.checkViewExists(facesContext, logicalViewId))
+                else if (!viewHandlerSupport.isViewExistent(facesContext, logicalViewId))
                 {
                     sendSourceNotFound(facesContext, viewId);
                     return true;
@@ -338,7 +340,7 @@ class RestoreViewExecutor extends PhaseExecutor
         String viewId, UIViewRoot root) throws ProtectedViewException
     {
         boolean valid = true;
-        if (ViewProtectionUtils.isViewProtected(facesContext, viewId))
+        if (getViewIdSupport(facesContext).isViewProtected(facesContext, viewId))
         {
             // "... Obtain the value of the value of the request parameter whose 
             // name is given by the value of ResponseStateManager.NON_POSTBACK_VIEW_TOKEN_PARAM. 
@@ -555,20 +557,24 @@ class RestoreViewExecutor extends PhaseExecutor
         }
         return factory.getLifecycle(id);  
     }
-    
-    protected RestoreViewSupport getRestoreViewSupport()
-    {
-        return getRestoreViewSupport(FacesContext.getCurrentInstance());
-    }
-    
+
     protected RestoreViewSupport getRestoreViewSupport(FacesContext context)
     {
         if (_restoreViewSupport == null)
         {
-            _restoreViewSupport = new DefaultRestoreViewSupport(context);
+            _restoreViewSupport = new RestoreViewSupport(context);
         }
         return _restoreViewSupport;
     }
+    
+    protected ViewIdSupport getViewIdSupport(FacesContext context)
+    {
+        if (_viewIdSupport == null)
+        {
+            _viewIdSupport = ViewIdSupport.getInstance(context);
+        }
+        return _viewIdSupport;
+    }
 
     protected RenderKitFactory getRenderKitFactory()
     {
@@ -579,14 +585,16 @@ class RestoreViewExecutor extends PhaseExecutor
         return _renderKitFactory;
     }
     
-    /**
-     * @param restoreViewSupport
-     *            the restoreViewSupport to set
-     */
+
     public void setRestoreViewSupport(RestoreViewSupport restoreViewSupport)
     {
         _restoreViewSupport = restoreViewSupport;
     }
+    
+    public void setViewHandlerSupport(ViewIdSupport viewHandlerSupport)
+    {
+        _viewIdSupport = viewHandlerSupport;
+    }
 
     @Override
     public PhaseId getPhase()
diff --git a/impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewSupport.java b/impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewSupport.java
index 4453f1e..1d0d670 100644
--- a/impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewSupport.java
+++ b/impl/src/main/java/org/apache/myfaces/lifecycle/RestoreViewSupport.java
@@ -1,80 +1,109 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.myfaces.lifecycle;
-
-import javax.faces.component.UIComponent;
-import javax.faces.context.FacesContext;
-
-/**
- * Support class for restore view phase
- * 
- * @author Mathias Broekelmann (latest modification by $Author$)
- * @version $Revision$ $Date$
- */
-public interface RestoreViewSupport
-{
-    /**
-     * <p>
-     * Calculates the view id from the given faces context by the following algorithm
-     * </p>
-     * <ul>
-     * <li>lookup the viewid from the request attribute "javax.servlet.include.path_info"
-     * <li>if null lookup the value for viewid by {@link javax.faces.context.ExternalContext#getRequestPathInfo()}
-     * <li>if null lookup the value for viewid from the request attribute "javax.servlet.include.servlet_path"
-     * <li>if null lookup the value for viewid by {@link javax.faces.context.ExternalContext#getRequestServletPath()}
-     * <li>if null throw a {@link javax.faces.FacesException}
-     * </ul>
-     */
-    String calculateViewId(FacesContext facesContext);
-
-    /**
-     * Processes the component tree. For each component (including the given one) in the tree determine if a value
-     * expression for the attribute "binding" is defined. If the expression is not null set the component instance to
-     * the value of this expression
-     * 
-     * @param facesContext
-     * @param component
-     *            the root component
-     */
-    void processComponentBinding(FacesContext facesContext, UIComponent component);
-
-    /**
-     * <p>
-     * Determine if the current request is a post back by the following algorithm.
-     * </p>
-     * <p>
-     * Find the render-kit-id for the current request by calling calculateRenderKitId() on the Application’s
-     * ViewHandler. Get that RenderKit’s ResponseStateManager and call its isPostback() method, passing the given
-     * FacesContext.
-     * </p>
-     * 
-     * @param facesContext
-     * @return
-     */
-    boolean isPostback(FacesContext facesContext);
-    
-    /**
-     * Check if a view exists
-     * 
-     * @param facesContext
-     * @param viewId
-     * @return 
-     */
-    boolean checkViewExists(FacesContext facesContext, String viewId);
-}
+/*
+ * 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.lifecycle;
+
+import java.util.logging.Logger;
+
+import javax.faces.FactoryFinder;
+import javax.faces.application.ViewHandler;
+import javax.faces.component.UIComponent;
+import javax.faces.component.visit.VisitCallback;
+import javax.faces.component.visit.VisitContext;
+import javax.faces.component.visit.VisitContextFactory;
+import javax.faces.component.visit.VisitResult;
+import javax.faces.context.FacesContext;
+import javax.faces.event.PostRestoreStateEvent;
+import javax.faces.render.RenderKitFactory;
+import javax.faces.render.ResponseStateManager;
+import org.apache.myfaces.util.VisitHintsHelper;
+
+/**
+ * @author Mathias Broekelmann (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+public class RestoreViewSupport
+{
+    private final Logger log = Logger.getLogger(RestoreViewSupport.class.getName());
+
+    private RenderKitFactory renderKitFactory = null;
+    private VisitContextFactory visitContextFactory = null;
+
+    public RestoreViewSupport(FacesContext facesContext)
+    {
+        visitContextFactory = (VisitContextFactory) FactoryFinder.getFactory(FactoryFinder.VISIT_CONTEXT_FACTORY);
+        renderKitFactory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
+    }
+
+    public void processComponentBinding(FacesContext facesContext, UIComponent component)
+    {
+        // JSF 2.0: Old hack related to t:aliasBean was fixed defining a event that traverse
+        // whole tree and let components to override UIComponent.processEvent() method to include it.
+        
+        // Remove this hack SKIP_ITERATION_HINT and use VisitHints.SKIP_ITERATION in JSF 2.1 only
+        // is not possible, because jsf 2.0 API-based libraries can use the String
+        // hint, JSF21-based libraries can use both.
+        try
+        {
+            facesContext.getAttributes().put(VisitHintsHelper.SKIP_ITERATION_HINT, Boolean.TRUE);
+
+            VisitContext visitContext = (VisitContext) visitContextFactory.getVisitContext(facesContext,
+                    null, VisitHintsHelper.SKIP_ITERATION_VISIT_HINTS);
+            component.visitTree(visitContext, new RestoreStateCallback());
+        }
+        finally
+        {
+            // We must remove hint in finally, because an exception can break this phase,
+            // but lifecycle can continue, if custom exception handler swallows the exception
+            facesContext.getAttributes().remove(VisitHintsHelper.SKIP_ITERATION_HINT);
+        }
+    }
+
+    public boolean isPostback(FacesContext facesContext)
+    {
+        ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
+        String renderkitId = viewHandler.calculateRenderKitId(facesContext);
+        ResponseStateManager rsm = renderKitFactory.getRenderKit(facesContext, renderkitId).getResponseStateManager();
+        return rsm.isPostback(facesContext);
+    }
+
+    private static class RestoreStateCallback implements VisitCallback
+    {
+        private PostRestoreStateEvent event;
+
+        @Override
+        public VisitResult visit(VisitContext context, UIComponent target)
+        {
+            if (event == null)
+            {
+                event = new PostRestoreStateEvent(target);
+            }
+            else
+            {
+                event.setComponent(target);
+            }
+
+            // call the processEvent method of the current component.
+            // The argument event must be an instance of AfterRestoreStateEvent whose component
+            // property is the current component in the traversal.
+            target.processEvent(event);
+            
+            return VisitResult.ACCEPT;
+        }
+    }
+}
diff --git a/impl/src/main/java/org/apache/myfaces/resource/BaseResourceHandlerSupport.java b/impl/src/main/java/org/apache/myfaces/resource/BaseResourceHandlerSupport.java
index f8b41f9..2727484 100644
--- a/impl/src/main/java/org/apache/myfaces/resource/BaseResourceHandlerSupport.java
+++ b/impl/src/main/java/org/apache/myfaces/resource/BaseResourceHandlerSupport.java
@@ -18,8 +18,6 @@
  */
 package org.apache.myfaces.resource;
 
-import java.util.Map;
-
 import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
 
@@ -32,13 +30,7 @@ import org.apache.myfaces.config.MyfacesConfig;
  * ie an engine that supports javax.servlet, and uses a standard web.xml file.
  */
 public class BaseResourceHandlerSupport extends ResourceHandlerSupport
-{
-    /**
-     * Identifies the FacesServlet mapping in the current request map.
-     */
-    private static final String CACHED_SERVLET_MAPPING =
-        BaseResourceHandlerSupport.class.getName() + ".CACHED_SERVLET_MAPPING";
-    
+{    
     private static final ResourceLoader[] EMPTY_RESOURCE_LOADERS = new ResourceLoader[]{}; 
     private static final ContractResourceLoader[] EMPTY_CONTRACT_RESOURCE_LOADERS = 
         new ContractResourceLoader[]{}; 
@@ -72,7 +64,7 @@ public class BaseResourceHandlerSupport extends ResourceHandlerSupport
     @Override
     public String calculateResourceBasePath(FacesContext facesContext)
     {        
-        FacesServletMapping mapping = getFacesServletMapping(facesContext);
+        FacesServletMapping mapping = FacesServletMappingUtils.getCurrentRequestFacesServletMapping(facesContext);
         ExternalContext externalContext = facesContext.getExternalContext();      
         
         if (mapping != null)
@@ -122,7 +114,8 @@ public class BaseResourceHandlerSupport extends ResourceHandlerSupport
     @Override
     public boolean isExtensionMapping()
     {
-        FacesServletMapping mapping = getFacesServletMapping(FacesContext.getCurrentInstance());
+        FacesServletMapping mapping = FacesServletMappingUtils.getCurrentRequestFacesServletMapping(
+                FacesContext.getCurrentInstance());
         if (mapping != null)
         {
             if (mapping.isExtensionMapping())
@@ -136,7 +129,8 @@ public class BaseResourceHandlerSupport extends ResourceHandlerSupport
     @Override
     public String getMapping()
     {
-        FacesServletMapping mapping = getFacesServletMapping(FacesContext.getCurrentInstance());
+        FacesServletMapping mapping = FacesServletMappingUtils.getCurrentRequestFacesServletMapping(
+                FacesContext.getCurrentInstance());
         if (mapping != null)
         {
             if (mapping.isExtensionMapping())
@@ -150,29 +144,6 @@ public class BaseResourceHandlerSupport extends ResourceHandlerSupport
         }
         return "";
     }
-
-    /**
-     * Read the web.xml file that is in the classpath and parse its internals to
-     * figure out how the FacesServlet is mapped for the current webapp.
-     */
-    protected FacesServletMapping getFacesServletMapping(FacesContext context)
-    {
-        Map<Object, Object> attributes = context.getAttributes();
-
-        // Has the mapping already been determined during this request?
-        FacesServletMapping mapping = (FacesServletMapping) attributes.get(CACHED_SERVLET_MAPPING);
-        if (mapping == null)
-        {
-            ExternalContext externalContext = context.getExternalContext();
-            mapping = FacesServletMappingUtils.calculateFacesServletMapping(
-                    context, externalContext.getRequestServletPath(),
-                    externalContext.getRequestPathInfo(),
-                    false);
-
-            attributes.put(CACHED_SERVLET_MAPPING, mapping);
-        }
-        return mapping;
-    }
     
     @Override
     public long getStartupTime()
diff --git a/impl/src/main/java/org/apache/myfaces/util/ViewProtectionUtils.java b/impl/src/main/java/org/apache/myfaces/util/ViewProtectionUtils.java
index 685ba08..4195e54 100644
--- a/impl/src/main/java/org/apache/myfaces/util/ViewProtectionUtils.java
+++ b/impl/src/main/java/org/apache/myfaces/util/ViewProtectionUtils.java
@@ -18,9 +18,6 @@
  */
 package org.apache.myfaces.util;
 
-import java.util.Set;
-import javax.faces.context.FacesContext;
-
 /**
  *
  * @since 2.2
@@ -107,25 +104,5 @@ public class ViewProtectionUtils
         return (false);
     }
     
-    public static boolean isViewProtected(FacesContext context, String viewId)
-    {
-        Set<String> protectedViews = context.getApplication().getViewHandler().getProtectedViewsUnmodifiable();
-        if (!protectedViews.isEmpty())
-        {
-            boolean matchFound = false;
-            for (String urlPattern : protectedViews)
-            {
-                if (ViewProtectionUtils.matchPattern(viewId, urlPattern))
-                {
-                    matchFound = true;
-                    break;
-                }
-            }
-            return matchFound;
-        }
-        else
-        {
-            return false;
-        }
-    }
+
 }
diff --git a/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerSupport.java b/impl/src/main/java/org/apache/myfaces/util/VisitHintsHelper.java
similarity index 63%
rename from impl/src/main/java/org/apache/myfaces/application/NavigationHandlerSupport.java
rename to impl/src/main/java/org/apache/myfaces/util/VisitHintsHelper.java
index f4ebe49..c26bd66 100644
--- a/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerSupport.java
+++ b/impl/src/main/java/org/apache/myfaces/util/VisitHintsHelper.java
@@ -16,23 +16,18 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.myfaces.application;
+package org.apache.myfaces.util;
 
-import javax.faces.context.FacesContext;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
+import javax.faces.component.visit.VisitHint;
 
-/**
- *
- * @author lu4242
- */
-public abstract class NavigationHandlerSupport
-{
-  
-    /**
-     * <p>
-     * Calculates the view id from the given faces context, following the algorithm 
-     * described in JSF spec.
-     * </p>
-     */
-    public abstract String calculateViewId(FacesContext facesContext);
 
+public class VisitHintsHelper
+{
+    public static final String SKIP_ITERATION_HINT = "javax.faces.visit.SKIP_ITERATION";
+    
+    public static final Set<VisitHint> SKIP_ITERATION_VISIT_HINTS = Collections.unmodifiableSet( 
+            EnumSet.of(VisitHint.SKIP_ITERATION));
 }
diff --git a/impl/src/main/java/org/apache/myfaces/view/ViewScopeProxyMap.java b/impl/src/main/java/org/apache/myfaces/view/ViewScopeProxyMap.java
index f03807d..1247559 100644
--- a/impl/src/main/java/org/apache/myfaces/view/ViewScopeProxyMap.java
+++ b/impl/src/main/java/org/apache/myfaces/view/ViewScopeProxyMap.java
@@ -40,7 +40,7 @@ import org.apache.myfaces.spi.ViewScopeProviderFactory;
  *
  * @author Leonardo Uribe
  */
-public class ViewScopeProxyMap implements Map<String, Object>, StateHolder
+public class ViewScopeProxyMap extends HashMap<String, Object> implements StateHolder
 {
     private String _viewScopeId;
     
diff --git a/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java b/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java
index 4687c9d..dae47f5 100644
--- a/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java
+++ b/impl/src/main/java/org/apache/myfaces/view/facelets/DefaultFaceletsStateManagementStrategy.java
@@ -20,8 +20,6 @@ package org.apache.myfaces.view.facelets;
 
 import java.io.Serializable;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -39,7 +37,6 @@ import javax.faces.component.UIViewRoot;
 import javax.faces.component.visit.VisitCallback;
 import javax.faces.component.visit.VisitContext;
 import javax.faces.component.visit.VisitContextFactory;
-import javax.faces.component.visit.VisitHint;
 import javax.faces.component.visit.VisitResult;
 import javax.faces.context.FacesContext;
 import javax.faces.event.PostAddToViewEvent;
@@ -57,6 +54,7 @@ import org.apache.myfaces.context.RequestViewContext;
 import org.apache.myfaces.config.MyfacesConfig;
 import org.apache.myfaces.util.ClassUtils;
 import org.apache.myfaces.util.HashMapUtils;
+import org.apache.myfaces.util.VisitHintsHelper;
 import org.apache.myfaces.view.facelets.compiler.CheckDuplicateIdFaceletUtils;
 import org.apache.myfaces.view.facelets.pool.ViewEntry;
 import org.apache.myfaces.view.facelets.pool.ViewPool;
@@ -124,16 +122,8 @@ public class DefaultFaceletsStateManagementStrategy extends StateManagementStrat
     public  static final String COMPONENT_ADDED_AFTER_BUILD_VIEW = "oam.COMPONENT_ADDED_AFTER_BUILD_VIEW"; 
 
 
-    
-
-    
-    private static final String SKIP_ITERATION_HINT = "javax.faces.visit.SKIP_ITERATION";
-    
     private static final Object[] EMPTY_STATES = new Object[]{null, null};
-    
-    private static final Set<VisitHint> VISIT_HINTS = Collections.unmodifiableSet( 
-            EnumSet.of(VisitHint.SKIP_ITERATION));
-    
+
     private static final String UNIQUE_ID_COUNTER_KEY =
               "oam.view.uniqueIdCounter";
     
@@ -945,11 +935,11 @@ public class DefaultFaceletsStateManagementStrategy extends StateManagementStrat
     private void saveStateOnMapVisitTree(final FacesContext facesContext, final Map<String,Object> states,
             final UIViewRoot uiViewRoot)
     {
-        facesContext.getAttributes().put(SKIP_ITERATION_HINT, Boolean.TRUE);
+        facesContext.getAttributes().put(VisitHintsHelper.SKIP_ITERATION_HINT, Boolean.TRUE);
         try
         {
             uiViewRoot.visitTree( getVisitContextFactory().getVisitContext(
-                    facesContext, null, VISIT_HINTS), new VisitCallback()
+                    facesContext, null, VisitHintsHelper.SKIP_ITERATION_VISIT_HINTS), new VisitCallback()
             {
                 @Override
                 public VisitResult visit(VisitContext context, UIComponent target)
@@ -1045,7 +1035,7 @@ public class DefaultFaceletsStateManagementStrategy extends StateManagementStrat
         }
         finally
         {
-            facesContext.getAttributes().remove(SKIP_ITERATION_HINT);
+            facesContext.getAttributes().remove(VisitHintsHelper.SKIP_ITERATION_HINT);
         }
         if (!uiViewRoot.isTransient())
         {
@@ -1063,7 +1053,7 @@ public class DefaultFaceletsStateManagementStrategy extends StateManagementStrat
     private SaveStateAndResetViewCallback saveStateOnMapVisitTreeAndReset(final FacesContext facesContext,
             final Map<String,Object> states, final UIViewRoot uiViewRoot, boolean forceHardReset)
     {
-        facesContext.getAttributes().put(SKIP_ITERATION_HINT, Boolean.TRUE);
+        facesContext.getAttributes().put(VisitHintsHelper.SKIP_ITERATION_HINT, Boolean.TRUE);
         SaveStateAndResetViewCallback callback = new SaveStateAndResetViewCallback(
                 facesContext.getViewRoot(), states, forceHardReset);
         if (forceHardReset)
@@ -1099,11 +1089,11 @@ public class DefaultFaceletsStateManagementStrategy extends StateManagementStrat
             try
             {
                 uiViewRoot.visitTree( getVisitContextFactory().getVisitContext(
-                        facesContext, null, VISIT_HINTS), callback);
+                        facesContext, null, VisitHintsHelper.SKIP_ITERATION_VISIT_HINTS), callback);
             }
             finally
             {
-                facesContext.getAttributes().remove(SKIP_ITERATION_HINT);
+                facesContext.getAttributes().remove(VisitHintsHelper.SKIP_ITERATION_HINT);
             }
             
             if (callback.isViewResetable() && callback.isRemoveAddedComponents())
diff --git a/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java b/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java
index 16c58e1..0f57626 100644
--- a/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java
+++ b/impl/src/main/java/org/apache/myfaces/view/facelets/FaceletViewDeclarationLanguage.java
@@ -94,8 +94,7 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.myfaces.application.StateManagerImpl;
 
 import org.apache.myfaces.config.RuntimeConfig;
-import org.apache.myfaces.application.DefaultViewHandlerSupport;
-import org.apache.myfaces.application.ViewHandlerSupport;
+import org.apache.myfaces.application.ViewIdSupport;
 import org.apache.myfaces.config.MyfacesConfig;
 import org.apache.myfaces.util.ClassUtils;
 import org.apache.myfaces.util.StringUtils;
@@ -219,7 +218,7 @@ public class FaceletViewDeclarationLanguage extends FaceletViewDeclarationLangua
     private final FaceletsCompilerSupport faceletsCompilerSupport;
     private final MyfacesConfig config;
     private final ViewPoolProcessor viewPoolProcessor;
-    private final ViewHandlerSupport viewHandlerSupport;
+    private final ViewIdSupport viewIdSupport;
     
     private StateManagementStrategy stateManagementStrategy;
     private Set<String> fullStateSavingViewIds;
@@ -239,7 +238,7 @@ public class FaceletViewDeclarationLanguage extends FaceletViewDeclarationLangua
         this.config = MyfacesConfig.getCurrentInstance(context);
         this.strategy = strategy;
         this.viewPoolProcessor = ViewPoolProcessor.getInstance(context);
-        this.viewHandlerSupport = new DefaultViewHandlerSupport(context);
+        this.viewIdSupport = ViewIdSupport.getInstance(context);
         this.faceletsCompilerSupport = new FaceletsCompilerSupport();
 
         Compiler compiler = createCompiler(context);
@@ -2079,7 +2078,7 @@ public class FaceletViewDeclarationLanguage extends FaceletViewDeclarationLangua
     @Override
     protected String calculateViewId(FacesContext context, String viewId)
     {
-        return viewHandlerSupport.deriveLogicalViewId(context, viewId);
+        return viewIdSupport.deriveLogicalViewId(context, viewId);
     }
 
     /**
diff --git a/impl/src/main/java/org/apache/myfaces/view/facelets/ViewPoolProcessor.java b/impl/src/main/java/org/apache/myfaces/view/facelets/ViewPoolProcessor.java
index 69590ae..33d5cf8 100644
--- a/impl/src/main/java/org/apache/myfaces/view/facelets/ViewPoolProcessor.java
+++ b/impl/src/main/java/org/apache/myfaces/view/facelets/ViewPoolProcessor.java
@@ -39,7 +39,6 @@ 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.DefaultRestoreViewSupport;
 import org.apache.myfaces.lifecycle.RestoreViewSupport;
 import org.apache.myfaces.config.MyfacesConfig;
 import org.apache.myfaces.util.WebConfigParamUtils;
@@ -144,7 +143,7 @@ public class ViewPoolProcessor
     public ViewPoolProcessor(FacesContext context)
     {
         viewPoolFactory = new ViewPoolFactoryImpl(context);
-        restoreViewSupport = new DefaultRestoreViewSupport(context);
+        restoreViewSupport = new RestoreViewSupport(context);
     }
     
     public static ViewPoolProcessor getInstance(FacesContext context)
diff --git a/impl/src/main/java/org/apache/myfaces/view/jsp/JspViewDeclarationLanguageBase.java b/impl/src/main/java/org/apache/myfaces/view/jsp/JspViewDeclarationLanguageBase.java
index cf21b14..aa03657 100644
--- a/impl/src/main/java/org/apache/myfaces/view/jsp/JspViewDeclarationLanguageBase.java
+++ b/impl/src/main/java/org/apache/myfaces/view/jsp/JspViewDeclarationLanguageBase.java
@@ -42,8 +42,7 @@ import javax.servlet.ServletResponse;
 import javax.servlet.ServletResponseWrapper;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.myfaces.application.DefaultViewHandlerSupport;
-import org.apache.myfaces.application.ViewHandlerSupport;
+import org.apache.myfaces.application.ViewIdSupport;
 import org.apache.myfaces.config.MyfacesConfig;
 import org.apache.myfaces.view.HttpServletResponseSwitch;
 import org.apache.myfaces.view.ResponseSwitch;
@@ -61,7 +60,7 @@ public abstract class JspViewDeclarationLanguageBase extends ViewDeclarationLang
               + ".AFTER_VIEW_TAG_CONTENT";
   private static final int FORM_STATE_MARKER_LEN = FORM_STATE_MARKER.length();
 
-  private ViewHandlerSupport _cachedViewHandlerSupport;
+  private ViewIdSupport viewIdSupport;
   
   @Override
   public String getId()
@@ -373,12 +372,12 @@ public abstract class JspViewDeclarationLanguageBase extends ViewDeclarationLang
   @Override
   protected String calculateViewId(FacesContext context, String viewId)
   {
-      if (_cachedViewHandlerSupport == null)
+      if (viewIdSupport == null)
       {
-          _cachedViewHandlerSupport = new DefaultViewHandlerSupport(context);
+          viewIdSupport = ViewIdSupport.getInstance(context);
       }
   
-      return _cachedViewHandlerSupport.deriveLogicalViewId(context, viewId);
+      return viewIdSupport.deriveLogicalViewId(context, viewId);
   }
   
   /**
diff --git a/impl/src/test/java/org/apache/myfaces/application/ViewIdSupportMockTest.java b/impl/src/test/java/org/apache/myfaces/application/ViewIdSupportMockTest.java
new file mode 100644
index 0000000..071a370
--- /dev/null
+++ b/impl/src/test/java/org/apache/myfaces/application/ViewIdSupportMockTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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.application;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.faces.FacesException;
+
+import org.apache.myfaces.test.MyFacesAsserts;
+import org.apache.myfaces.test.FacesTestCase;
+import org.apache.myfaces.test.TestRunner;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class ViewIdSupportMockTest extends FacesTestCase
+{
+    private ViewIdSupport viewIdSupport;
+
+    @Override
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+
+        Mockito.when(_facesContext.getExternalContext()).thenReturn(_externalContext);
+        Mockito.when(_externalContext.getApplicationMap()).thenReturn(new HashMap<String, Object>());
+
+        viewIdSupport = ViewIdSupport.getInstance(_facesContext);
+    }
+
+    @Test
+    public void testCalculateViewIdFromRequestAttributeIncludePathInfo()
+    {
+        Map<String, Object> map = new HashMap<String, Object>();
+        String expectedValue = "javax.servlet.include.path_info_VIEWID";
+        map.put("javax.servlet.include.path_info", expectedValue);        
+        Mockito.when(_externalContext.getRequestMap()).thenReturn(map);
+
+        assertEquals(expectedValue, viewIdSupport.calculateViewId(_facesContext));
+    }
+
+    public void testCalculateViewIdFromRequestPathInfo()
+    {
+        Mockito.when(_externalContext.getRequestMap()).thenReturn(Collections.emptyMap());
+        
+        String expectedValue = "requestPathInfo_VIEWID";
+        Mockito.when(_externalContext.getRequestPathInfo()).thenReturn(expectedValue);
+
+        assertEquals(expectedValue, viewIdSupport.calculateViewId(_facesContext));
+    }
+
+    public void testCalculateViewIdFromRequestAttributeIncludeServletPath()
+    {
+        Map<String, Object> map = new HashMap<String, Object>();
+        String expectedValue = "javax.servlet.include.servlet_path_VIEWID";
+        map.put("javax.servlet.include.servlet_path", expectedValue);
+        Mockito.when(_externalContext.getRequestMap()).thenReturn(map);
+        
+        Mockito.when(_externalContext.getRequestPathInfo()).thenReturn(null);
+
+        assertEquals(expectedValue, viewIdSupport.calculateViewId(_facesContext));
+    }
+
+    public void testCalculateViewIdFromRequestServletPath()
+    {
+        Mockito.when(_externalContext.getRequestMap()).thenReturn(Collections.emptyMap());
+        Mockito.when(_externalContext.getRequestPathInfo()).thenReturn(null);
+        String expectedValue = "RequestServletPath_VIEWID";
+        Mockito.when(_externalContext.getRequestServletPath()).thenReturn(expectedValue);
+
+        assertEquals(expectedValue, viewIdSupport.calculateViewId(_facesContext));
+    }
+
+    public void testCalculateViewIdFacesException()
+    {
+        Mockito.when(_externalContext.getRequestMap()).thenReturn(Collections.emptyMap());
+        Mockito.when(_externalContext.getRequestPathInfo()).thenReturn(null);
+        Mockito.when(_externalContext.getRequestServletPath()).thenReturn(null);
+
+        MyFacesAsserts.assertException(FacesException.class, new TestRunner()
+        {
+            public void run() throws Throwable
+            {
+                viewIdSupport.calculateViewId(_facesContext);
+            }
+        });
+    }
+}
diff --git a/impl/src/test/java/org/apache/myfaces/shared/application/DefaultViewHandlerSupportTest.java b/impl/src/test/java/org/apache/myfaces/application/ViewIdSupportTest.java
similarity index 73%
rename from impl/src/test/java/org/apache/myfaces/shared/application/DefaultViewHandlerSupportTest.java
rename to impl/src/test/java/org/apache/myfaces/application/ViewIdSupportTest.java
index 6b172a8..7c38708 100644
--- a/impl/src/test/java/org/apache/myfaces/shared/application/DefaultViewHandlerSupportTest.java
+++ b/impl/src/test/java/org/apache/myfaces/application/ViewIdSupportTest.java
@@ -16,9 +16,8 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.myfaces.shared.application;
+package org.apache.myfaces.application;
 
-import org.apache.myfaces.application.DefaultViewHandlerSupport;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.net.URI;
@@ -28,18 +27,28 @@ import org.apache.myfaces.test.base.junit4.AbstractJsfTestCase;
 import org.junit.Assert;
 import org.junit.Test;
 
-public class DefaultViewHandlerSupportTest extends AbstractJsfTestCase
+public class ViewIdSupportTest extends AbstractJsfTestCase
 {
     private final String filePath = this.getDirectory();
+    private ViewIdSupport viewHandlerSupport;
     
     @Override
     protected void setUpServletObjects() throws Exception
     {
         URI context = this.getContext();
         super.setUpServletObjects();
+        
+        //setup document root to correctly resolve viewExists
         servletContext.setDocumentRoot(new File(context));
     }
     
+    @Override
+    public void setUp() throws Exception
+    {
+        super.setUp();
+        viewHandlerSupport = ViewIdSupport.getInstance(facesContext);
+    }
+    
     private String getDirectory()
     {
         return this.getClass().getName().substring(0,
@@ -73,34 +82,28 @@ public class DefaultViewHandlerSupportTest extends AbstractJsfTestCase
     public void testDeriveViewId1() throws Exception
     {
         request.setPathElements("/testwebapp", "/view1.jsf", null , null);
-
-        DefaultViewHandlerSupport support = new DefaultViewHandlerSupport();
         
-        String derivedViewId = support.deriveViewId(facesContext, "/view1.jsf");
+        String derivedViewId = viewHandlerSupport.deriveViewId(facesContext, "/view1.jsf");
         
         Assert.assertNotNull(derivedViewId);
     }
     
     @Test
     public void testDeriveViewId2() throws Exception
-    {
-        DefaultViewHandlerSupport support = new DefaultViewHandlerSupport();
-        
+    {        
         request.setPathElements("/testwebapp", "/faces", "/view1.jsp" , null);
         
-        String derivedViewId = support.deriveViewId(facesContext, "/view1.jsp");
+        String derivedViewId = viewHandlerSupport.deriveViewId(facesContext, "/view1.jsp");
         
         Assert.assertNotNull(derivedViewId);
     }
     
     @Test
     public void testDeriveViewId21() throws Exception
-    {
-        DefaultViewHandlerSupport support = new DefaultViewHandlerSupport();
-        
+    {        
         request.setPathElements("/testwebapp", "/faces", "/faces/view1.jsp" , null);
         
-        String derivedViewId = support.deriveViewId(facesContext, "/faces/view1.jsp");
+        String derivedViewId = viewHandlerSupport.deriveViewId(facesContext, "/faces/view1.jsp");
         
         Assert.assertNotNull(derivedViewId);
     }    
@@ -108,23 +111,19 @@ public class DefaultViewHandlerSupportTest extends AbstractJsfTestCase
     @Test
     public void testDeriveViewId3() throws Exception
     {
-        DefaultViewHandlerSupport support = new DefaultViewHandlerSupport();
-        
         request.setPathElements("/testwebapp", "/view2.jsf", null , null);
         
-        String derivedViewId = support.deriveViewId(facesContext, "/view2.jsf");
+        String derivedViewId = viewHandlerSupport.deriveViewId(facesContext, "/view2.jsf");
         
         Assert.assertNotNull(derivedViewId);
     }
     
     @Test
     public void testDeriveViewId4() throws Exception
-    {
-        DefaultViewHandlerSupport support = new DefaultViewHandlerSupport();
-        
+    {        
         request.setPathElements("/testwebapp", "/faces", "/view2.xhtml" , null);
         
-        String derivedViewId = support.deriveViewId(facesContext, "/view2.xhtml");
+        String derivedViewId = viewHandlerSupport.deriveViewId(facesContext, "/view2.xhtml");
         
         Assert.assertNotNull(derivedViewId);
     }
@@ -134,10 +133,8 @@ public class DefaultViewHandlerSupportTest extends AbstractJsfTestCase
     public void testDeriveViewId5() throws Exception
     {
         request.setPathElements("/testwebapp", "/noview1.jsf", null , null);
-
-        DefaultViewHandlerSupport support = new DefaultViewHandlerSupport();
         
-        String derivedViewId = support.deriveViewId(facesContext, "/noview1.jsf");
+        String derivedViewId = viewHandlerSupport.deriveViewId(facesContext, "/noview1.jsf");
         
         Assert.assertNull(derivedViewId);
     }
@@ -148,12 +145,10 @@ public class DefaultViewHandlerSupportTest extends AbstractJsfTestCase
      */
     @Test
     public void testEmptyPrefixMapping() throws Exception
-    {
-        DefaultViewHandlerSupport support = new DefaultViewHandlerSupport();
-        
+    {        
         request.setPathElements("/testwebapp", "", "/view2.xhtml" , null);
         
-        String derivedViewId = support.deriveViewId(facesContext, "/view2.xhtml");
+        String derivedViewId = viewHandlerSupport.deriveViewId(facesContext, "/view2.xhtml");
         
         Assert.assertEquals("/view2.xhtml", derivedViewId);
     }
@@ -166,13 +161,12 @@ public class DefaultViewHandlerSupportTest extends AbstractJsfTestCase
      */
     @Test
     public void testEmptyPrefixMappingDoubleSlash() throws Exception
-    {
-        DefaultViewHandlerSupport support = new DefaultViewHandlerSupport();
-        
+    {        
         request.setPathElements("/testwebapp", "", "//view2.xhtml" , null);
         
-        String derivedViewId = support.deriveViewId(facesContext, "//view2.xhtml");
+        String derivedViewId = viewHandlerSupport.deriveViewId(facesContext, "//view2.xhtml");
         
         Assert.assertEquals("/view2.xhtml", derivedViewId);
     }
+
 }
diff --git a/impl/src/test/java/org/apache/myfaces/lifecycle/DefaultRestoreViewSupport2Test.java b/impl/src/test/java/org/apache/myfaces/lifecycle/DefaultRestoreViewSupport2Test.java
deleted file mode 100644
index e28d9fb..0000000
--- a/impl/src/test/java/org/apache/myfaces/lifecycle/DefaultRestoreViewSupport2Test.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.lifecycle;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.net.URI;
-import java.net.URL;
-
-import org.apache.myfaces.test.base.junit4.AbstractJsfTestCase;
-import org.junit.Assert;
-import org.junit.Test;
-
-public class DefaultRestoreViewSupport2Test extends AbstractJsfTestCase
-{
-    private final String filePath = this.getDirectory();
-    
-    @Override
-    protected void setUpServletObjects() throws Exception
-    {
-        URI context = this.getContext();
-        super.setUpServletObjects();
-        servletContext.setDocumentRoot(new File(context));
-    }
-    
-    private String getDirectory()
-    {
-        return this.getClass().getName().substring(0,
-                this.getClass().getName().lastIndexOf('.')).replace('.', '/')
-                + "/";
-    }
-    
-    protected URI getContext()
-    {
-        try
-        {
-            ClassLoader cl = Thread.currentThread().getContextClassLoader();
-            URL url = cl.getResource(this.filePath);
-            if (url == null)
-            {
-                throw new FileNotFoundException(cl.getResource("").getFile()
-                        + this.filePath + " was not found");
-            }
-            else
-            {
-                return new URI(url.toString());
-            }
-        }
-        catch (Exception e)
-        {
-            throw new RuntimeException("Error Initializing Context", e);
-        }
-    }
-    
- 
-}
diff --git a/impl/src/test/java/org/apache/myfaces/lifecycle/DefaultRestoreViewSupportTest.java b/impl/src/test/java/org/apache/myfaces/lifecycle/DefaultRestoreViewSupportTest.java
deleted file mode 100644
index 2d89d7f..0000000
--- a/impl/src/test/java/org/apache/myfaces/lifecycle/DefaultRestoreViewSupportTest.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * 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.lifecycle;
-
-import static org.easymock.EasyMock.expect;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.faces.FacesException;
-
-import org.apache.myfaces.test.MyFacesAsserts;
-import org.apache.myfaces.test.FacesTestCase;
-import org.apache.myfaces.test.TestRunner;
-
-/**
- * @author Mathias Broekelmann (latest modification by $Author$)
- * @version $Revision$ $Date$
- */
-public class DefaultRestoreViewSupportTest extends FacesTestCase
-{
-
-    private DefaultRestoreViewSupport _testimpl;
-
-    protected void setUp() throws Exception
-    {
-        super.setUp();
-        _testimpl = new DefaultRestoreViewSupport();
-    }
-
-    /**
-     * Test method for
-     * {@link org.apache.myfaces.lifecycle.DefaultRestoreViewSupport#processComponentBinding(javax.faces.context.FacesContext, javax.faces.component.UIComponent)}.
-     */
-    /*
-    public void testProcessComponentBinding()
-    {
-        UIComponent root = _mocksControl.createMock(UIComponent.class);
-        UIComponent testcomponent = _mocksControl.createMock(UIComponent.class);
-        ValueExpression rootExpression = _mocksControl.createMock(ValueExpression.class);
-        ValueExpression testExpression = _mocksControl.createMock(ValueExpression.class);
-        
-        _mocksControl.checkOrder(true);
-        expect(root.getValueExpression(eq("binding"))).andReturn(rootExpression);
-        expect(_facesContext.getELContext()).andReturn(_elContext);
-        rootExpression.setValue(same(_elContext), same(root));
-        expect(root.getFacetsAndChildren()).andReturn(Arrays.asList(new UIComponent[] { testcomponent }).iterator());
-        expect(testcomponent.getValueExpression(eq("binding"))).andReturn(testExpression);
-        expect(_facesContext.getELContext()).andReturn(_elContext);
-        testExpression.setValue(same(_elContext), same(testcomponent));
-        
-        List<UIComponent> emptyList = Collections.emptyList();
-        expect(testcomponent.getFacetsAndChildren()).andReturn(emptyList.iterator());
-
-        _mocksControl.replay();
-        _testimpl.processComponentBinding(_facesContext, root);
-        _mocksControl.verify();
-    }
-    */
-
-    /**
-     * Test method for
-     * {@link org.apache.myfaces.lifecycle.DefaultRestoreViewSupport#calculateViewId(javax.faces.context.FacesContext)}.
-     */
-    public void testCalculateViewIdFromRequestAttributeIncludePathInfo()
-    {
-        _mocksControl.checkOrder(true);
-        expect(_facesContext.getExternalContext()).andReturn(_externalContext);
-        Map<String, Object> map = new HashMap<String, Object>();
-        String expectedValue = "javax.servlet.include.path_info_VIEWID";
-        map.put("javax.servlet.include.path_info", expectedValue);
-        expect(_externalContext.getRequestMap()).andReturn(map);
-        //expect(_facesContext.getApplication()).andReturn(_application);
-        //ViewHandler viewHandler = _mocksControl.createMock(ViewHandler.class);
-        //expect(_application.getViewHandler()).andReturn(viewHandler);
-        //expect(viewHandler.deriveViewId(
-        //        same(_facesContext), eq(expectedValue))).andReturn(expectedValue);
-        _mocksControl.replay();
-        assertEquals(expectedValue, _testimpl.calculateViewId(_facesContext));
-        _mocksControl.verify();
-    }
-
-    /**
-     * Test method for
-     * {@link org.apache.myfaces.lifecycle.DefaultRestoreViewSupport#calculateViewId(javax.faces.context.FacesContext)}.
-     */
-    public void testCalculateViewIdFromRequestPathInfo()
-    {
-        _mocksControl.checkOrder(true);
-        expect(_facesContext.getExternalContext()).andReturn(_externalContext);
-        
-        Map<String, Object> emptyMap = Collections.emptyMap();
-        expect(_externalContext.getRequestMap()).andReturn(emptyMap);
-        String expectedValue = "requestPathInfo_VIEWID";
-        expect(_externalContext.getRequestPathInfo()).andReturn(expectedValue);
-        //expect(_facesContext.getApplication()).andReturn(_application);
-        //ViewHandler viewHandler = _mocksControl.createMock(ViewHandler.class);
-        //expect(_application.getViewHandler()).andReturn(viewHandler);
-        //expect(viewHandler.deriveViewId(
-        //        same(_facesContext), eq(expectedValue))).andReturn(expectedValue);
-
-        _mocksControl.replay();
-        assertEquals(expectedValue, _testimpl.calculateViewId(_facesContext));
-        _mocksControl.verify();
-    }
-
-    /**
-     * Test method for
-     * {@link org.apache.myfaces.lifecycle.DefaultRestoreViewSupport#calculateViewId(javax.faces.context.FacesContext)}.
-     */
-    public void testCalculateViewIdFromRequestAttributeIncludeServletPath()
-    {
-        _mocksControl.checkOrder(true);
-        expect(_facesContext.getExternalContext()).andReturn(_externalContext);
-        Map<String, Object> map = new HashMap<String, Object>();
-        String expectedValue = "javax.servlet.include.servlet_path_VIEWID";
-        map.put("javax.servlet.include.servlet_path", expectedValue);
-        expect(_externalContext.getRequestMap()).andReturn(map);
-        expect(_externalContext.getRequestPathInfo()).andReturn(null);
-        //expect(_facesContext.getApplication()).andReturn(_application);
-        //ViewHandler viewHandler = _mocksControl.createMock(ViewHandler.class);
-        //expect(_application.getViewHandler()).andReturn(viewHandler);
-        //expect(viewHandler.deriveViewId(
-        //        same(_facesContext), eq(expectedValue))).andReturn(expectedValue);
-
-        _mocksControl.replay();
-        assertEquals(expectedValue, _testimpl.calculateViewId(_facesContext));
-        _mocksControl.verify();
-    }
-
-    /**
-     * Test method for
-     * {@link org.apache.myfaces.lifecycle.DefaultRestoreViewSupport#calculateViewId(javax.faces.context.FacesContext)}.
-     */
-    public void testCalculateViewIdFromRequestServletPath()
-    {
-        _mocksControl.checkOrder(true);
-        expect(_facesContext.getExternalContext()).andReturn(_externalContext);
-        
-        Map<String, Object> emptyMap = Collections.emptyMap();
-        
-        expect(_externalContext.getRequestMap()).andReturn(emptyMap);
-        expect(_externalContext.getRequestPathInfo()).andReturn(null);
-        String expectedValue = "RequestServletPath_VIEWID";
-        expect(_externalContext.getRequestServletPath()).andReturn(expectedValue);
-        //expect(_facesContext.getApplication()).andReturn(_application);
-        //ViewHandler viewHandler = _mocksControl.createMock(ViewHandler.class);
-        //expect(_application.getViewHandler()).andReturn(viewHandler);
-        //expect(viewHandler.deriveViewId(
-        //        same(_facesContext), eq(expectedValue))).andReturn(expectedValue);
-
-        _mocksControl.replay();
-        assertEquals(expectedValue, _testimpl.calculateViewId(_facesContext));
-        _mocksControl.verify();
-    }
-
-    /**
-     * Test method for
-     * {@link org.apache.myfaces.lifecycle.DefaultRestoreViewSupport#calculateViewId(javax.faces.context.FacesContext)}.
-     */
-    public void testCalculateViewIdFacesException()
-    {
-        _mocksControl.checkOrder(true);
-        expect(_facesContext.getExternalContext()).andReturn(_externalContext);
-        
-        Map<String, Object> emptyMap = Collections.emptyMap();
-        
-        expect(_externalContext.getRequestMap()).andReturn(emptyMap);
-        expect(_externalContext.getRequestPathInfo()).andReturn(null);
-        expect(_externalContext.getRequestServletPath()).andReturn(null);
-
-        _mocksControl.replay();
-        MyFacesAsserts.assertException(FacesException.class, new TestRunner()
-        {
-            public void run() throws Throwable
-            {
-                _testimpl.calculateViewId(_facesContext);
-            }
-        });
-        _mocksControl.verify();
-    }
-
-    /**
-     * Test method for
-     * {@link org.apache.myfaces.lifecycle.DefaultRestoreViewSupport#isPostback(javax.faces.context.FacesContext)}.
-     */
-    public void testIsPostback()
-    {
-        // TODO: not testable unless static call to RendererUtils is removed
-    }
-
-}
diff --git a/impl/src/test/java/org/apache/myfaces/lifecycle/RestoreViewExecutorTest.java b/impl/src/test/java/org/apache/myfaces/lifecycle/RestoreViewExecutorTest.java
index 202e14e..d6c74cd 100644
--- a/impl/src/test/java/org/apache/myfaces/lifecycle/RestoreViewExecutorTest.java
+++ b/impl/src/test/java/org/apache/myfaces/lifecycle/RestoreViewExecutorTest.java
@@ -18,17 +18,15 @@
  */
 package org.apache.myfaces.lifecycle;
 
-import static org.easymock.EasyMock.eq;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.same;
-
 import java.util.Locale;
 
 import javax.faces.application.ViewHandler;
 import javax.faces.component.UIViewRoot;
 import javax.faces.event.PhaseId;
+import org.apache.myfaces.application.ViewIdSupport;
 
 import org.apache.myfaces.test.FacesTestCase;
+import org.mockito.Mockito;
 
 /**
  * @author Mathias Broekelmann (latest modification by $Author$)
@@ -39,15 +37,18 @@ public class RestoreViewExecutorTest extends FacesTestCase
     private RestoreViewExecutor _testimpl;
     private ViewHandler _viewHandler;
     private RestoreViewSupport _restoreViewSupport;
+    private ViewIdSupport _viewHandlerSupport;
 
     @Override
     protected void setUp() throws Exception
     {
         super.setUp();
-        _viewHandler = _mocksControl.createMock(ViewHandler.class);
-        _restoreViewSupport = _mocksControl.createMock(RestoreViewSupport.class);
+        _viewHandler = Mockito.mock(ViewHandler.class);
+        _restoreViewSupport = Mockito.mock(RestoreViewSupport.class);
+        _viewHandlerSupport = Mockito.mock(ViewIdSupport.class);
         _testimpl = new RestoreViewExecutor();
         _testimpl.setRestoreViewSupport(_restoreViewSupport);
+        _testimpl.setViewHandlerSupport(_viewHandlerSupport);
     }
 
     /**
@@ -56,133 +57,20 @@ public class RestoreViewExecutorTest extends FacesTestCase
      */
     public void testExecuteWithExistingViewRoot()
     {
-        expect(_facesContext.getApplication()).andReturn(_application).anyTimes();
-        expect(_application.getViewHandler()).andReturn(_viewHandler).anyTimes();
-        _viewHandler.initView(eq(_facesContext));
-        UIViewRoot viewRoot = _mocksControl.createMock(UIViewRoot.class);
-        expect(_facesContext.getViewRoot()).andReturn(viewRoot).times(2);
+        Mockito.when(_facesContext.getApplication()).thenReturn(_application);
+        Mockito.when(_application.getViewHandler()).thenReturn(_viewHandler);
+        _viewHandler.initView(_facesContext);
+        UIViewRoot viewRoot = Mockito.mock(UIViewRoot.class);
+        Mockito.when(_facesContext.getViewRoot()).thenReturn(viewRoot);
         Locale expectedLocale = new Locale("xxx");
-        expect(_facesContext.getExternalContext()).andReturn(_externalContext).anyTimes();
-        expect(_externalContext.getRequestLocale()).andReturn(expectedLocale);
-        viewRoot.setLocale(eq(expectedLocale));
-        expect(viewRoot.getAfterPhaseListener()).andReturn(null);
-        _restoreViewSupport.processComponentBinding(same(_facesContext), same(viewRoot));
+        Mockito.when(_facesContext.getExternalContext()).thenReturn(_externalContext);
+        Mockito.when(_externalContext.getRequestLocale()).thenReturn(expectedLocale);
+        viewRoot.setLocale(expectedLocale);
+        Mockito.when(viewRoot.getAfterPhaseListener()).thenReturn(null);
+        _restoreViewSupport.processComponentBinding(_facesContext, viewRoot);
 
-        _mocksControl.replay();
         _testimpl.doPrePhaseActions(_facesContext);
         _testimpl.execute(_facesContext);
-        _mocksControl.verify();
-    }
-
-    /**
-     * Test method for
-     * {@link org.apache.myfaces.lifecycle.RestoreViewExecutor#execute(javax.faces.context.FacesContext)}.
-     *//*
-    public void testExecuteWOExistingViewRootNoPostBack()
-    {
-        setupWOExistingViewRoot();
-        expect(_facesContext.getExternalContext()).andReturn(_externalContext).anyTimes();
-        expect(_externalContext.getRequestMap()).andReturn(new HashMap());
-        expect(_restoreViewSupport.isPostback(same(_facesContext))).andReturn(false);
-        _facesContext.renderResponse();
-
-        UIViewRoot viewRoot = _mocksControl.createMock(UIViewRoot.class);
-        //viewRoot.subscribeToEvent(same(PostAddToViewEvent.class), same(viewRoot));
-
-        ViewDeclarationLanguage vdl = _mocksControl.createMock(ViewDeclarationLanguage.class);
-        //expect(_restoreViewSupport.deriveViewId(same(_facesContext), eq("calculatedViewId"))).andReturn("calculatedViewId");
-        expect(_viewHandler.deriveLogicalViewId(same(_facesContext), eq("calculatedViewId"))).andReturn("calculatedViewId");
-        expect(_facesContext.getResponseComplete()).andReturn(false);
-        expect(_viewHandler.getViewDeclarationLanguage(same(_facesContext), eq("calculatedViewId")))
-            .andReturn(vdl);
-        expect(vdl.getViewMetadata(same(_facesContext), eq("calculatedViewId")))
-            .andReturn(null);
-        expect(_viewHandler.createView(same(_facesContext), eq("calculatedViewId"))).andReturn(viewRoot);
-        expect(_application.getFlowHandler()).andReturn(null);
-        _application.publishEvent(same(_facesContext), same(PostAddToViewEvent.class), same(viewRoot));
-        _facesContext.setViewRoot(same(viewRoot));
-        expect(_facesContext.getViewRoot()).andReturn(viewRoot);
-        expect(viewRoot.getAfterPhaseListener()).andReturn(null);
-
-        _mocksControl.replay();
-        _testimpl.doPrePhaseActions(_facesContext);
-        _testimpl.execute(_facesContext);
-        _mocksControl.verify();
-    }*/
-
-    /**
-     * Test method for
-     * {@link org.apache.myfaces.lifecycle.RestoreViewExecutor#execute(javax.faces.context.FacesContext)}.
-     *//*
-    public void testExecuteWOExistingViewRootPostBack()
-    {
-        setupWOExistingViewRoot();
-        expect(_facesContext.getExternalContext()).andReturn(_externalContext).anyTimes();
-        expect(_externalContext.getRequestMap()).andReturn(new HashMap());
-        expect(_restoreViewSupport.isPostback(same(_facesContext))).andReturn(true);
-        _facesContext.setProcessingEvents(eq(true));
-        UIViewRoot viewRoot = _mocksControl.createMock(UIViewRoot.class);
-        expect(_viewHandler.restoreView(same(_facesContext), eq("calculatedViewId"))).andReturn(viewRoot);
-        _restoreViewSupport.processComponentBinding(same(_facesContext), same(viewRoot));
-        _facesContext.setViewRoot(same(viewRoot));
-        _facesContext.setProcessingEvents(eq(false));
-        expect(_facesContext.getViewRoot()).andReturn(viewRoot);
-        expect(viewRoot.getAfterPhaseListener()).andReturn(null);
-
-        _mocksControl.replay();
-        _testimpl.doPrePhaseActions(_facesContext);
-        _testimpl.execute(_facesContext);
-        _mocksControl.verify();
-    }*/
-
-    /**
-     * Test method for
-     * {@link org.apache.myfaces.lifecycle.RestoreViewExecutor#execute(javax.faces.context.FacesContext)}.
-     *//*
-    public void testExecuteWOExistingViewRootPostBackAndViewExpired()
-    {
-        setupWOExistingViewRoot();
-        expect(_facesContext.getExternalContext()).andReturn(_externalContext).anyTimes();
-        expect(_externalContext.getRequestMap()).andReturn(new HashMap());
-        expect(_restoreViewSupport.isPostback(same(_facesContext))).andReturn(true);
-        _facesContext.setProcessingEvents(eq(true));
-        expect(_viewHandler.restoreView(same(_facesContext), eq("calculatedViewId"))).andReturn(null);
-        _facesContext.setProcessingEvents(eq(false));
-
-        _mocksControl.replay();
-        assertException(ViewExpiredException.class, new TestRunner()
-        {
-            public void run() throws Throwable
-            {
-                _testimpl.doPrePhaseActions(_facesContext);
-                _testimpl.execute(_facesContext);
-            };
-        });
-        _mocksControl.verify();
-    }*/
-
-    private void setupWOExistingViewRoot()
-    {
-        expect(_facesContext.getApplication()).andReturn(_application).anyTimes();
-        expect(_application.getViewHandler()).andReturn(_viewHandler).anyTimes();
-        _viewHandler.initView(eq(_facesContext));
-        expect(_facesContext.getViewRoot()).andReturn(null);
-        expect(_restoreViewSupport.calculateViewId(eq(_facesContext))).andReturn("calculatedViewId");
-    }
-
-    /**
-     * Test method for {@link org.apache.myfaces.lifecycle.RestoreViewExecutor#getRestoreViewSupport()}.
-     */
-    public void testGetRestoreViewSupport() throws Exception
-    {
-        expect(_facesContext.getExternalContext()).andReturn(_externalContext).anyTimes();
-        expect(_externalContext.getInitParameter("javax.faces.FACELETS_VIEW_MAPPINGS")).andReturn(null).anyTimes();
-        expect(_externalContext.getInitParameter("facelets.VIEW_MAPPINGS")).andReturn(null).anyTimes();
-        expect(_externalContext.getInitParameter("javax.faces.FACELETS_SUFFIX")).andReturn(null).anyTimes();
-        expect(_externalContext.getInitParameter("javax.faces.DEFAULT_SUFFIX")).andReturn(null).anyTimes();
-        _mocksControl.replay();
-        assertTrue(DefaultRestoreViewSupport.class.equals(new RestoreViewExecutor().getRestoreViewSupport(_facesContext).getClass()));
-        _mocksControl.verify();
     }
 
     /**
diff --git a/impl/src/test/java/org/apache/myfaces/shared/renderkit/html/HtmlResponseStateManagerTest.java b/impl/src/test/java/org/apache/myfaces/shared/renderkit/html/HtmlResponseStateManagerTest.java
new file mode 100644
index 0000000..b8a98a5
--- /dev/null
+++ b/impl/src/test/java/org/apache/myfaces/shared/renderkit/html/HtmlResponseStateManagerTest.java
@@ -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.shared.renderkit.html;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.faces.render.ResponseStateManager;
+import static junit.framework.TestCase.assertEquals;
+import org.apache.myfaces.renderkit.html.HtmlResponseStateManager;
+import org.apache.myfaces.test.FacesTestCase;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class HtmlResponseStateManagerTest extends FacesTestCase
+{
+    @Test
+    public void testIsPostback()
+    {
+        HtmlResponseStateManager hrsm = Mockito.spy(HtmlResponseStateManager.class);
+        
+        Mockito.when(_facesContext.getExternalContext()).thenReturn(_externalContext);
+        
+        Map<String, String> map = new HashMap<>();
+        map.put(ResponseStateManager.VIEW_STATE_PARAM, "seomthing");
+        Mockito.when(_externalContext.getRequestParameterMap()).thenReturn(map);
+
+        assertEquals(true, hrsm.isPostback(_facesContext));
+    }
+    
+    @Test
+    public void testIsNoPostback()
+    {
+        HtmlResponseStateManager hrsm = Mockito.spy(HtmlResponseStateManager.class);
+        
+        Mockito.when(_facesContext.getExternalContext()).thenReturn(_externalContext);
+        
+        Map<String, String> map = new HashMap<>();
+        Mockito.when(_externalContext.getRequestParameterMap()).thenReturn(map);
+
+        assertEquals(false, hrsm.isPostback(_facesContext));
+    }
+}
diff --git a/impl/src/test/java/org/apache/myfaces/test/FacesTestCase.java b/impl/src/test/java/org/apache/myfaces/test/FacesTestCase.java
index 62de971..a1f95d2 100644
--- a/impl/src/test/java/org/apache/myfaces/test/FacesTestCase.java
+++ b/impl/src/test/java/org/apache/myfaces/test/FacesTestCase.java
@@ -26,8 +26,7 @@ import javax.faces.context.FacesContext;
 import junit.framework.TestCase;
 
 import org.apache.myfaces.test.mock.MockFacesContext12;
-import org.easymock.classextension.EasyMock;
-import org.easymock.classextension.IMocksControl;
+import org.mockito.Mockito;
 
 /**
  * @author Mathias Broekelmann (latest modification by $Author$)
@@ -36,19 +35,17 @@ import org.easymock.classextension.IMocksControl;
 public abstract class FacesTestCase extends TestCase
 {
     protected FacesContext _facesContext;
-    protected IMocksControl _mocksControl;
     protected ExternalContext _externalContext;
     protected Application _application;
     protected ELContext _elContext;
 
     protected void setUp() throws Exception
     {
-        _mocksControl = EasyMock.createControl();
-        _externalContext = _mocksControl.createMock(ExternalContext.class);
-        _facesContext = _mocksControl.createMock(FacesContext.class);
+        _externalContext = Mockito.mock(ExternalContext.class);
+        _facesContext = Mockito.mock(FacesContext.class);
         MockFacesContext12.setCurrentInstance(_facesContext);
-        _application = _mocksControl.createMock(Application.class);
-        _elContext = _mocksControl.createMock(ELContext.class);        
+        _application = Mockito.mock(Application.class);
+        _elContext = Mockito.mock(ELContext.class);        
     }
     
     @Override
diff --git a/impl/src/test/java/org/apache/myfaces/view/facelets/FaceletMultipleRequestsTestCase.java b/impl/src/test/java/org/apache/myfaces/view/facelets/FaceletMultipleRequestsTestCase.java
index 85203ff..0910da3 100644
--- a/impl/src/test/java/org/apache/myfaces/view/facelets/FaceletMultipleRequestsTestCase.java
+++ b/impl/src/test/java/org/apache/myfaces/view/facelets/FaceletMultipleRequestsTestCase.java
@@ -51,7 +51,7 @@ import org.apache.myfaces.config.element.facelets.FaceletTagLibrary;
 import org.apache.myfaces.config.impl.digester.DigesterFacesConfigDispenserImpl;
 import org.apache.myfaces.config.impl.digester.DigesterFacesConfigUnmarshallerImpl;
 import org.apache.myfaces.context.PartialViewContextFactoryImpl;
-import org.apache.myfaces.application.ViewHandlerSupport;
+import org.apache.myfaces.application.ViewIdSupport;
 import org.apache.myfaces.util.ClassUtils;
 import org.apache.myfaces.spi.FacesConfigurationProviderFactory;
 import org.apache.myfaces.test.base.junit4.AbstractJsfConfigurableMultipleRequestsTestCase;
@@ -230,7 +230,7 @@ public abstract class FaceletMultipleRequestsTestCase extends AbstractJsfConfigu
         ((MockFacesContext)facesContext).setApplication(application);
         
         ViewHandlerImpl viewHandler = (ViewHandlerImpl) application.getViewHandler();
-        viewHandler.setViewHandlerSupport(new ViewHandlerSupport(){
+        viewHandler.setViewIdSupport(new ViewIdSupport(facesContext){
 
             @Override
             public String calculateActionURL(FacesContext facesContext,
diff --git a/impl/src/test/java/org/apache/myfaces/view/facelets/FaceletTestCase.java b/impl/src/test/java/org/apache/myfaces/view/facelets/FaceletTestCase.java
index c519d49..611d7c7 100644
--- a/impl/src/test/java/org/apache/myfaces/view/facelets/FaceletTestCase.java
+++ b/impl/src/test/java/org/apache/myfaces/view/facelets/FaceletTestCase.java
@@ -52,7 +52,7 @@ import org.apache.myfaces.config.element.facelets.FaceletTagLibrary;
 import org.apache.myfaces.config.impl.digester.DigesterFacesConfigDispenserImpl;
 import org.apache.myfaces.config.impl.digester.DigesterFacesConfigUnmarshallerImpl;
 import org.apache.myfaces.context.PartialViewContextFactoryImpl;
-import org.apache.myfaces.application.ViewHandlerSupport;
+import org.apache.myfaces.application.ViewIdSupport;
 import org.apache.myfaces.util.ClassUtils;
 import org.apache.myfaces.spi.FacesConfigurationProviderFactory;
 import org.apache.myfaces.test.base.junit4.AbstractJsfConfigurableMockTestCase;
@@ -210,7 +210,7 @@ public abstract class FaceletTestCase extends AbstractJsfConfigurableMockTestCas
         super.setUpApplication();
         
         ViewHandlerImpl viewHandler = (ViewHandlerImpl) facesContext.getApplication().getViewHandler();
-        viewHandler.setViewHandlerSupport(new ViewHandlerSupport(){
+        viewHandler.setViewIdSupport(new ViewIdSupport(facesContext){
 
             public String calculateActionURL(FacesContext facesContext,
                     String viewId)
diff --git a/impl/src/test/resources/org/apache/myfaces/application/view1.jsp b/impl/src/test/resources/org/apache/myfaces/application/view1.jsp
new file mode 100644
index 0000000..193fd69
--- /dev/null
+++ b/impl/src/test/resources/org/apache/myfaces/application/view1.jsp
@@ -0,0 +1,27 @@
+<!--
+ Licensed 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.
+
+ $Id$
+-->
+<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
+    pageEncoding="ISO-8859-1"%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Insert title here</title>
+</head>
+<body>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/impl/src/test/resources/org/apache/myfaces/application/view2.xhtml b/impl/src/test/resources/org/apache/myfaces/application/view2.xhtml
new file mode 100644
index 0000000..9373340
--- /dev/null
+++ b/impl/src/test/resources/org/apache/myfaces/application/view2.xhtml
@@ -0,0 +1,25 @@
+<!--
+ Licensed 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.
+
+ $Id: defineInclude.xml 804043 2009-08-13 22:08:44Z lu4242 $
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Insert title here</title>
+</head>
+<body>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/parent/pom.xml b/parent/pom.xml
index b8abb1b..da008aa 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -475,6 +475,13 @@
             </dependency>
 
             <dependency>
+                <groupId>org.mockito</groupId>
+                <artifactId>mockito-core</artifactId>
+                <version>2.23.0</version>
+                <scope>test</scope>
+            </dependency>
+
+            <dependency>
                 <groupId>de.berlios.jsunit</groupId>
                 <artifactId>jsunit-maven2-plugin</artifactId>
                 <version>1.3</version>


Mime
View raw message