You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ta...@apache.org on 2021/03/16 09:39:41 UTC

[myfaces] branch master updated: refactored flows

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 6f5599a  refactored flows
6f5599a is described below

commit 6f5599a219ae1f19d6a6ba7a8a9dc566b0bff1a4
Author: Thomas Andraschko <ta...@apache.org>
AuthorDate: Tue Mar 16 10:39:32 2021 +0100

    refactored flows
---
 .../viewstate/StateCacheServerSide.java            |   2 +-
 .../apache/myfaces/cdi/JsfArtifactProducer.java    | 373 +++++++++++----------
 .../cdi/clientwindow/ClientWindowScopeContext.java |  17 +-
 .../ClientWindowScopeContextualStorageHolder.java  |  10 +
 .../myfaces/cdi/model/FacesDataModelManager.java   |   2 +-
 .../cdi/util/AbstractContextualStorageHolder.java  |  37 +-
 .../java/org/apache/myfaces/cdi/util/CDIUtils.java |   6 +
 .../apache/myfaces/cdi/view/ViewScopeCDIMap.java   |   4 +-
 .../apache/myfaces/cdi/view/ViewScopeContext.java  |  19 +-
 .../cdi/view/ViewScopeContextualStorageHolder.java |  10 +
 .../cdi/wrapper/FacesBehaviorCDIWrapper.java       |   3 +-
 .../cdi/wrapper/FacesClientBehaviorCDIWrapper.java |   3 +-
 .../cdi/wrapper/FacesConverterCDIWrapper.java      |   2 +-
 .../cdi/wrapper/FacesValidatorCDIWrapper.java      |   2 +-
 .../myfaces/el/DefaultELResolverBuilder.java       |   3 +-
 .../org/apache/myfaces/el/ELResolverBuilder.java   |   2 +-
 .../flow/cdi/DefaultCDIFacesFlowProvider.java      |  81 +----
 .../flow/cdi/FacesFlowClientWindowCollection.java  |  70 ----
 .../myfaces/flow/cdi/FlowBuilderExtension.java     |  47 ---
 .../myfaces/flow/cdi/FlowBuilderFactoryBean.java   |  46 ---
 .../myfaces/flow/cdi/FlowScopeBeanHolder.java      | 334 ------------------
 .../apache/myfaces/flow/cdi/FlowScopeContext.java  | 167 +++------
 .../flow/cdi/FlowScopeContextualStorageHolder.java | 215 ++++++++++++
 .../myfaces/flow/cdi/FlowScopeExtension.java       |   6 +-
 .../org/apache/myfaces/flow/cdi/FlowScopeMap.java  |  20 +-
 .../flow/impl/DefaultFacesFlowProvider.java        |   6 -
 .../myfaces/push/WebsocketComponentRenderer.java   |   6 +-
 .../myfaces/push/cdi/PushContextCDIExtension.java  |   4 -
 .../myfaces/push/cdi/PushContextFactoryBean.java   |  44 ---
 .../apache/myfaces/push/cdi/PushContextImpl.java   |   4 +-
 .../org/apache/myfaces/spi/FacesFlowProvider.java  |   2 -
 .../org/apache/myfaces/view/ViewScopeProxyMap.java |   2 +-
 .../myfaces/webapp/AbstractFacesInitializer.java   |  13 -
 .../myfaces/webapp/MyFacesHttpSessionListener.java |  21 +-
 .../jakarta.enterprise.inject.spi.Extension        |   1 -
 35 files changed, 572 insertions(+), 1012 deletions(-)

diff --git a/impl/src/main/java/org/apache/myfaces/application/viewstate/StateCacheServerSide.java b/impl/src/main/java/org/apache/myfaces/application/viewstate/StateCacheServerSide.java
index df6f771..93fa65b 100644
--- a/impl/src/main/java/org/apache/myfaces/application/viewstate/StateCacheServerSide.java
+++ b/impl/src/main/java/org/apache/myfaces/application/viewstate/StateCacheServerSide.java
@@ -72,7 +72,7 @@ class StateCacheServerSide extends StateCache<Object, Object>
     private final int numberOfSequentialViewsInSession;
     private final boolean serializeStateInSession;
     private final boolean compressStateInSession;
-    
+
     private final SessionViewStorageFactory sessionViewStorageFactory;
     private final CsrfSessionTokenFactory csrfSessionTokenFactory;
     private final StateTokenProcessor stateTokenProcessor;
diff --git a/impl/src/main/java/org/apache/myfaces/cdi/JsfArtifactProducer.java b/impl/src/main/java/org/apache/myfaces/cdi/JsfArtifactProducer.java
index 50f3ee6..5f25cfa 100644
--- a/impl/src/main/java/org/apache/myfaces/cdi/JsfArtifactProducer.java
+++ b/impl/src/main/java/org/apache/myfaces/cdi/JsfArtifactProducer.java
@@ -21,6 +21,7 @@ package org.apache.myfaces.cdi;
 import java.util.Map;
 import jakarta.enterprise.context.ApplicationScoped;
 import jakarta.enterprise.inject.Produces;
+import jakarta.enterprise.inject.spi.InjectionPoint;
 import jakarta.faces.annotation.ApplicationMap;
 import jakarta.faces.annotation.HeaderMap;
 import jakarta.faces.annotation.HeaderValuesMap;
@@ -37,188 +38,210 @@ import jakarta.faces.component.UIViewRoot;
 import jakarta.faces.context.ExternalContext;
 import jakarta.faces.context.FacesContext;
 import jakarta.faces.context.Flash;
+import jakarta.faces.flow.builder.FlowBuilder;
+import jakarta.faces.flow.builder.FlowBuilderParameter;
 import jakarta.faces.lifecycle.ClientWindow;
+import jakarta.faces.push.Push;
+import jakarta.faces.push.PushContext;
 import jakarta.inject.Named;
 import org.apache.myfaces.cdi.view.ViewTransientScoped;
+import org.apache.myfaces.flow.builder.FlowBuilderImpl;
+import org.apache.myfaces.push.cdi.PushContextImpl;
 
 @ApplicationScoped
 public class JsfArtifactProducer
 {
-   @Produces
-   @Named("application")
-   @ApplicationScoped
-   public Application getApplication()
-   {
-      return FacesContext.getCurrentInstance().getApplication();
-   }
-   
-   @Produces
-   @Named("applicationScope")
-   @ApplicationMap
-   @ApplicationScoped
-   public Map<String, Object> getApplicationMap()
-   {
-       return FacesContext.getCurrentInstance().getExternalContext().getApplicationMap();
-   }
-
-   @Produces
-   @Named("initParam")
-   @InitParameterMap
-   @ApplicationScoped
-   public Map<String, String> getInitParameterMap()
-   {
-       return FacesContext.getCurrentInstance().getExternalContext().getInitParameterMap();
-   }
+    @Produces
+    @Named("application")
+    @ApplicationScoped
+    public Application getApplication()
+    {
+       return FacesContext.getCurrentInstance().getApplication();
+    }
+
+    @Produces
+    @Named("applicationScope")
+    @ApplicationMap
+    @ApplicationScoped
+    public Map<String, Object> getApplicationMap()
+    {
+        return FacesContext.getCurrentInstance().getExternalContext().getApplicationMap();
+    }
+
+    @Produces
+    @Named("initParam")
+    @InitParameterMap
+    @ApplicationScoped
+    public Map<String, String> getInitParameterMap()
+    {
+        return FacesContext.getCurrentInstance().getExternalContext().getInitParameterMap();
+    }
+
+    @Produces
+    @Named("resource")
+    @ApplicationScoped
+    public ResourceHandler getResourceHandler()
+    {
+       return FacesContext.getCurrentInstance().getApplication().getResourceHandler();
+    }
+
+    @Produces
+    @Named("facesContext")
+    @FacesScoped 
+    public FacesContext getFacesContext()
+    {
+       return FacesContext.getCurrentInstance();
+    }
+
+    @Produces
+    @Named("externalContext")
+    @FacesScoped 
+    public ExternalContext getExternalContext()
+    {
+       return FacesContext.getCurrentInstance().getExternalContext();
+    }
+
+    @Produces
+    @Named("flash")
+    @FacesScoped 
+    public Flash getFlash()
+    {
+       return FacesContext.getCurrentInstance().getExternalContext().getFlash();
+    }
+
+    @Produces
+    @Named("header")
+    @HeaderMap
+    @FacesScoped
+    public Map<String, String> getHeaderMap()
+    {
+        return FacesContext.getCurrentInstance().getExternalContext().getRequestHeaderMap();
+    }
+
+    @Produces
+    @Named("headerValues")
+    @HeaderValuesMap
+    @FacesScoped
+    public Map<String, String[]> getHeaderValuesMap()
+    {
+        return FacesContext.getCurrentInstance().getExternalContext().getRequestHeaderValuesMap();
+    }
+
+    @Produces
+    @Named("requestScope")
+    @RequestMap
+    @FacesScoped
+    public Map<String, Object> getRequestMap()
+    {
+        return FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
+    }   
+
+    @Produces
+    @Named("cookie")
+    @RequestCookieMap
+    @FacesScoped
+    public Map<String, Object> getRequestCookieMap()
+    {
+        return FacesContext.getCurrentInstance().getExternalContext().getRequestCookieMap();
+    }
+
+    @Produces
+    @Named("param")
+    @RequestParameterMap
+    @FacesScoped
+    public Map<String, String> getRequestParameterMap()
+    {
+        return FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
+    }
+
+    @Produces
+    @Named("paramValues")
+    @RequestParameterValuesMap
+    @FacesScoped
+    public Map<String, String[]> getRequestParameterValuesMap()
+    {
+        return FacesContext.getCurrentInstance().getExternalContext().getRequestParameterValuesMap();
+    }   
+
+    @Produces
+    @Named("sessionScope")
+    @SessionMap
+    @FacesScoped
+    public Map<String, Object> getSessionMap()
+    {
+        return FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
+    }
+
+    @Produces
+    @Named("view")
+    @FacesScoped
+    public UIViewRoot getViewRoot() 
+    {
+        return FacesContext.getCurrentInstance().getViewRoot();
+    }
+
+    @Produces
+    @Named("session")
+    @FacesScoped
+    public Object getSession()
+    {
+        return FacesContext.getCurrentInstance().getExternalContext().getSession(false);
+    }
+
    
-   @Produces
-   @Named("resource")
-   @ApplicationScoped
-   public ResourceHandler getResourceHandler()
-   {
-      return FacesContext.getCurrentInstance().getApplication().getResourceHandler();
-   }
+    /*
+    The spec actually forces us the use producers for "cc" and "component but it leads to a bad performance.
+    Also @Inject UIComponent doesn't make sense and wouldn't work correctly if we don't create a own "ComponentScoped"
+    or something.
+    We will still use ELResolvers for this - see ImplicitObjectResolver#makeResolverForFacesCDI().
+
+    @Produces
+    @Named("component")
+    @Dependent
+    public UIComponent getComponent() 
+    {
+        return UIComponent.getCurrentComponent(FacesContext.getCurrentInstance());
+    }
+
+    @Produces
+    @Named("cc")
+    @Dependent
+    public UIComponent getCompositeComponent() 
+    {
+        return UIComponent.getCurrentCompositeComponent(FacesContext.getCurrentInstance());
+    }
+    */
+
+    @Produces
+    @Named("viewScope")
+    @ViewMap
+    @ViewTransientScoped
+    public Map<String, Object> getViewMap()
+    {
+        return FacesContext.getCurrentInstance().getViewRoot().getViewMap();
+    }
+
+    @Produces
+    @Named("clientWindow")
+    @FacesScoped 
+    public ClientWindow getClientWindow()
+    {
+       return FacesContext.getCurrentInstance().getExternalContext().getClientWindow();
+    }
+
+    @Produces
+    @FlowBuilderParameter
+    public FlowBuilder getFlowBuilderInstance()
+    {
+        return new FlowBuilderImpl();
+    }
     
-   @Produces
-   @Named("facesContext")
-   @FacesScoped 
-   public FacesContext getFacesContext()
-   {
-      return FacesContext.getCurrentInstance();
-   }
-   
-   @Produces
-   @Named("externalContext")
-   @FacesScoped 
-   public ExternalContext getExternalContext()
-   {
-      return FacesContext.getCurrentInstance().getExternalContext();
-   }
-   
-   @Produces
-   @Named("flash")
-   @FacesScoped 
-   public Flash getFlash()
-   {
-      return FacesContext.getCurrentInstance().getExternalContext().getFlash();
-   }
-   
-   @Produces
-   @Named("header")
-   @HeaderMap
-   @FacesScoped
-   public Map<String, String> getHeaderMap()
-   {
-       return FacesContext.getCurrentInstance().getExternalContext().getRequestHeaderMap();
-   }
-
-   @Produces
-   @Named("headerValues")
-   @HeaderValuesMap
-   @FacesScoped
-   public Map<String, String[]> getHeaderValuesMap()
-   {
-       return FacesContext.getCurrentInstance().getExternalContext().getRequestHeaderValuesMap();
-   }
-
-   @Produces
-   @Named("requestScope")
-   @RequestMap
-   @FacesScoped
-   public Map<String, Object> getRequestMap()
-   {
-       return FacesContext.getCurrentInstance().getExternalContext().getRequestMap();
-   }   
-   
-   @Produces
-   @Named("cookie")
-   @RequestCookieMap
-   @FacesScoped
-   public Map<String, Object> getRequestCookieMap()
-   {
-       return FacesContext.getCurrentInstance().getExternalContext().getRequestCookieMap();
-   }
-   
-   @Produces
-   @Named("param")
-   @RequestParameterMap
-   @FacesScoped
-   public Map<String, String> getRequestParameterMap()
-   {
-       return FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
-   }
-   
-   @Produces
-   @Named("paramValues")
-   @RequestParameterValuesMap
-   @FacesScoped
-   public Map<String, String[]> getRequestParameterValuesMap()
-   {
-       return FacesContext.getCurrentInstance().getExternalContext().getRequestParameterValuesMap();
-   }   
-
-   @Produces
-   @Named("sessionScope")
-   @SessionMap
-   @FacesScoped
-   public Map<String, Object> getSessionMap()
-   {
-       return FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
-   }
-
-   @Produces
-   @Named("view")
-   @FacesScoped
-   public UIViewRoot getViewRoot() 
-   {
-       return FacesContext.getCurrentInstance().getViewRoot();
-   }
-
-   @Produces
-   @Named("session")
-   @FacesScoped
-   public Object getSession()
-   {
-       return FacesContext.getCurrentInstance().getExternalContext().getSession(false);
-   }
-   
-   
-   /*
-   The spec actually forces us the use producers for "cc" and "component but it leads to a bad performance.
-   Also @Inject UIComponent doesn't make sense and wouldn't work correctly if we don't create a own "ComponentScoped"
-   or something.
-   We will still use ELResolvers for this - see ImplicitObjectResolver#makeResolverForFacesCDI().
-   
-   @Produces
-   @Named("component")
-   @Dependent
-   public UIComponent getComponent() 
-   {
-       return UIComponent.getCurrentComponent(FacesContext.getCurrentInstance());
-   }
-   
-   @Produces
-   @Named("cc")
-   @Dependent
-   public UIComponent getCompositeComponent() 
-   {
-       return UIComponent.getCurrentCompositeComponent(FacesContext.getCurrentInstance());
-   }
-   */
-
-   @Produces
-   @Named("viewScope")
-   @ViewMap
-   @ViewTransientScoped
-   public Map<String, Object> getViewMap()
-   {
-       return FacesContext.getCurrentInstance().getViewRoot().getViewMap();
-   }
-
-   @Produces
-   @Named("clientWindow")
-   @FacesScoped 
-   public ClientWindow getClientWindow()
-   {
-      return FacesContext.getCurrentInstance().getExternalContext().getClientWindow();
-   }
+    @Produces
+    @Push
+    public PushContext getPushContext(InjectionPoint ip)
+    {
+        Push push = ip.getAnnotated().getAnnotation(Push.class);
+        String channel = push.channel().isEmpty() ? ip.getMember().getName() : push.channel();
+        return new PushContextImpl(channel);
+    }
 }
