public void destroyFaces(ServletContext servletContext)
    {

        FacesContext facesContext = FacesContext.getCurrentInstance();

        if (!WebConfigParamUtils.getBooleanInitParameter(facesContext.getExternalContext(),
                                                         INITIALIZE_ALWAYS_STANDALONE, false))
        {
            //We need to check if the current application was initialized by myfaces
            WebConfigProvider webConfigProvider = WebConfigProviderFactory.getWebConfigProviderFactory(
                    facesContext.getExternalContext()).getWebConfigProvider(facesContext.getExternalContext());

            if (webConfigProvider.getFacesServletMappings(facesContext.getExternalContext()).isEmpty())
            {
                // check to see if the FacesServlet was found by MyFacesContainerInitializer
                Boolean mappingAdded = (Boolean) servletContext.getAttribute(FACES_SERVLET_FOUND);

                if (mappingAdded == null || !mappingAdded)
                {
                    // check if the FacesServlet has been added dynamically
                    // in a Servlet 3.0 environment by MyFacesContainerInitializer
                    mappingAdded = (Boolean) servletContext.getAttribute(FACES_SERVLET_ADDED_ATTRIBUTE);

                    if (mappingAdded == null || !mappingAdded)
                    {
                        if (log.isLoggable(Level.WARNING))
                        {
                            log.warning("No mappings of FacesServlet found. Abort destroy MyFaces.");
                        }
                        return;
                    }
                }
            }
        }

        _dispatchApplicationEvent(servletContext, PreDestroyApplicationEvent.class);

        _callPreDestroyOnInjectedJSFArtifacts(facesContext);
        
        // clear the cache of MetaRulesetImpl in order to prevent a memory leak
        MetaRulesetImpl.clearMetadataTargetCache();
        
        // clear UIViewParameter default renderer map
        try
        {
            Class<?> c = Class.forName("javax.faces.component.UIViewParameter");
            Method m = c.getDeclaredMethod("releaseRenderer");
            m.setAccessible(true);
            m.invoke(null);
        }
        catch(ClassNotFoundException e)
        {
            log.log(Level.SEVERE, e.getMessage(), e);
        }
        catch(NoSuchMethodException e)
        {
            log.log(Level.SEVERE, e.getMessage(), e);
        }
        catch(IllegalAccessException e)
        {
            log.log(Level.SEVERE, e.getMessage(), e);
        }
        catch(InvocationTargetException e)
        {
            log.log(Level.SEVERE, e.getMessage(), e);
        }

        // TODO is it possible to make a real cleanup?
    }
public void destroyFaces ( ServletContext servletContext ) { FacesContext facesContext = FacesContext . getCurrentInstance ( ) ; if ( ! WebConfigParamUtils . getBooleanInitParameter ( facesContext . getExternalContext ( ) , INITIALIZE_ALWAYS_STANDALONE , false ) ) { WebConfigProvider webConfigProvider = WebConfigProviderFactory . getWebConfigProviderFactory ( facesContext . getExternalContext ( ) ) . getWebConfigProvider ( facesContext . getExternalContext ( ) ) ; if ( webConfigProvider . getFacesServletMappings ( facesContext . getExternalContext ( ) ) . isEmpty ( ) ) { Boolean mappingAdded = ( Boolean ) servletContext . getAttribute ( FACES_SERVLET_FOUND ) ; if ( mappingAdded == null || ! mappingAdded ) { mappingAdded = ( Boolean ) servletContext . getAttribute ( FACES_SERVLET_ADDED_ATTRIBUTE ) ; if ( mappingAdded == null || ! mappingAdded ) { if ( log . isLoggable ( Level . WARNING ) ) { log . warning ( "No mappings of FacesServlet found. Abort destroy MyFaces." ) ; } return ; } } } } _dispatchApplicationEvent ( servletContext , PreDestroyApplicationEvent . class ) ; _callPreDestroyOnInjectedJSFArtifacts ( facesContext ) ; MetaRulesetImpl . clearMetadataTargetCache ( ) ; try { Class < ? > c = Class . forName ( "javax.faces.component.UIViewParameter" ) ; Method m = c . getDeclaredMethod ( "releaseRenderer" ) ; m . setAccessible ( true ) ; m . invoke ( null ) ; } catch ( ClassNotFoundException e ) { log . log ( Level . SEVERE , e . getMessage ( ) , e ) ; } catch ( NoSuchMethodException e ) { log . log ( Level . SEVERE , e . getMessage ( ) , e ) ; } catch ( IllegalAccessException e ) { log . log ( Level . SEVERE , e . getMessage ( ) , e ) ; } catch ( InvocationTargetException e ) { log . log ( Level . SEVERE , e . getMessage ( ) , e ) ; } }
Cleans up all remaining resources (well, theoretically).