diff --git a/impl/src/main/java/org/apache/myfaces/cdi/clientwindow/ClientWindowScopeContext.java b/impl/src/main/java/org/apache/myfaces/cdi/clientwindow/ClientWindowScopeContext.java
index 8bb9d15..8ad992c 100644
--- a/impl/src/main/java/org/apache/myfaces/cdi/clientwindow/ClientWindowScopeContext.java
+++ b/impl/src/main/java/org/apache/myfaces/cdi/clientwindow/ClientWindowScopeContext.java
@@ -30,7 +30,6 @@ import jakarta.faces.context.FacesContext;
 import jakarta.faces.lifecycle.ClientWindowScoped;
 import org.apache.myfaces.cdi.util.ContextualInstanceInfo;
 import org.apache.myfaces.cdi.util.ContextualStorage;
-import org.apache.myfaces.cdi.util.AbstractContextualStorageHolder;
 
 /**
  * Minimal implementation of ClientWindowScope.
@@ -76,7 +75,7 @@ public class ClientWindowScopeContext implements Context
 
         if (facesContext != null)
         {
-            ContextualStorage storage = getContextManager(facesContext).getContextualStorage(
+            ContextualStorage storage = getStorageHolder(facesContext).getContextualStorage(
                     getCurrentClientWindowId(facesContext), false);
             if (storage != null)
             {
@@ -103,7 +102,7 @@ public class ClientWindowScopeContext implements Context
         
         checkActive(facesContext);
 
-        ContextualStorage storage = getContextManager(facesContext).getContextualStorage(
+        ContextualStorage storage = getStorageHolder(facesContext).getContextualStorage(
                 getCurrentClientWindowId(facesContext), true);
 
         Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
@@ -132,9 +131,9 @@ public class ClientWindowScopeContext implements Context
         }
     }
 
-    protected ClientWindowScopeContextualStorageHolder getContextManager(FacesContext context)
+    protected ClientWindowScopeContextualStorageHolder getStorageHolder(FacesContext context)
     {
-        return AbstractContextualStorageHolder.getInstance(context, ClientWindowScopeContextualStorageHolder.class);
+        return ClientWindowScopeContextualStorageHolder.getInstance(context, true);
     }
 
     protected String getCurrentClientWindowId(FacesContext context)
@@ -145,8 +144,8 @@ public class ClientWindowScopeContext implements Context
 
     public static void destroyAll(FacesContext facesContext)
     {
-        ClientWindowScopeContextualStorageHolder manager = AbstractContextualStorageHolder.getInstance(facesContext,
-                ClientWindowScopeContextualStorageHolder.class);
+        ClientWindowScopeContextualStorageHolder manager =
+                ClientWindowScopeContextualStorageHolder.getInstance(facesContext);
         if (manager != null)
         {
             manager.destroyAll(facesContext);
@@ -155,8 +154,8 @@ public class ClientWindowScopeContext implements Context
     
     public static void destroyAll(FacesContext context, String clientWindowId)
     {
-        ClientWindowScopeContextualStorageHolder manager = AbstractContextualStorageHolder.getInstance(context,
-                ClientWindowScopeContextualStorageHolder.class);
+        ClientWindowScopeContextualStorageHolder manager = ClientWindowScopeContextualStorageHolder
+                .getInstance(context);
         if (manager != null)
         {
             manager.destroyAll(context, clientWindowId);
diff --git a/impl/src/main/java/org/apache/myfaces/cdi/clientwindow/ClientWindowScopeContextualStorageHolder.java b/impl/src/main/java/org/apache/myfaces/cdi/clientwindow/ClientWindowScopeContextualStorageHolder.java
index a12a323..ce4b812 100644
--- a/impl/src/main/java/org/apache/myfaces/cdi/clientwindow/ClientWindowScopeContextualStorageHolder.java
+++ b/impl/src/main/java/org/apache/myfaces/cdi/clientwindow/ClientWindowScopeContextualStorageHolder.java
@@ -56,4 +56,14 @@ public class ClientWindowScopeContextualStorageHolder
     {
         return new ContextualStorage(beanManager, true);
     }
+    
+    protected static ClientWindowScopeContextualStorageHolder getInstance(FacesContext facesContext)
+    {
+        return getInstance(facesContext, false);
+    }
+    
+    protected static ClientWindowScopeContextualStorageHolder getInstance(FacesContext facesContext, boolean create)
+    {
+        return getInstance(facesContext, ClientWindowScopeContextualStorageHolder.class, create);
+    }
 }
diff --git a/impl/src/main/java/org/apache/myfaces/cdi/model/FacesDataModelManager.java b/impl/src/main/java/org/apache/myfaces/cdi/model/FacesDataModelManager.java
index d6e88d6..9b9bae3 100644
--- a/impl/src/main/java/org/apache/myfaces/cdi/model/FacesDataModelManager.java
+++ b/impl/src/main/java/org/apache/myfaces/cdi/model/FacesDataModelManager.java
@@ -163,7 +163,7 @@ public class FacesDataModelManager
 
     public static DataModel createDataModel(FacesContext facesContext, Class<?> forClass, Object value)
     {
-        BeanManager beanManager = CDIUtils.getBeanManager(facesContext.getExternalContext());
+        BeanManager beanManager = CDIUtils.getBeanManager(facesContext);
         FacesDataModelManager facesDataModelManager = CDIUtils.get(beanManager, FacesDataModelManager.class);
         return facesDataModelManager.tryToCreateDataModel(facesContext, forClass, value);
     }
diff --git a/impl/src/main/java/org/apache/myfaces/cdi/util/AbstractContextualStorageHolder.java b/impl/src/main/java/org/apache/myfaces/cdi/util/AbstractContextualStorageHolder.java
index 88a6155..172303a 100644
--- a/impl/src/main/java/org/apache/myfaces/cdi/util/AbstractContextualStorageHolder.java
+++ b/impl/src/main/java/org/apache/myfaces/cdi/util/AbstractContextualStorageHolder.java
@@ -202,11 +202,15 @@ public abstract class AbstractContextualStorageHolder<T extends ContextualStorag
 
             for (Map.Entry<Object, ContextualInstanceInfo<?>> entry : contextMap.entrySet())
             {  
-                Contextual bean = contextualStorage.getBean(entry.getKey());
+                boolean skip = isSkipDestroy(entry);
+                if (!skip)
+                {
+                    Contextual bean = contextualStorage.getBean(entry.getKey());
 
-                ContextualInstanceInfo<?> contextualInstanceInfo = entry.getValue();
-                bean.destroy(contextualInstanceInfo.getContextualInstance(), 
-                    contextualInstanceInfo.getCreationalContext());
+                    ContextualInstanceInfo<?> contextualInstanceInfo = entry.getValue();
+                    bean.destroy(contextualInstanceInfo.getContextualInstance(), 
+                        contextualInstanceInfo.getCreationalContext());
+                }
             }
 
             contextMap.clear();
@@ -221,6 +225,11 @@ public abstract class AbstractContextualStorageHolder<T extends ContextualStorag
             }
         }
     }
+    
+    protected boolean isSkipDestroy(Map.Entry<Object, ContextualInstanceInfo<?>> entry)
+    {
+        return false;
+    }
 
     public void destroyAll(FacesContext context, String slotId)
     {
@@ -233,9 +242,15 @@ public abstract class AbstractContextualStorageHolder<T extends ContextualStorag
         destroyAll(contextualStorage, context);
     }
 
-    public static <T extends AbstractContextualStorageHolder> T getInstance(FacesContext facesContext,
+    protected static <T extends AbstractContextualStorageHolder> T getInstance(FacesContext facesContext,
             Class<T> contextManagerClass)
     {
+        return getInstance(facesContext, contextManagerClass, false);
+    }
+    
+    protected static <T extends AbstractContextualStorageHolder> T getInstance(FacesContext facesContext,
+            Class<T> contextManagerClass, boolean create)
+    {
         if (facesContext == null
                 || facesContext.getExternalContext() == null
                 || facesContext.getExternalContext().getSession(false) == null)
@@ -243,7 +258,7 @@ public abstract class AbstractContextualStorageHolder<T extends ContextualStorag
             return null;
         }
 
-        BeanManager beanManager = CDIUtils.getBeanManager(facesContext.getExternalContext());
+        BeanManager beanManager = CDIUtils.getBeanManager(facesContext);
         if (beanManager == null)
         {
             return null;
@@ -257,7 +272,14 @@ public abstract class AbstractContextualStorageHolder<T extends ContextualStorag
         T cached = (T) facesContext.getExternalContext().getSessionMap().get(contextManagerClass.getClass().getName());
         if (cached == null)
         {
-            cached = CDIUtils.getOptional(beanManager, contextManagerClass);
+            if (create)
+            {
+                cached = CDIUtils.get(beanManager, contextManagerClass);
+            }
+            else
+            {
+                cached = CDIUtils.getOptional(beanManager, contextManagerClass);
+            }
             if (cached != null)
             {
                 facesContext.getExternalContext().getSessionMap().put(contextManagerClass.getClass().getName(),
@@ -267,4 +289,5 @@ public abstract class AbstractContextualStorageHolder<T extends ContextualStorag
 
         return cached;
     }
+
 }
diff --git a/impl/src/main/java/org/apache/myfaces/cdi/util/CDIUtils.java b/impl/src/main/java/org/apache/myfaces/cdi/util/CDIUtils.java
index 9c559c8..a3b3e3c 100644
--- a/impl/src/main/java/org/apache/myfaces/cdi/util/CDIUtils.java
+++ b/impl/src/main/java/org/apache/myfaces/cdi/util/CDIUtils.java
@@ -30,6 +30,7 @@ import jakarta.enterprise.context.spi.CreationalContext;
 import jakarta.enterprise.inject.spi.Bean;
 import jakarta.enterprise.inject.spi.BeanManager;
 import jakarta.faces.context.ExternalContext;
+import jakarta.faces.context.FacesContext;
 import jakarta.faces.view.ViewScoped;
 import org.apache.myfaces.webapp.AbstractFacesInitializer;
 
@@ -38,6 +39,11 @@ import org.apache.myfaces.webapp.AbstractFacesInitializer;
  */
 public class CDIUtils
 {
+    public static BeanManager getBeanManager(FacesContext facesContext)
+    {
+        return getBeanManager(facesContext.getExternalContext());
+    }
+
     public static BeanManager getBeanManager(ExternalContext externalContext)
     {
         return (BeanManager) externalContext.getApplicationMap().get(
diff --git a/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeCDIMap.java b/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeCDIMap.java
index e3874f1..50ee7d8 100644
--- a/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeCDIMap.java
+++ b/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeCDIMap.java
@@ -40,7 +40,7 @@ public class ViewScopeCDIMap implements Map<String, Object>
 
     public ViewScopeCDIMap(FacesContext facesContext)
     {
-        BeanManager beanManager = CDIUtils.getBeanManager(facesContext.getExternalContext());
+        BeanManager beanManager = CDIUtils.getBeanManager(facesContext);
         ViewScopeContextualStorageHolder bean = CDIUtils.get(beanManager, ViewScopeContextualStorageHolder.class);
         viewScopeId = bean.generateUniqueViewScopeId();
     }
@@ -59,7 +59,7 @@ public class ViewScopeCDIMap implements Map<String, Object>
         if (storage == null)
         {
             FacesContext facesContext = FacesContext.getCurrentInstance();
-            BeanManager beanManager = CDIUtils.getBeanManager(facesContext.getExternalContext());
+            BeanManager beanManager = CDIUtils.getBeanManager(facesContext);
 
             ViewScopeContextualStorageHolder bean = CDIUtils.get(beanManager, ViewScopeContextualStorageHolder.class);
             
diff --git a/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContext.java b/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContext.java
index e5826eb..c2ddfa0 100644
--- a/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContext.java
+++ b/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContext.java
@@ -32,7 +32,6 @@ import jakarta.faces.context.FacesContext;
 import jakarta.faces.view.ViewScoped;
 
 import org.apache.myfaces.cdi.util.ContextualInstanceInfo;
-import org.apache.myfaces.cdi.util.AbstractContextualStorageHolder;
 import org.apache.myfaces.view.ViewScopeProxyMap;
 
 /**
@@ -57,15 +56,9 @@ public class ViewScopeContext implements Context
         this.passivatingScope = beanManager.isPassivatingScope(getScope());
     }
 
-    protected ViewScopeContextualStorageHolder getContextManager(FacesContext facesContext)
+    protected ViewScopeContextualStorageHolder getStorageHolder(FacesContext facesContext)
     {
-        return AbstractContextualStorageHolder.getInstance(facesContext, ViewScopeContextualStorageHolder.class);
-    }
-
-    protected static ViewScopeContextualStorageHolder getViewScopeBeanHolder(FacesContext facesContext)
-    {
-        return (ViewScopeContextualStorageHolder) facesContext.getExternalContext().getSessionMap()
-                .get(ViewScopeContextualStorageHolder.class.getName());
+        return ViewScopeContextualStorageHolder.getInstance(facesContext, true);
     }
 
     public String getCurrentViewScopeId(boolean create)
@@ -96,7 +89,7 @@ public class ViewScopeContext implements Context
         }
         if (viewScopeId != null)
         {
-            return getContextManager(facesContext).getContextualStorage(viewScopeId, createIfNotExist);
+            return getStorageHolder(facesContext).getContextualStorage(viewScopeId, createIfNotExist);
         }
         return null;
     }
@@ -194,8 +187,7 @@ public class ViewScopeContext implements Context
 
     public static void destroyAll(FacesContext facesContext)
     {
-        ViewScopeContextualStorageHolder manager = AbstractContextualStorageHolder.getInstance(facesContext,
-                ViewScopeContextualStorageHolder.class);
+        ViewScopeContextualStorageHolder manager = ViewScopeContextualStorageHolder.getInstance(facesContext);
         if (manager != null)
         {
             manager.destroyAll(facesContext);
@@ -204,8 +196,7 @@ public class ViewScopeContext implements Context
 
     public static void destroyAll(FacesContext facesContext, String viewScopeId)
     {
-        ViewScopeContextualStorageHolder manager = AbstractContextualStorageHolder.getInstance(facesContext,
-                ViewScopeContextualStorageHolder.class);
+        ViewScopeContextualStorageHolder manager = ViewScopeContextualStorageHolder.getInstance(facesContext);
         if (manager != null)
         {
             manager.destroyAll(facesContext, viewScopeId);
diff --git a/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContextualStorageHolder.java b/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContextualStorageHolder.java
index abe80b9..a50cc63 100644
--- a/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContextualStorageHolder.java
+++ b/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContextualStorageHolder.java
@@ -21,6 +21,7 @@ package org.apache.myfaces.cdi.view;
 import java.io.Serializable;
 import java.util.Random;
 import jakarta.enterprise.context.SessionScoped;
+import jakarta.faces.context.FacesContext;
 import org.apache.myfaces.cdi.util.AbstractContextualStorageHolder;
 
 /**
@@ -56,4 +57,13 @@ public class ViewScopeContextualStorageHolder
         return new ViewScopeContextualStorage(beanManager);
     }
 
+    protected static ViewScopeContextualStorageHolder getInstance(FacesContext facesContext)
+    {
+        return getInstance(facesContext, false);
+    }
+    
+    protected static ViewScopeContextualStorageHolder getInstance(FacesContext facesContext, boolean create)
+    {
+        return getInstance(facesContext, ViewScopeContextualStorageHolder.class, create);
+    }
 }
diff --git a/impl/src/main/java/org/apache/myfaces/cdi/wrapper/FacesBehaviorCDIWrapper.java b/impl/src/main/java/org/apache/myfaces/cdi/wrapper/FacesBehaviorCDIWrapper.java
index 1b944ef..e07f8c7 100644
--- a/impl/src/main/java/org/apache/myfaces/cdi/wrapper/FacesBehaviorCDIWrapper.java
+++ b/impl/src/main/java/org/apache/myfaces/cdi/wrapper/FacesBehaviorCDIWrapper.java
@@ -54,8 +54,7 @@ public class FacesBehaviorCDIWrapper implements PartialStateHolder, Behavior, Fa
     {
         if (delegate == null)
         {
-            delegate = (Behavior) CDIUtils.get(CDIUtils.getBeanManager(
-                FacesContext.getCurrentInstance().getExternalContext()), 
+            delegate = (Behavior) CDIUtils.get(CDIUtils.getBeanManager(FacesContext.getCurrentInstance()),
                     Behavior.class, true, new FacesBehaviorAnnotationLiteral(behaviorId));
         }
         return delegate;
diff --git a/impl/src/main/java/org/apache/myfaces/cdi/wrapper/FacesClientBehaviorCDIWrapper.java b/impl/src/main/java/org/apache/myfaces/cdi/wrapper/FacesClientBehaviorCDIWrapper.java
index 7957199..113145b 100644
--- a/impl/src/main/java/org/apache/myfaces/cdi/wrapper/FacesClientBehaviorCDIWrapper.java
+++ b/impl/src/main/java/org/apache/myfaces/cdi/wrapper/FacesClientBehaviorCDIWrapper.java
@@ -76,8 +76,7 @@ public class FacesClientBehaviorCDIWrapper implements PartialStateHolder, Client
     {
         if (delegate == null)
         {
-            delegate = (ClientBehavior) CDIUtils.get(CDIUtils.getBeanManager(
-                FacesContext.getCurrentInstance().getExternalContext()), 
+            delegate = (ClientBehavior) CDIUtils.get(CDIUtils.getBeanManager(FacesContext.getCurrentInstance()), 
                     ClientBehavior.class, true, new FacesBehaviorAnnotationLiteral(behaviorId));
         }
         return delegate;
diff --git a/impl/src/main/java/org/apache/myfaces/cdi/wrapper/FacesConverterCDIWrapper.java b/impl/src/main/java/org/apache/myfaces/cdi/wrapper/FacesConverterCDIWrapper.java
index 50c8fa5..86294f2 100644
--- a/impl/src/main/java/org/apache/myfaces/cdi/wrapper/FacesConverterCDIWrapper.java
+++ b/impl/src/main/java/org/apache/myfaces/cdi/wrapper/FacesConverterCDIWrapper.java
@@ -73,7 +73,7 @@ public class FacesConverterCDIWrapper implements PartialStateHolder, Converter,
     {
         if (delegate == null)
         {
-            BeanManager bm = CDIUtils.getBeanManager(FacesContext.getCurrentInstance().getExternalContext());
+            BeanManager bm = CDIUtils.getBeanManager(FacesContext.getCurrentInstance());
 
             if (converterId != null)
             {
diff --git a/impl/src/main/java/org/apache/myfaces/cdi/wrapper/FacesValidatorCDIWrapper.java b/impl/src/main/java/org/apache/myfaces/cdi/wrapper/FacesValidatorCDIWrapper.java
index 28114fc..b5c80a7 100644
--- a/impl/src/main/java/org/apache/myfaces/cdi/wrapper/FacesValidatorCDIWrapper.java
+++ b/impl/src/main/java/org/apache/myfaces/cdi/wrapper/FacesValidatorCDIWrapper.java
@@ -63,7 +63,7 @@ public class FacesValidatorCDIWrapper implements PartialStateHolder, Validator,
     {
         if (delegate == null)
         {
-            BeanManager bm = CDIUtils.getBeanManager(FacesContext.getCurrentInstance().getExternalContext());
+            BeanManager bm = CDIUtils.getBeanManager(FacesContext.getCurrentInstance());
             FacesValidatorAnnotationLiteral literal = new FacesValidatorAnnotationLiteral(validatorId);
             delegate = (Validator) CDIUtils.get(bm, VALIDATOR_TYPE, true, literal);
             
diff --git a/impl/src/main/java/org/apache/myfaces/el/DefaultELResolverBuilder.java b/impl/src/main/java/org/apache/myfaces/el/DefaultELResolverBuilder.java
index 12cd9d8..5617937 100644
--- a/impl/src/main/java/org/apache/myfaces/el/DefaultELResolverBuilder.java
+++ b/impl/src/main/java/org/apache/myfaces/el/DefaultELResolverBuilder.java
@@ -182,8 +182,7 @@ public class DefaultELResolverBuilder extends ELResolverBuilder
     
     protected ELResolver getCDIELResolver()
     {
-        BeanManager beanManager = CDIUtils.getBeanManager(
-                FacesContext.getCurrentInstance().getExternalContext());
+        BeanManager beanManager = CDIUtils.getBeanManager(FacesContext.getCurrentInstance());
         return beanManager.getELResolver();
     }
 }
diff --git a/impl/src/main/java/org/apache/myfaces/el/ELResolverBuilder.java b/impl/src/main/java/org/apache/myfaces/el/ELResolverBuilder.java
index e4c4bad..368e2c0 100644
--- a/impl/src/main/java/org/apache/myfaces/el/ELResolverBuilder.java
+++ b/impl/src/main/java/org/apache/myfaces/el/ELResolverBuilder.java
@@ -142,7 +142,7 @@ public class ELResolverBuilder
             return false;
         }
 
-        BeanManager beanManager = CDIUtils.getBeanManager(facesContext.getExternalContext());
+        BeanManager beanManager = CDIUtils.getBeanManager(facesContext);
         if (beanManager != null)
         {
             FacesConfigBeanHolder holder = CDIUtils.get(beanManager, FacesConfigBeanHolder.class);
diff --git a/impl/src/main/java/org/apache/myfaces/flow/cdi/DefaultCDIFacesFlowProvider.java b/impl/src/main/java/org/apache/myfaces/flow/cdi/DefaultCDIFacesFlowProvider.java
index 0a1748f..598333a 100644
--- a/impl/src/main/java/org/apache/myfaces/flow/cdi/DefaultCDIFacesFlowProvider.java
+++ b/impl/src/main/java/org/apache/myfaces/flow/cdi/DefaultCDIFacesFlowProvider.java
@@ -44,43 +44,9 @@ public class DefaultCDIFacesFlowProvider extends FacesFlowProvider
 {
     private final static String CURRENT_FLOW_SCOPE_MAP = "oam.flow.SCOPE_MAP";
     private final static char SEPARATOR_CHAR = '.';
-    
-    private BeanManager _beanManager;
-    private boolean _initialized;
+
     private List<Flow> flows;
-    
-    private boolean isFlowScopeBeanHolderCreated(FacesContext facesContext)
-    {
-        if (facesContext.getExternalContext().getSession(false) == null)
-        {
-            return false;
-        }
-        
-        return facesContext.getExternalContext().getSessionMap()
-                .containsKey(FlowScopeBeanHolder.CREATED);
-    }
-    
-    @Override
-    public void onSessionDestroyed()
-    {
-        // In CDI case, the best way to deal with this is use a method 
-        // with @PreDestroy annotation on a session scope bean 
-        // ( ViewScopeBeanHolder.destroyBeans() ). There is no need
-        // to do anything else in this location, but it is advised
-        // in CDI the beans are destroyed at the end of the request,
-        // not when invalidateSession() is called.
-        FacesContext facesContext = FacesContext.getCurrentInstance();
-        if (facesContext != null && isFlowScopeBeanHolderCreated(facesContext))
-        {
-            FlowScopeBeanHolder flowScopeBeanHolder = CDIUtils.get(
-                _beanManager, FlowScopeBeanHolder.class, false);
-            if (flowScopeBeanHolder != null)
-            {
-                flowScopeBeanHolder.destroyBeans();
-            }
-        }
-    }
-    
+
     @Override
     public Iterator<Flow> getAnnotatedFlows(FacesContext facesContext)
     {
@@ -88,7 +54,7 @@ public class DefaultCDIFacesFlowProvider extends FacesFlowProvider
         {
             flows = new ArrayList<>();
 
-            BeanManager beanManager = getBeanManager(facesContext);
+            BeanManager beanManager = CDIUtils.getBeanManager(facesContext);
             if (beanManager == null)
             {
                 Logger.getLogger(DefaultCDIFacesFlowProvider.class.getName()).log(Level.INFO,
@@ -111,12 +77,8 @@ public class DefaultCDIFacesFlowProvider extends FacesFlowProvider
     @Override
     public void doAfterEnterFlow(FacesContext context, Flow flow)
     {
-        BeanManager beanManager = getBeanManager(context);
-        if (beanManager != null)
-        {
-            FlowScopeBeanHolder beanHolder = CDIUtils.get(beanManager, FlowScopeBeanHolder.class);
-            beanHolder.createCurrentFlowScope(context);
-        }
+        FlowScopeContextualStorageHolder storageHolder = FlowScopeContextualStorageHolder.getInstance(context, true);
+        storageHolder.createCurrentFlowScope(context);
 
         String mapKey = getFlowKey(flow);
         context.getAttributes().remove(mapKey);
@@ -125,12 +87,8 @@ public class DefaultCDIFacesFlowProvider extends FacesFlowProvider
     @Override
     public void doBeforeExitFlow(FacesContext context, Flow flow)
     {
-        BeanManager beanManager = getBeanManager(context);
-        if (beanManager != null)
-        {
-            FlowScopeBeanHolder beanHolder = CDIUtils.get(beanManager, FlowScopeBeanHolder.class);
-            beanHolder.destroyCurrentFlowScope(context);
-        }
+        FlowScopeContextualStorageHolder storageHolder = FlowScopeContextualStorageHolder.getInstance(context, true);
+        storageHolder.destroyCurrentFlowScope(context);
 
         String mapKey = getFlowKey(flow);
         context.getAttributes().remove(mapKey);
@@ -144,7 +102,9 @@ public class DefaultCDIFacesFlowProvider extends FacesFlowProvider
         {
             String mapKey = getFlowKey(flow);
             return (Map<Object, Object>) facesContext.getAttributes().computeIfAbsent(mapKey,
-                    k -> new FlowScopeMap(getBeanManager(facesContext), FlowUtils.getFlowMapKey(facesContext, flow)));
+                    k -> new FlowScopeMap(
+                            CDIUtils.getBeanManager(facesContext),
+                            FlowUtils.getFlowMapKey(facesContext, flow)));
         }
 
         return null;
@@ -158,27 +118,12 @@ public class DefaultCDIFacesFlowProvider extends FacesFlowProvider
             Flow flow = facesContext.getApplication().getFlowHandler().getCurrentFlow(facesContext);
             if (flow != null)
             {
-                BeanManager beanManager = getBeanManager(facesContext);
-                if (beanManager != null)
-                {
-                    FlowScopeBeanHolder beanHolder = CDIUtils.get(beanManager, FlowScopeBeanHolder.class);
-
-                    //Refresh client window for flow scope
-                    beanHolder.refreshClientWindow(facesContext);
-                }
+                FlowScopeContextualStorageHolder storageHolder = FlowScopeContextualStorageHolder
+                        .getInstance(facesContext, true);
+                storageHolder.refreshClientWindow(facesContext);
             }
         }
     }
-    
-    public BeanManager getBeanManager(FacesContext facesContext)
-    {
-        if (_beanManager == null && !_initialized)
-        {
-            _beanManager = CDIUtils.getBeanManager(facesContext.getExternalContext());
-            _initialized = true;
-        }
-        return _beanManager;
-    }
 
     protected String getFlowKey(Flow flow)
     {
diff --git a/impl/src/main/java/org/apache/myfaces/flow/cdi/FacesFlowClientWindowCollection.java b/impl/src/main/java/org/apache/myfaces/flow/cdi/FacesFlowClientWindowCollection.java
deleted file mode 100644
index 6b495aa..0000000
--- a/impl/src/main/java/org/apache/myfaces/flow/cdi/FacesFlowClientWindowCollection.java
+++ /dev/null
@@ -1,70 +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.flow.cdi;
-
-import java.io.Serializable;
-import org.apache.myfaces.util.lang.LRULinkedHashMap;
-
-/**
- * This class is a wrapper used to deal with concurrency issues when accessing the inner LRUMap.
- */
-class FacesFlowClientWindowCollection implements Serializable
-{
-    private static final long serialVersionUID = 1L;
-
-    private LRULinkedHashMap<String, String> map;
-    private FlowScopeBeanHolder holder;
-
-    public FacesFlowClientWindowCollection()
-    {
-    }
-    
-    public FacesFlowClientWindowCollection(int capacity)
-    {
-        this.map = new LRULinkedHashMap<>(capacity, (eldest) ->
-        {
-            holder.clearFlowMap(eldest.getKey());
-        });
-    }
-
-    public synchronized void put(String key, String value)
-    {
-        map.put(key, value);
-    }
-    
-    public synchronized String get(String key)
-    {
-        return map.get(key);
-    }
-    
-    public synchronized void remove(String key)
-    {
-        map.remove(key);
-    }
-    
-    public synchronized boolean isEmpty()
-    {
-        return map.isEmpty();
-    }
-    
-    public void setFlowScopeBeanHolder(FlowScopeBeanHolder holder)
-    {
-        this.holder = holder;
-    }
-}
diff --git a/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowBuilderExtension.java b/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowBuilderExtension.java
deleted file mode 100644
index 2527c36..0000000
--- a/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowBuilderExtension.java
+++ /dev/null
@@ -1,47 +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.flow.cdi;
-
-import jakarta.enterprise.event.Observes;
-import jakarta.enterprise.inject.spi.AnnotatedType;
-import jakarta.enterprise.inject.spi.BeanManager;
-import jakarta.enterprise.inject.spi.BeforeBeanDiscovery;
-import jakarta.enterprise.inject.spi.Extension;
-
-/**
- * This extension is responsible of scan flow definitions through CDI. For example:
- *
- * <code>
- * &#64;Produces &#64;FlowDefinition
- * public Flow defineFlow(&#64;FlowBuilderParameter FlowBuilder flowBuilder) {...}
- * </code>
- *
- * @author Leonardo Uribe
- */
-public class FlowBuilderExtension implements Extension
-{
-    void beforeBeanDiscovery(@Observes final BeforeBeanDiscovery event, BeanManager beanManager)
-    {
-        // Register FlowBuilderFactoryBean as a bean with CDI annotations, so the system
-        // can take it into account, and use it later when necessary.
-        AnnotatedType<FlowBuilderFactoryBean> flowDiscoveryHelper =
-                        beanManager.createAnnotatedType(FlowBuilderFactoryBean.class);
-        event.addAnnotatedType(flowDiscoveryHelper, flowDiscoveryHelper.getJavaClass().getName());
-    }
-}
diff --git a/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowBuilderFactoryBean.java b/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowBuilderFactoryBean.java
deleted file mode 100644
index cf29891..0000000
--- a/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowBuilderFactoryBean.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.flow.cdi;
-
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.enterprise.inject.Produces;
-import jakarta.faces.flow.builder.FlowBuilder;
-import jakarta.faces.flow.builder.FlowBuilderParameter;
-
-import org.apache.myfaces.flow.builder.FlowBuilderImpl;
-
-/**
- * This bean is used later by CDI to process flow definitions
- *
- * @author Leonardo Uribe
- */
-@ApplicationScoped
-public class FlowBuilderFactoryBean
-{
-    public FlowBuilderFactoryBean()
-    {
-    }
-
-    @Produces
-    @FlowBuilderParameter
-    public FlowBuilder createFlowBuilderInstance()
-    {
-        return new FlowBuilderImpl();
-    }
-}
diff --git a/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeBeanHolder.java b/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeBeanHolder.java
deleted file mode 100644
index d2f62b4..0000000
--- a/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeBeanHolder.java
+++ /dev/null
@@ -1,334 +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.flow.cdi;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import jakarta.annotation.PostConstruct;
-import jakarta.annotation.PreDestroy;
-import jakarta.enterprise.context.SessionScoped;
-import jakarta.enterprise.inject.spi.BeanManager;
-import jakarta.faces.context.ExceptionHandler;
-import jakarta.faces.context.ExternalContext;
-import jakarta.faces.context.FacesContext;
-import jakarta.faces.flow.Flow;
-import jakarta.faces.flow.FlowHandler;
-import jakarta.faces.lifecycle.ClientWindow;
-import jakarta.inject.Inject;
-import jakarta.servlet.ServletContext;
-import org.apache.myfaces.cdi.util.ContextualInstanceInfo;
-import org.apache.myfaces.cdi.util.ContextualStorage;
-import org.apache.myfaces.cdi.JsfApplicationArtifactHolder;
-import org.apache.myfaces.cdi.util.CDIUtils;
-import org.apache.myfaces.context.servlet.StartupFacesContextImpl;
-import org.apache.myfaces.context.servlet.StartupServletExternalContextImpl;
-import org.apache.myfaces.flow.FlowUtils;
-import org.apache.myfaces.config.MyfacesConfig;
-import org.apache.myfaces.context.ExceptionHandlerImpl;
-
-
-/**
- *
- * This holder will store the flow scope active ids and it's beans for the current
- * HTTP Session. We use standard SessionScoped bean to not need
- * to treat async-supported and similar headache.
- * 
- * @author lu4242
- */
-@SessionScoped
-public class FlowScopeBeanHolder implements Serializable
-{
-    /**
-     * key: client window id + flow id
-     * value: the {@link ContextualStorage} which holds all the
-     * {@link jakarta.enterprise.inject.spi.Bean}s.
-     */
-    private Map<String, ContextualStorage> storageMap;
-    
-    private Map<String, List<String>> activeFlowMapKeys;
-    
-    private FacesFlowClientWindowCollection windowCollection;
-    
-    public static final String CURRENT_FLOW_SCOPE_MAP = "oam.CURRENT_FLOW_SCOPE_MAP";
-
-    public static final String CREATED = FlowScopeBeanHolder.class.getName() + ".CREATED";
-    
-    @Inject
-    JsfApplicationArtifactHolder applicationContextBean;
-
-    public FlowScopeBeanHolder()
-    {
-    }
-    
-    @PostConstruct
-    public void init()
-    {
-        storageMap = new ConcurrentHashMap<>();
-        activeFlowMapKeys = new ConcurrentHashMap<>();
-        windowCollection = null;
-        
-        FacesContext facesContext = FacesContext.getCurrentInstance();
-        this.refreshClientWindow(facesContext);
-        facesContext.getExternalContext().getSessionMap().put(CREATED, true);
-        
-        Object context = facesContext.getExternalContext().getContext();
-        if (context instanceof ServletContext)
-        {
-            BeanManager beanManager = CDIUtils.getBeanManager(facesContext.getExternalContext());
-            JsfApplicationArtifactHolder appBean = CDIUtils.get(beanManager, JsfApplicationArtifactHolder.class);
-            if (appBean.getServletContext() != null)
-            {
-                appBean.setServletContext((ServletContext) context);
-            }
-        }
-    }
-
-    /**
-     * This method will return the ContextualStorage or create a new one
-     * if no one is yet assigned to the current flowClientWindowId.
-     * 
-     * @param beanManager we need the CDI {@link BeanManager} for serialisation.
-     * @param flowClientWindowId the flowClientWindowId for the current flow.
-     * @param create create if not existent
-     *
-     * @return the ContextualStorage or null
-     */
-    public ContextualStorage getContextualStorage(BeanManager beanManager, String flowClientWindowId, boolean create)
-    {
-        ContextualStorage storage = storageMap.get(flowClientWindowId);
-        if (storage == null && create)
-        {
-            storage = new ContextualStorage(beanManager, true);
-            storageMap.put(flowClientWindowId, storage);
-        }
-        return storage;
-    }
-
-    public Map<String, ContextualStorage> getStorageMap()
-    {
-        return storageMap;
-    }
-    
-    public Map<Object, Object> getFlowScopeMap(BeanManager beanManager, String flowClientWindowId, boolean create)
-    {
-        ContextualStorage contextualStorage = getContextualStorage(beanManager, flowClientWindowId, create);
-        if (contextualStorage == null)
-        {
-            return null;
-        }
-
-        ContextualInstanceInfo info = contextualStorage.getStorage().get(CURRENT_FLOW_SCOPE_MAP);
-        if (info == null && create)
-        {
-            info = new ContextualInstanceInfo<>();
-            contextualStorage.getStorage().put(CURRENT_FLOW_SCOPE_MAP, info);
-        }
-        if (info == null)
-        {
-            return null;
-        }
-
-        Map<Object, Object> map = (Map<Object, Object>) info.getContextualInstance();
-        if (map == null && create)
-        {
-            map = new HashMap<>();
-            info.setContextualInstance(map);
-        }
-        return map;
-    }
-
-    /**
-     *
-     * This method will replace the storageMap and with
-     * a new empty one.
-     * This method can be used to properly destroy the BeanHolder beans
-     * without having to sync heavily. Any
-     * {@link jakarta.enterprise.inject.spi.Bean#destroy(Object, jakarta.enterprise.context.spi.CreationalContext)}
-     * should be performed on the returned old storage map.
-     * @return the old storageMap.
-     */
-    public Map<String, ContextualStorage> forceNewStorage()
-    {
-        Map<String, ContextualStorage> oldStorageMap = storageMap;
-        storageMap = new ConcurrentHashMap<>();
-        return oldStorageMap;
-    }
-
-    /**
-     * This method properly destroys all current &#064;WindowScoped beans
-     * of the active session and also prepares the storage for new beans.
-     * It will automatically get called when the session context closes
-     * but can also get invoked manually, e.g. if a user likes to get rid
-     * of all it's &#064;WindowScoped beans.
-     */
-    //@PreDestroy
-    public void destroyBeans()
-    {
-        // we replace the old BeanHolder beans with a new storage Map
-        // an afterwards destroy the old Beans without having to care about any syncs.
-        Map<String, ContextualStorage> oldContextStorages = forceNewStorage();
-
-        for (ContextualStorage contextualStorage : oldContextStorages.values())
-        {
-            FlowScopeContext.destroyAllActive(contextualStorage);
-        }
-    }
-    
-    /**
-     * See description on ViewScopeBeanHolder for details about how this works
-     */
-    @PreDestroy
-    public void destroyBeansOnPreDestroy()
-    {
-        Map<String, ContextualStorage> oldContextStorages = forceNewStorage();
-        if (!oldContextStorages.isEmpty())
-        {
-            FacesContext facesContext = FacesContext.getCurrentInstance();
-            ServletContext servletContext = null;
-            if (facesContext == null)
-            {
-                try
-                {
-                    servletContext = applicationContextBean.getServletContext();
-                }
-                catch (Throwable e)
-                {
-                    Logger.getLogger(FlowScopeBeanHolder.class.getName()).log(Level.WARNING,
-                        "Cannot locate servletContext to create FacesContext on @PreDestroy flow scope beans. "
-                                + "The beans will be destroyed without active FacesContext instance.");
-                    servletContext = null;
-                }
-            }
-            if (facesContext == null && servletContext != null)
-            {
-                try
-                {
-                    ExternalContext externalContext = new StartupServletExternalContextImpl(servletContext, false);
-                    ExceptionHandler exceptionHandler = new ExceptionHandlerImpl();
-                    facesContext = new StartupFacesContextImpl(externalContext, externalContext, exceptionHandler,
-                            false);
-                    for (ContextualStorage contextualStorage : oldContextStorages.values())
-                    {
-                        FlowScopeContext.destroyAllActive(contextualStorage);
-                    }
-                }
-                finally
-                {
-                    facesContext.release();
-                }
-            }
-            else
-            {
-                for (ContextualStorage contextualStorage : oldContextStorages.values())
-                {
-                    FlowScopeContext.destroyAllActive(contextualStorage);
-                }
-            }
-        }
-    }
-    
-    public void refreshClientWindow(FacesContext facesContext)
-    {
-        if (windowCollection == null)
-        {
-            Integer numberOfFacesFlowClientWindowIdsInSession =
-                    MyfacesConfig.getCurrentInstance(facesContext).getNumberOfFacesFlowClientWindowIdsInSession();
-            windowCollection = new FacesFlowClientWindowCollection(numberOfFacesFlowClientWindowIdsInSession);
-        }
-        ClientWindow cw = facesContext.getExternalContext().getClientWindow();
-        if (cw != null && cw.getId() != null)
-        {
-            windowCollection.setFlowScopeBeanHolder(this);
-            windowCollection.put(cw.getId(), "");
-        }
-    }
-    
-    public void clearFlowMap(String clientWindowId)
-    {
-        List<String> activeFlowKeys = activeFlowMapKeys.remove(clientWindowId);
-        if (activeFlowKeys != null && !activeFlowKeys.isEmpty())
-        {
-            for (String flowMapKey : activeFlowKeys)
-            {
-                ContextualStorage contextualStorage = storageMap.remove(flowMapKey);
-                if (contextualStorage != null)
-                {
-                    FlowScopeContext.destroyAllActive(contextualStorage);
-                }
-            }
-        }
-    }
-    
-    public List<String> getActiveFlowMapKeys(FacesContext facesContext)
-    {
-        ClientWindow cw = facesContext.getExternalContext().getClientWindow();
-        String baseKey = cw.getId();
-        List<String> activeFlowKeys = activeFlowMapKeys.get(baseKey);
-        if (activeFlowKeys == null)
-        {
-            return Collections.emptyList();
-        }
-
-        return activeFlowKeys;
-    }
-    
-    public void createCurrentFlowScope(FacesContext facesContext)
-    {
-        ClientWindow cw = facesContext.getExternalContext().getClientWindow();
-        String baseKey = cw.getId();
-        
-        FlowHandler flowHandler = facesContext.getApplication().getFlowHandler();
-        Flow flow = flowHandler.getCurrentFlow(facesContext);
-        String flowMapKey = FlowUtils.getFlowMapKey(facesContext, flow);
-
-        List<String> activeFlowKeys = activeFlowMapKeys.computeIfAbsent(baseKey, k -> new ArrayList<>());
-        activeFlowKeys.add(0, flowMapKey);
-        activeFlowMapKeys.put(baseKey, activeFlowKeys);
-        refreshClientWindow(facesContext);
-    }
-    
-    public void destroyCurrentFlowScope(FacesContext facesContext)
-    {
-        ClientWindow cw = facesContext.getExternalContext().getClientWindow();
-        String baseKey = cw.getId();
-        
-        FlowHandler flowHandler = facesContext.getApplication().getFlowHandler();
-        Flow flow = flowHandler.getCurrentFlow(facesContext);
-        String flowMapKey = FlowUtils.getFlowMapKey(facesContext, flow);
-
-        ContextualStorage contextualStorage = storageMap.remove(flowMapKey);
-        if (contextualStorage != null)
-        {
-            FlowScopeContext.destroyAllActive(contextualStorage);
-        }
-        
-        List<String> activeFlowKeys = activeFlowMapKeys.get(baseKey);
-        if (activeFlowKeys != null && !activeFlowKeys.isEmpty())
-        {
-            activeFlowKeys.remove(flowMapKey);
-        }
-    }
-}
diff --git a/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeContext.java b/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeContext.java
index be5f533..7c40bad 100644
--- a/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeContext.java
+++ b/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeContext.java
@@ -33,7 +33,6 @@ import jakarta.faces.context.FacesContext;
 import jakarta.faces.flow.Flow;
 import jakarta.faces.flow.FlowHandler;
 import jakarta.faces.flow.FlowScoped;
-import org.apache.myfaces.cdi.util.CDIUtils;
 import org.apache.myfaces.cdi.util.ContextualInstanceInfo;
 import org.apache.myfaces.cdi.util.ContextualStorage;
 import org.apache.myfaces.flow.FlowReference;
@@ -67,24 +66,9 @@ public class FlowScopeContext implements Context
         this.passivatingScope = beanManager.isPassivatingScope(getScope());
     }
 
-    protected FlowScopeBeanHolder getFlowScopeBeanHolder()
+    protected FlowScopeContextualStorageHolder getStorageHolder(FacesContext facesContext)
     {
-        return getFlowScopeBeanHolder(FacesContext.getCurrentInstance());
-    }
-    
-    protected FlowScopeBeanHolder getFlowScopeBeanHolder(FacesContext facesContext)
-    {
-        FlowScopeBeanHolder beanHolder = (FlowScopeBeanHolder) facesContext.getExternalContext().getApplicationMap()
-                .get(FlowScopeBeanHolder.class.getName());
-        if (beanHolder == null)
-        {
-            beanHolder = CDIUtils.get(beanManager, FlowScopeBeanHolder.class);
-            facesContext.getExternalContext().getApplicationMap().put(
-                    FlowScopeBeanHolder.class.getName(),
-                    beanHolder);
-        }
-
-        return beanHolder;
+        return FlowScopeContextualStorageHolder.getInstance(facesContext, true);
     }
     
     public String getCurrentClientWindowFlowId(FacesContext facesContext)
@@ -99,22 +83,6 @@ public class FlowScopeContext implements Context
         return flowMapKey;
     }
 
-    /**
-     * An implementation has to return the underlying storage which
-     * contains the items held in the Context.
-     * @param createIfNotExist whether a ContextualStorage shall get created if it doesn't yet exist.
-     * @return the underlying storage
-     */
-    protected ContextualStorage getContextualStorage(boolean createIfNotExist, String clientWindowFlowId)
-    {
-        if (clientWindowFlowId == null)
-        {
-            throw new ContextNotActiveException(this.getClass().getName() + ": no current active flow");
-        }
-
-        return getFlowScopeBeanHolder().getContextualStorage(beanManager, clientWindowFlowId, createIfNotExist);
-    }
-
     @Override
     public Class<? extends Annotation> getScope()
     {
@@ -138,9 +106,15 @@ public class FlowScopeContext implements Context
         return flow != null;
     }
 
-    /**
-     * @return whether the served scope is a passivating scope
-     */
+    protected void checkActive(FacesContext facesContext)
+    {
+        if (!isActive(facesContext))
+        {
+            throw new ContextNotActiveException("CDI context with scope annotation @"
+                + getScope().getName() + " is not active with respect to the current thread");
+        }
+    }
+
     public boolean isPassivatingScope()
     {
         return passivatingScope;
@@ -159,7 +133,7 @@ public class FlowScopeContext implements Context
             String flowMapKey = FlowUtils.getFlowMapKey(facesContext, reference);
             if (flowMapKey != null)
             {
-                ContextualStorage storage = getContextualStorage(false, flowMapKey);
+                ContextualStorage storage = getContextualStorage(facesContext, false, flowMapKey);
                 if (storage != null)
                 {
                     Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
@@ -178,13 +152,12 @@ public class FlowScopeContext implements Context
             }
         }
         
-        List<String> activeFlowMapKeys = getFlowScopeBeanHolder().getActiveFlowMapKeys(facesContext);
+        List<String> activeFlowMapKeys = getStorageHolder(facesContext).getActiveFlowMapKeys(facesContext);
         for (String flowMapKey : activeFlowMapKeys)
         {
-            ContextualStorage storage = getContextualStorage(false, flowMapKey);
+            ContextualStorage storage = getContextualStorage(facesContext, false, flowMapKey);
             if (storage == null)
             {
-                //return null;
                 continue;
             }
 
@@ -213,30 +186,28 @@ public class FlowScopeContext implements Context
                     " doesn't implement " + PassivationCapable.class.getName());
         }
         
-        FlowReference reference = flowBeanReferences.get(((Bean)bean).getBeanClass());
+        FlowReference reference = flowBeanReferences.get(((Bean) bean).getBeanClass());
         if (reference != null)
         {
             String flowMapKey = FlowUtils.getFlowMapKey(facesContext, reference);
-            if (flowMapKey != null)
-            {
-                ContextualStorage storage = getContextualStorage(false, flowMapKey);
-                if (storage != null)
-                {
-                    Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
-                    ContextualInstanceInfo<?> contextualInstanceInfo = contextMap.get(storage.getBeanKey(bean));
-
-                    if (contextualInstanceInfo != null)
-                    {
-                        return (T) contextualInstanceInfo.getContextualInstance();
-                    }
-                }
-            }
-            else
+            if (flowMapKey == null)
             {
                 throw new IllegalStateException("Flow " + reference.getId()+
                     " cannot be found when resolving bean " + bean.toString());
             }
-            
+
+            ContextualStorage storage = getContextualStorage(facesContext, false, flowMapKey);
+            if (storage != null)
+            {
+                Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
+                ContextualInstanceInfo<?> contextualInstanceInfo = contextMap.get(storage.getBeanKey(bean));
+
+                if (contextualInstanceInfo != null)
+                {
+                    return (T) contextualInstanceInfo.getContextualInstance();
+                }
+            }
+
             FlowHandler flowHandler = facesContext.getApplication().getFlowHandler();
             // Since it is possible to have only the flow id without documentId, the best
             // is first get the flow using flowHandler.getFlow and then check if the flow is
@@ -253,11 +224,10 @@ public class FlowScopeContext implements Context
                 throw new IllegalStateException(bean.toString() + "cannot be created if flow "
                         + reference.getId() + " is not active");
             }
-            
-            ContextualStorage storage = getContextualStorage(true, flowMapKey);
+
+            storage = getContextualStorage(facesContext, true, flowMapKey); // now create it
             Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
             ContextualInstanceInfo<?> contextualInstanceInfo = contextMap.get(storage.getBeanKey(bean));
-
             if (contextualInstanceInfo != null)
             {
                 @SuppressWarnings("unchecked")
@@ -271,14 +241,13 @@ public class FlowScopeContext implements Context
             return storage.createContextualInstance(bean, creationalContext);
         }
 
-        List<String> activeFlowMapKeys = getFlowScopeBeanHolder().getActiveFlowMapKeys(facesContext);
+        List<String> activeFlowMapKeys = getStorageHolder(facesContext).getActiveFlowMapKeys(facesContext);
         for (String flowMapKey : activeFlowMapKeys)
         {
-            ContextualStorage storage = getContextualStorage(false, flowMapKey);
+            ContextualStorage storage = getContextualStorage(facesContext, false, flowMapKey);
 
             Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
             ContextualInstanceInfo<?> contextualInstanceInfo = contextMap.get(storage.getBeanKey(bean));
-
             if (contextualInstanceInfo != null)
             {
                 @SuppressWarnings("unchecked")
@@ -288,13 +257,12 @@ public class FlowScopeContext implements Context
                     return instance;
                 }
             }
-
         }
         
-        ContextualStorage storage = getContextualStorage(true, getCurrentClientWindowFlowId(facesContext));
+        ContextualStorage storage = getContextualStorage(facesContext, true,
+                getCurrentClientWindowFlowId(facesContext));
         Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
         ContextualInstanceInfo<?> contextualInstanceInfo = contextMap.get(storage.getBeanKey(bean));
-
         if (contextualInstanceInfo != null)
         {
             @SuppressWarnings("unchecked")
@@ -304,72 +272,27 @@ public class FlowScopeContext implements Context
                 return instance;
             }
         }
-            
+
         return storage.createContextualInstance(bean, creationalContext);
     }
 
-    /**
-     * Destroy the Contextual Instance of the given Bean.
-     * @param bean dictates which bean shall get cleaned up
-     * @return <code>true</code> if the bean was destroyed, <code>false</code> if there was no such bean.
-     */
-    public boolean destroy(Contextual bean)
+    protected ContextualStorage getContextualStorage(FacesContext context, boolean createIfNotExist,
+            String clientWindowFlowId)
     {
-        FacesContext facesContext = FacesContext.getCurrentInstance();
-        List<String> activeFlowMapKeys = getFlowScopeBeanHolder().getActiveFlowMapKeys(facesContext);
-        for (String flowMapKey : activeFlowMapKeys)
+        if (clientWindowFlowId == null)
         {
-            ContextualStorage storage = getContextualStorage(false, flowMapKey);
-            if (storage == null)
-            {
-                continue;
-            }
-            ContextualInstanceInfo<?> contextualInstanceInfo = storage.getStorage().get(storage.getBeanKey(bean));
-
-            if (contextualInstanceInfo == null)
-            {
-                continue;
-            }
-
-            bean.destroy(contextualInstanceInfo.getContextualInstance(), contextualInstanceInfo.getCreationalContext());
-            return true;
+            throw new ContextNotActiveException(this.getClass().getName() + ": no current active flow");
         }
-        return false;
-    }
-
-    /**
-     * Destroys all the Contextual Instances in the specified ContextualStorage.
-     * This is a static method to allow various holder objects to cleanup
-     * properly in &#064;PreDestroy.
-     */
-    public static void destroyAllActive(ContextualStorage storage)
-    {
-        Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
-        for (Map.Entry<Object, ContextualInstanceInfo<?>> entry : contextMap.entrySet())
-        {
-            if (!FlowScopeBeanHolder.CURRENT_FLOW_SCOPE_MAP.equals(entry.getKey()))
-            {
-                Contextual bean = storage.getBean(entry.getKey());
 
-                ContextualInstanceInfo<?> contextualInstanceInfo = entry.getValue();
-                bean.destroy(contextualInstanceInfo.getContextualInstance(), 
-                    contextualInstanceInfo.getCreationalContext());
-            }
-        }
+        return getStorageHolder(context).getContextualStorage(clientWindowFlowId, createIfNotExist);
     }
 
-    /**
-     * Make sure that the Context is really active.
-     * @throws ContextNotActiveException if there is no active
-     *         Context for the current Thread.
-     */
-    protected void checkActive(FacesContext facesContext)
+    public static void destroyAll(FacesContext facesContext)
     {
-        if (!isActive(facesContext))
+        FlowScopeContextualStorageHolder manager = FlowScopeContextualStorageHolder.getInstance(facesContext);
+        if (manager != null)
         {
-            throw new ContextNotActiveException("CDI context with scope annotation @"
-                + getScope().getName() + " is not active with respect to the current thread");
+            manager.destroyAll(facesContext);
         }
     }
-
 }
diff --git a/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeContextualStorageHolder.java b/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeContextualStorageHolder.java
new file mode 100644
index 0000000..d2aae03
--- /dev/null
+++ b/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeContextualStorageHolder.java
@@ -0,0 +1,215 @@
+/*
+ * 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.flow.cdi;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import jakarta.annotation.PostConstruct;
+import jakarta.enterprise.context.SessionScoped;
+import jakarta.enterprise.inject.spi.BeanManager;
+import jakarta.faces.context.FacesContext;
+import jakarta.faces.flow.Flow;
+import jakarta.faces.flow.FlowHandler;
+import jakarta.faces.lifecycle.ClientWindow;
+import org.apache.myfaces.cdi.util.ContextualInstanceInfo;
+import org.apache.myfaces.cdi.util.ContextualStorage;
+import org.apache.myfaces.cdi.util.AbstractContextualStorageHolder;
+import org.apache.myfaces.flow.FlowUtils;
+import org.apache.myfaces.config.MyfacesConfig;
+import org.apache.myfaces.util.lang.LRULinkedHashMap;
+
+/**
+ * This holder will store the flow scope active ids and it's beans for the current
+ * HTTP Session. We use standard SessionScoped bean to not need
+ * to treat async-supported and similar headache.
+ * 
+ * @author lu4242
+ */
+@SessionScoped
+public class FlowScopeContextualStorageHolder 
+        extends AbstractContextualStorageHolder<ContextualStorage>
+        implements Serializable
+{
+    /**
+     * key: client window id + flow id
+     * value: the {@link ContextualStorage} which holds all the
+     * {@link jakarta.enterprise.inject.spi.Bean}s.
+     */
+    
+    // clientwindow <> List<Flow>
+    private Map<String, List<String>> activeFlowMapKeys;
+    
+    private LRULinkedHashMap<String, String> clientWindowExpirationStack;
+    
+    public static final String CURRENT_FLOW_SCOPE_MAP = "oam.CURRENT_FLOW_SCOPE_MAP";
+
+    public FlowScopeContextualStorageHolder()
+    {
+    }
+    
+    @PostConstruct
+    @Override
+    public void init()
+    {
+        super.init();
+        
+        activeFlowMapKeys = new ConcurrentHashMap<>();
+
+        FacesContext facesContext = FacesContext.getCurrentInstance();
+
+        Integer numberOfFacesFlowClientWindowIdsInSession =
+                MyfacesConfig.getCurrentInstance(facesContext).getNumberOfFacesFlowClientWindowIdsInSession();
+        clientWindowExpirationStack = new LRULinkedHashMap<>(numberOfFacesFlowClientWindowIdsInSession, (eldest) ->
+        {
+            clearFlowMap(FacesContext.getCurrentInstance(), eldest.getKey());
+        });
+
+        refreshClientWindow(facesContext);
+    }
+
+    public Map<Object, Object> getFlowScopeMap(BeanManager beanManager, String flowClientWindowId, boolean create)
+    {
+        ContextualStorage contextualStorage = getContextualStorage(flowClientWindowId, create);
+        if (contextualStorage == null)
+        {
+            return null;
+        }
+
+        ContextualInstanceInfo info = contextualStorage.getStorage().get(CURRENT_FLOW_SCOPE_MAP);
+        if (info == null && create)
+        {
+            info = new ContextualInstanceInfo<>();
+            contextualStorage.getStorage().put(CURRENT_FLOW_SCOPE_MAP, info);
+        }
+        if (info == null)
+        {
+            return null;
+        }
+
+        Map<Object, Object> map = (Map<Object, Object>) info.getContextualInstance();
+        if (map == null && create)
+        {
+            map = new HashMap<>();
+            info.setContextualInstance(map);
+        }
+        return map;
+    }
+
+    public void refreshClientWindow(FacesContext facesContext)
+    {
+        ClientWindow cw = facesContext.getExternalContext().getClientWindow();
+        if (cw != null && cw.getId() != null)
+        {
+            clientWindowExpirationStack.put(cw.getId(), "");
+        }
+    }
+    
+    public void clearFlowMap(FacesContext facesContext, String clientWindowId)
+    {
+        List<String> activeFlowKeys = activeFlowMapKeys.remove(clientWindowId);
+        if (activeFlowKeys != null && !activeFlowKeys.isEmpty())
+        {
+            for (String flowMapKey : activeFlowKeys)
+            {
+                ContextualStorage contextualStorage = storageMap.remove(flowMapKey);
+                if (contextualStorage != null)
+                {
+                    destroyAll(contextualStorage, facesContext);
+                }
+            }
+        }
+    }
+    
+    public List<String> getActiveFlowMapKeys(FacesContext facesContext)
+    {
+        ClientWindow cw = facesContext.getExternalContext().getClientWindow();
+        String baseKey = cw.getId();
+        List<String> activeFlowKeys = activeFlowMapKeys.get(baseKey);
+        if (activeFlowKeys == null)
+        {
+            return Collections.emptyList();
+        }
+
+        return activeFlowKeys;
+    }
+    
+    public void createCurrentFlowScope(FacesContext facesContext)
+    {
+        ClientWindow cw = facesContext.getExternalContext().getClientWindow();
+        String baseKey = cw.getId();
+        
+        FlowHandler flowHandler = facesContext.getApplication().getFlowHandler();
+        Flow flow = flowHandler.getCurrentFlow(facesContext);
+        String flowMapKey = FlowUtils.getFlowMapKey(facesContext, flow);
+
+        List<String> activeFlowKeys = activeFlowMapKeys.computeIfAbsent(baseKey, k -> new ArrayList<>());
+        activeFlowKeys.add(0, flowMapKey);
+        activeFlowMapKeys.put(baseKey, activeFlowKeys);
+        refreshClientWindow(facesContext);
+    }
+    
+    public void destroyCurrentFlowScope(FacesContext facesContext)
+    {
+        ClientWindow cw = facesContext.getExternalContext().getClientWindow();
+        String baseKey = cw.getId();
+        
+        FlowHandler flowHandler = facesContext.getApplication().getFlowHandler();
+        Flow flow = flowHandler.getCurrentFlow(facesContext);
+        String flowMapKey = FlowUtils.getFlowMapKey(facesContext, flow);
+
+        ContextualStorage contextualStorage = storageMap.remove(flowMapKey);
+        if (contextualStorage != null)
+        {
+            destroyAll(contextualStorage, facesContext);
+        }
+        
+        List<String> activeFlowKeys = activeFlowMapKeys.get(baseKey);
+        if (activeFlowKeys != null && !activeFlowKeys.isEmpty())
+        {
+            activeFlowKeys.remove(flowMapKey);
+        }
+    }
+
+    @Override
+    protected boolean isSkipDestroy(Map.Entry<Object, ContextualInstanceInfo<?>> entry)
+    {
+        return CURRENT_FLOW_SCOPE_MAP.equals(entry.getKey());
+    }
+
+    @Override
+    protected ContextualStorage newContextualStorage(String slotId)
+    {
+        return new ContextualStorage(beanManager, true);
+    }
+
+    public static FlowScopeContextualStorageHolder getInstance(FacesContext facesContext)
+    {
+        return getInstance(facesContext, false);
+    }
+    
+    public static FlowScopeContextualStorageHolder getInstance(FacesContext facesContext, boolean create)
+    {
+        return getInstance(facesContext, FlowScopeContextualStorageHolder.class, create);
+    }
+}
diff --git a/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeExtension.java b/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeExtension.java
index 47ab63b..692f3c9 100644
--- a/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeExtension.java
+++ b/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeExtension.java
@@ -48,9 +48,8 @@ public class FlowScopeExtension implements Extension
     void beforeBeanDiscovery(@Observes final BeforeBeanDiscovery event, BeanManager beanManager)
     {
         event.addScope(FlowScoped.class, true, true);
-        // Register FlowBuilderFactoryBean as a bean with CDI annotations, so the system
-        // can take it into account, and use it later when necessary.
-        AnnotatedType bean = beanManager.createAnnotatedType(FlowScopeBeanHolder.class);
+
+        AnnotatedType bean = beanManager.createAnnotatedType(FlowScopeContextualStorageHolder.class);
         event.addAnnotatedType(bean, bean.getJavaClass().getName());
     }
     
@@ -76,5 +75,4 @@ public class FlowScopeExtension implements Extension
         flowScopedContext = new FlowScopeContext(manager, flowBeanReferences);
         event.addContext(flowScopedContext);
     }
-
 }
diff --git a/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeMap.java b/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeMap.java
index d8a7efd..a6bf42e 100644
--- a/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeMap.java
+++ b/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeMap.java
@@ -26,7 +26,7 @@ import jakarta.enterprise.inject.spi.BeanManager;
 import java.util.Collections;
 
 /**
- * 
+ *
  *
  * @author Leonardo Uribe
  */
@@ -34,9 +34,9 @@ public class FlowScopeMap implements Map
 {
     private BeanManager beanManager;
     private String currentClientWindowFlowId;
-    private FlowScopeBeanHolder beanHolder;
+    private FlowScopeContextualStorageHolder storageHolder;
     private boolean beanHolderInitialized = false;
-    
+
     public FlowScopeMap(BeanManager beanManager, String currentClientWindowFlowId)
     {
         this.beanManager = beanManager;
@@ -45,33 +45,33 @@ public class FlowScopeMap implements Map
 
     private Map<Object, Object> getWrapped(boolean create)
     {
-        if (beanHolder == null)
+        if (storageHolder == null)
         {
             if (create)
             {
-                beanHolder = CDIUtils.get(beanManager, FlowScopeBeanHolder.class);
+                storageHolder = CDIUtils.get(beanManager, FlowScopeContextualStorageHolder.class);
             }
             else if (!beanHolderInitialized)
             {
-                beanHolder = CDIUtils.get(beanManager, FlowScopeBeanHolder.class, false);
+                storageHolder = CDIUtils.get(beanManager, FlowScopeContextualStorageHolder.class, false);
                 beanHolderInitialized = true;
             }
         }
 
-        if (beanHolder == null)
+        if (storageHolder == null)
         {
             return null;
         }
-        return beanHolder.getFlowScopeMap(beanManager, currentClientWindowFlowId, create);
+        return storageHolder.getFlowScopeMap(beanManager, currentClientWindowFlowId, create);
     }
-    
+
     @Override
     public int size()
     {
         Map<Object, Object> wrapped = getWrapped(false);
         return wrapped == null ? 0 : wrapped.size();
     }
-    
+
     @Override
     public boolean isEmpty()
     {
diff --git a/impl/src/main/java/org/apache/myfaces/flow/impl/DefaultFacesFlowProvider.java b/impl/src/main/java/org/apache/myfaces/flow/impl/DefaultFacesFlowProvider.java
index cc8ca64..49a7912 100644
--- a/impl/src/main/java/org/apache/myfaces/flow/impl/DefaultFacesFlowProvider.java
+++ b/impl/src/main/java/org/apache/myfaces/flow/impl/DefaultFacesFlowProvider.java
@@ -125,12 +125,6 @@ public class DefaultFacesFlowProvider extends FacesFlowProvider
         return map;
     }
 
-    @Override
-    public void onSessionDestroyed()
-    {
-        
-    }
-
     protected String getFlowKey(Flow flow)
     {
         return CURRENT_FLOW_SCOPE_MAP + SEPARATOR_CHAR
diff --git a/impl/src/main/java/org/apache/myfaces/push/WebsocketComponentRenderer.java b/impl/src/main/java/org/apache/myfaces/push/WebsocketComponentRenderer.java
index 758f62f..fa2889f 100644
--- a/impl/src/main/java/org/apache/myfaces/push/WebsocketComponentRenderer.java
+++ b/impl/src/main/java/org/apache/myfaces/push/WebsocketComponentRenderer.java
@@ -119,7 +119,7 @@ public class WebsocketComponentRenderer extends Renderer implements ComponentSys
         String channel = component.getChannel();
 
         // TODO: use a single bean and entry point for this algorithm.
-        BeanManager beanManager = CDIUtils.getBeanManager(facesContext.getExternalContext());
+        BeanManager beanManager = CDIUtils.getBeanManager(facesContext);
 
         WebsocketChannelTokenBuilderBean channelTokenBean = CDIUtils.get(
                 beanManager,
@@ -169,7 +169,7 @@ public class WebsocketComponentRenderer extends Renderer implements ComponentSys
         else if (scope.equals("session"))
         {
             sessionTokenBean = (sessionTokenBean != null) ? sessionTokenBean : CDIUtils.get(
-                    CDIUtils.getBeanManager(facesContext.getExternalContext()),
+                    CDIUtils.getBeanManager(facesContext),
                     WebsocketSessionBean.class);
 
             sessionTokenBean.registerWebsocketSession(channelToken, metadata);
@@ -178,7 +178,7 @@ public class WebsocketComponentRenderer extends Renderer implements ComponentSys
         {
             //Default application
             appTokenBean = (appTokenBean != null) ? appTokenBean : CDIUtils.get(
-                    CDIUtils.getBeanManager(facesContext.getExternalContext()),
+                    CDIUtils.getBeanManager(facesContext),
                     WebsocketApplicationBean.class);
 
             appTokenBean.registerWebsocketSession(channelToken, metadata);
diff --git a/impl/src/main/java/org/apache/myfaces/push/cdi/PushContextCDIExtension.java b/impl/src/main/java/org/apache/myfaces/push/cdi/PushContextCDIExtension.java
index 69f8613..077cdba 100644
--- a/impl/src/main/java/org/apache/myfaces/push/cdi/PushContextCDIExtension.java
+++ b/impl/src/main/java/org/apache/myfaces/push/cdi/PushContextCDIExtension.java
@@ -34,10 +34,6 @@ public class PushContextCDIExtension implements Extension
     {
         // Register PushContextFactoryBean as a bean with CDI annotations, so the system
         // can take it into account, and use it later when necessary.
-        AnnotatedType<PushContextFactoryBean> pushContextFactoryBean =
-                        beanManager.createAnnotatedType(PushContextFactoryBean.class);
-        event.addAnnotatedType(pushContextFactoryBean, pushContextFactoryBean.getJavaClass().getName());
-        
         AnnotatedType wcbean = beanManager.createAnnotatedType(WebsocketChannelTokenBuilderBean.class);
         event.addAnnotatedType(wcbean, wcbean.getJavaClass().getName());
         
diff --git a/impl/src/main/java/org/apache/myfaces/push/cdi/PushContextFactoryBean.java b/impl/src/main/java/org/apache/myfaces/push/cdi/PushContextFactoryBean.java
deleted file mode 100644
index b871d35..0000000
--- a/impl/src/main/java/org/apache/myfaces/push/cdi/PushContextFactoryBean.java
+++ /dev/null
@@ -1,44 +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.push.cdi;
-
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.enterprise.inject.Disposes;
-import jakarta.enterprise.inject.Produces;
-import jakarta.enterprise.inject.spi.InjectionPoint;
-import jakarta.faces.push.Push;
-import jakarta.faces.push.PushContext;
-
-@ApplicationScoped
-public class PushContextFactoryBean
-{
-
-    @Produces
-    @Push
-    public PushContext createPushContext(InjectionPoint ip)
-    {
-        Push push = ip.getAnnotated().getAnnotation(Push.class);
-        String channel = push.channel().isEmpty() ? ip.getMember().getName() : push.channel();
-        return new PushContextImpl(channel);
-    }
-    
-    public void close(@Disposes @Push PushContext context) 
-    {
-    }
-}
diff --git a/impl/src/main/java/org/apache/myfaces/push/cdi/PushContextImpl.java b/impl/src/main/java/org/apache/myfaces/push/cdi/PushContextImpl.java
index 25d8ca6..29ea805 100644
--- a/impl/src/main/java/org/apache/myfaces/push/cdi/PushContextImpl.java
+++ b/impl/src/main/java/org/apache/myfaces/push/cdi/PushContextImpl.java
@@ -57,7 +57,7 @@ public class PushContextImpl implements PushContext
         FacesContext facesContext = FacesContext.getCurrentInstance();
         if (facesContext != null)
         {
-            beanManager = CDIUtils.getBeanManager(facesContext.getExternalContext());
+            beanManager = CDIUtils.getBeanManager(facesContext);
         }
         else
         {
@@ -143,7 +143,7 @@ public class PushContextImpl implements PushContext
         FacesContext facesContext = FacesContext.getCurrentInstance();
         if (facesContext != null)
         {
-            beanManager = CDIUtils.getBeanManager(facesContext.getExternalContext());
+            beanManager = CDIUtils.getBeanManager(facesContext);
         }
         else
         {
diff --git a/impl/src/main/java/org/apache/myfaces/spi/FacesFlowProvider.java b/impl/src/main/java/org/apache/myfaces/spi/FacesFlowProvider.java
index 85e1630..1116544 100644
--- a/impl/src/main/java/org/apache/myfaces/spi/FacesFlowProvider.java
+++ b/impl/src/main/java/org/apache/myfaces/spi/FacesFlowProvider.java
@@ -29,8 +29,6 @@ import jakarta.faces.flow.Flow;
  */
 public abstract class FacesFlowProvider
 {
-    public abstract void onSessionDestroyed();
-    
     public abstract Iterator<Flow> getAnnotatedFlows(FacesContext facesContext);
     
     public abstract void doAfterEnterFlow(FacesContext context, Flow flow);
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 6ea0762..637e792 100644
--- a/impl/src/main/java/org/apache/myfaces/view/ViewScopeProxyMap.java
+++ b/impl/src/main/java/org/apache/myfaces/view/ViewScopeProxyMap.java
@@ -81,7 +81,7 @@ public class ViewScopeProxyMap extends HashMap<String, Object> implements StateH
 
                 if (_viewScopeId == null)
                 {
-                    BeanManager beanManager = CDIUtils.getBeanManager(facesContext.getExternalContext());
+                    BeanManager beanManager = CDIUtils.getBeanManager(facesContext);
                     ViewScopeContextualStorageHolder beanHolder =
                             CDIUtils.get(beanManager, ViewScopeContextualStorageHolder.class);
                     _viewScopeId = beanHolder.generateUniqueViewScopeId();
diff --git a/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java b/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java
index 7295757..a748ad9 100644
--- a/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java
+++ b/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java
@@ -66,8 +66,6 @@ import org.apache.myfaces.push.EndpointImpl;
 import org.apache.myfaces.push.WebsocketConfigurator;
 import org.apache.myfaces.push.WebsocketFacesInit;
 import org.apache.myfaces.util.lang.ClassUtils;
-import org.apache.myfaces.spi.FacesFlowProvider;
-import org.apache.myfaces.spi.FacesFlowProviderFactory;
 import org.apache.myfaces.spi.ServiceProviderFinder;
 import org.apache.myfaces.spi.ServiceProviderFinderFactory;
 import org.apache.myfaces.view.facelets.ViewPoolProcessor;
@@ -165,17 +163,6 @@ public abstract class AbstractFacesInitializer implements FacesInitializer
             ExternalSpecifications.isEL3Available();
             ExternalSpecifications.isServlet4Available();
 
-            FacesFlowProviderFactory facesFlowProviderFactory =
-                    FacesFlowProviderFactory.getFacesFlowProviderFactory(externalContext);
-            FacesFlowProvider facesFlowProvider = facesFlowProviderFactory.getFacesFlowProvider(externalContext);
-            
-            MyFacesHttpSessionListener listener = (MyFacesHttpSessionListener) externalContext.getApplicationMap()
-                    .get(MyFacesHttpSessionListener.APPLICATION_MAP_KEY);
-            if (listener != null)
-            {
-                listener.setFacesFlowProvider(facesFlowProvider);
-            }
-            
             String useEncryption = servletContext.getInitParameter(StateUtils.USE_ENCRYPTION);
             if ("false".equals(useEncryption))
             {
diff --git a/impl/src/main/java/org/apache/myfaces/webapp/MyFacesHttpSessionListener.java b/impl/src/main/java/org/apache/myfaces/webapp/MyFacesHttpSessionListener.java
index 2ece7d6..7f5b99a 100644
--- a/impl/src/main/java/org/apache/myfaces/webapp/MyFacesHttpSessionListener.java
+++ b/impl/src/main/java/org/apache/myfaces/webapp/MyFacesHttpSessionListener.java
@@ -29,24 +29,17 @@ import org.apache.myfaces.cdi.view.ViewScopeContext;
 import org.apache.myfaces.context.ExceptionHandlerImpl;
 import org.apache.myfaces.context.servlet.StartupFacesContextImpl;
 import org.apache.myfaces.context.servlet.StartupServletExternalContextImpl;
-import org.apache.myfaces.spi.FacesFlowProvider;
+import org.apache.myfaces.flow.cdi.FlowScopeContext;
 
 public class MyFacesHttpSessionListener implements HttpSessionListener
 {
     public static final String APPLICATION_MAP_KEY = MyFacesHttpSessionListener.class.getName();
 
-    private FacesFlowProvider facesFlowProvider = null;
-
-    public void setFacesFlowProvider(FacesFlowProvider facesFlowProvider)
-    {
-        this.facesFlowProvider = facesFlowProvider;
-    }
-    
     @Override
     public void sessionCreated(HttpSessionEvent event)
     {
     }
-    
+
     @Override
     public void sessionDestroyed(HttpSessionEvent event)
     {
@@ -59,10 +52,7 @@ public class MyFacesHttpSessionListener implements HttpSessionListener
         FacesContext facesContext = FacesContext.getCurrentInstance();
         if (facesContext != null)
         {
-            if (facesFlowProvider != null)
-            {
-                facesFlowProvider.onSessionDestroyed();
-            }
+            FlowScopeContext.destroyAll(facesContext);
             ViewScopeContext.destroyAll(facesContext);
             ClientWindowScopeContext.destroyAll(facesContext);
         }
@@ -78,10 +68,7 @@ public class MyFacesHttpSessionListener implements HttpSessionListener
                 ExceptionHandler exceptionHandler = new ExceptionHandlerImpl();
                 facesContext = new StartupFacesContextImpl(externalContext, externalContext, exceptionHandler, false);
 
-                if (facesFlowProvider != null)
-                {
-                    facesFlowProvider.onSessionDestroyed();
-                }
+                FlowScopeContext.destroyAll(facesContext);
                 ViewScopeContext.destroyAll(facesContext);
                 ClientWindowScopeContext.destroyAll(facesContext);
             }
diff --git a/impl/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension b/impl/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension
index 5ba850d..b8ef9c3 100644
--- a/impl/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension
+++ b/impl/src/main/resources/META-INF/services/jakarta.enterprise.inject.spi.Extension
@@ -8,6 +8,5 @@ org.apache.myfaces.cdi.view.ViewScopeExtension
 org.apache.myfaces.cdi.view.ViewTransientScopeExtension
 org.apache.myfaces.config.annotation.CdiAnnotationProviderExtension
 org.apache.myfaces.push.cdi.PushContextCDIExtension
-org.apache.myfaces.flow.cdi.FlowBuilderExtension
 org.apache.myfaces.flow.cdi.FlowScopeExtension
 org.apache.myfaces.cdi.clientwindow.ClientWindowScopeExtension
\ No newline at end of file