You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2013/07/28 23:10:09 UTC

svn commit: r1507846 [1/3] - in /myfaces/core/trunk/impl: ./ src/main/java/org/apache/myfaces/application/ src/main/java/org/apache/myfaces/config/ src/main/java/org/apache/myfaces/config/element/ src/main/java/org/apache/myfaces/config/impl/digester/ ...

Author: lu4242
Date: Sun Jul 28 21:10:08 2013
New Revision: 1507846

URL: http://svn.apache.org/r1507846
Log:
MYFACES-3691 Implement Faces Flows MYFACES-3741 Implement CDI Flow Scope MYFACES-3742 Implement @FlowDefinition annotation 

Added:
    myfaces/core/trunk/impl/faces-flow.NavData
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_FlowNavigationStructure.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_WildcardPattern.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesFlowReference.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesFlowReferenceImpl.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/implicitobject/FlowScopeImplicitObject.java
      - copied, changed from r1505853, myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/implicitobject/SessionScopeImplicitObject.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/FlowReference.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/AnnotatedFlowConfigurator.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FacesFlowCDIUtils.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowBuilderCDIExtension.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowBuilderFactoryBean.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowDefinitionQualifier.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeCDIExtension.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeMap.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopedContextImpl.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/SubKeyMap.java
      - copied, changed from r1505853, myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/context/flash/SubKeyMap.java
    myfaces/core/trunk/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/flow/   (with props)
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/flow/FlowMyFacesRequestTestCase.java   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/flow/
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/flow/WEB-INF/   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/flow/WEB-INF/flow1-flow.xml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/flow/flow1/
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/flow/flow1/begin.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/flow/flow1/content.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/flow/flow1_1.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/flow/flow1_2.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/flow/flow1_end.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/flow/flow2/
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/flow/flow2/begin.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/flow/flow2/content.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/flow/flow3/   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/flow/flow3/begin.xhtml   (with props)
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/application/flow/flow3/content.xhtml   (with props)
Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/DefaultFacesConfigurationMerger.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/DefaultFacesConfigurationProvider.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesFlowCall.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesFlowMethodCall.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/DigesterFacesConfigUnmarshallerImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesFlowCallImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesFlowMethodCallImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/implicitobject/ImplicitObjectResolver.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/FlowCallNodeImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/FlowHandlerImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/FlowImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/builder/FlowBuilderImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/builder/ReturnBuilderImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/lifecycle/ClientWindowFactoryImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationProvider.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationProviderWrapper.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/config/FacesConfiguratorDefaultValidatorsTestCase.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/config/impl/digister/DigesterFacesConfigUnmarshallerImplTest.java
    myfaces/core/trunk/impl/src/test/resources/org/apache/myfaces/config/impl/digister/faces-flow.xml

Added: myfaces/core/trunk/impl/faces-flow.NavData
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/faces-flow.NavData?rev=1507846&view=auto
==============================================================================
--- myfaces/core/trunk/impl/faces-flow.NavData (added)
+++ myfaces/core/trunk/impl/faces-flow.NavData Sun Jul 28 21:10:08 2013
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scene Scope="Project" version="2">
+    <Scope Scope="Faces Configuration Only"/>
+    <Scope Scope="Project"/>
+    <Scope Scope="All Faces Configurations"/>
+</Scene>

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java?rev=1507846&r1=1507845&r2=1507846&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/NavigationHandlerImpl.java Sun Jul 28 21:10:08 2013
@@ -28,10 +28,12 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import java.util.regex.Pattern;
+import javax.el.MethodExpression;
 import javax.faces.FacesException;
 import javax.faces.application.ConfigurableNavigationHandler;
 import javax.faces.application.FacesMessage;
@@ -47,6 +49,16 @@ import javax.faces.component.visit.Visit
 import javax.faces.context.ExternalContext;
 import javax.faces.context.FacesContext;
 import javax.faces.context.PartialViewContext;
+import javax.faces.flow.Flow;
+import javax.faces.flow.FlowCallNode;
+import javax.faces.flow.FlowHandler;
+import javax.faces.flow.FlowNode;
+import javax.faces.flow.MethodCallNode;
+import javax.faces.flow.Parameter;
+import javax.faces.flow.ReturnNode;
+import javax.faces.flow.SwitchCase;
+import javax.faces.flow.SwitchNode;
+import javax.faces.flow.ViewNode;
 import javax.faces.view.ViewDeclarationLanguage;
 import javax.faces.view.ViewMetadata;
 
@@ -54,6 +66,7 @@ import org.apache.myfaces.config.Runtime
 import org.apache.myfaces.config.element.NavigationRule;
 import org.apache.myfaces.shared.application.NavigationUtils;
 import org.apache.myfaces.shared.renderkit.html.util.SharedStringBuilder;
+import org.apache.myfaces.shared.util.ClassUtils;
 import org.apache.myfaces.shared.util.HashMapUtils;
 import org.apache.myfaces.shared.util.StringUtils;
 import org.apache.myfaces.view.facelets.tag.jsf.PreDisposeViewEvent;
@@ -78,9 +91,13 @@ public class NavigationHandlerImpl
     private static final String ASTERISK = "*";
 
     private Map<String, Set<NavigationCase>> _navigationCases = null;
-    private List<String> _wildcardKeys = new ArrayList<String>();
+    //private List<String> _wildcardKeys = new ArrayList<String>();
+    private List<_WildcardPattern> _wildcardPatterns = new ArrayList<_WildcardPattern>();
     private Boolean _developmentStage;
     
+    private Map<String, _FlowNavigationStructure> _flowNavigationStructureMap = 
+        new ConcurrentHashMap<String, _FlowNavigationStructure>();
+    
     private NavigationHandlerSupport navigationHandlerSupport;
 
     public NavigationHandlerImpl()
@@ -94,7 +111,16 @@ public class NavigationHandlerImpl
     @Override
     public void handleNavigation(FacesContext facesContext, String fromAction, String outcome)
     {
-        NavigationCase navigationCase = getNavigationCase(facesContext, fromAction, outcome);
+        handleNavigation(facesContext, fromAction, outcome, null);
+    }
+
+    @Override
+    public void handleNavigation(FacesContext facesContext, String fromAction, 
+        String outcome, String toFlowDocumentId)
+    {
+        //NavigationCase navigationCase = getNavigationCase(facesContext, fromAction, outcome);
+        NavigationContext navigationContext = new NavigationContext();
+        NavigationCase navigationCase = getNavigationCommand(facesContext, navigationContext, fromAction, outcome);
 
         if (navigationCase != null)
         {
@@ -213,6 +239,27 @@ public class NavigationHandlerImpl
                         facesContext.getAttributes().remove(SKIP_ITERATION_HINT);
                     }
                 }
+                
+                //Apply Flow transition if any
+                if (navigationContext != null)
+                {
+                    // Is any flow transition on the way?
+                    if (navigationContext.getSourceFlow() != null ||
+                        (navigationContext.getTargetFlows() != null &&
+                         !navigationContext.getTargetFlows().isEmpty()))
+                    {
+                        FlowHandler flowHandler = facesContext.getApplication().getFlowHandler();
+                        Flow sourceFlow = navigationContext.getSourceFlow();
+                        for (int i = 0; i < navigationContext.getTargetFlows().size(); i++)
+                        {
+                            Flow targetFlow = navigationContext.getTargetFlows().get(i);
+                            flowHandler.transition(facesContext, sourceFlow, targetFlow, 
+                                navigationContext.getFlowCallNodes().get(i), 
+                                navigationContext.getNavigationCase().getToViewId(facesContext));
+                            sourceFlow = targetFlow;
+                        }
+                    }
+                }
 
                 // create UIViewRoot for new view
                 UIViewRoot viewRoot = null;
@@ -292,8 +339,14 @@ public class NavigationHandlerImpl
      */
     public NavigationCase getNavigationCase(FacesContext facesContext, String fromAction, String outcome)
     {
-        String viewId = facesContext.getViewRoot() != null ? facesContext.getViewRoot().getViewId() : null;
-        
+        NavigationContext navigationContext = new NavigationContext();
+        return getNavigationCommand(facesContext, navigationContext, fromAction, outcome);
+    }
+    
+    public NavigationCase getNavigationCommandFromGlobalNavigationCases(
+        FacesContext facesContext, String viewId, NavigationContext navigationContext, 
+        String fromAction, String outcome)
+    {
         Map<String, Set<NavigationCase>> casesMap = getNavigationCases();
         NavigationCase navigationCase = null;
         
@@ -311,48 +364,312 @@ public class NavigationHandlerImpl
         if (navigationCase == null)
         {
             // Wildcard match?
-            List<String> sortedWildcardKeys = getSortedWildcardKeys();
-            for (int i = 0; i < sortedWildcardKeys.size(); i++)
+            //List<String> sortedWildcardKeys = getSortedWildcardKeys();
+            List<_WildcardPattern> wildcardPatterns = getSortedWildcardPatterns();
+            
+            for (int i = 0; i < wildcardPatterns.size(); i++)
             {
-                String fromViewId = sortedWildcardKeys.get(i);
-                if (fromViewId.length() > 2)
+                _WildcardPattern wildcardPattern = wildcardPatterns.get(i);
+                if (wildcardPattern.match(viewId))
                 {
-                    String prefix = fromViewId.substring(0, fromViewId.length() - 1);
-                    if (viewId != null && viewId.startsWith(prefix))
+                    casesSet = casesMap.get(wildcardPattern.getPattern());
+                    if (casesSet != null)
                     {
-                        casesSet = casesMap.get(fromViewId);
-                        if (casesSet != null)
+                        navigationCase = calcMatchingNavigationCase(facesContext, casesSet, fromAction, outcome);
+                        if (navigationCase != null)
                         {
-                            navigationCase = calcMatchingNavigationCase(facesContext, casesSet, fromAction, outcome);
-                            if (navigationCase != null)
-                            {
-                                break;
-                            }
+                            break;
                         }
                     }
                 }
+            }
+        }
+        return navigationCase;
+    }
+    
+    public NavigationCase getNavigationCommand(
+        FacesContext facesContext, NavigationContext navigationContext, String fromAction, String outcome)
+    {
+        String viewId = facesContext.getViewRoot() != null ? facesContext.getViewRoot().getViewId() : null;
+        NavigationCase navigationCase = getNavigationCommandFromGlobalNavigationCases(
+                facesContext, viewId, navigationContext, fromAction, outcome);
+        // TODO: Add navigation commands for JSF 2.2 Faces Flow Here!
+        if (outcome != null && navigationCase == null)
+        {
+            FlowHandler flowHandler = facesContext.getApplication().getFlowHandler();
+            Flow currentFlow = navigationContext.getCurrentFlow(facesContext);
+            // JSF 2.2 section 7.4.2: "... When outside of a flow, view identifier 
+            // has the additional possibility of being a flow id.
+            Flow targetFlow = null;
+            FlowCallNode targetFlowCallNode = null;
+            if (currentFlow != null)
+            {
+                targetFlow = flowHandler.getFlow(facesContext, currentFlow.getDefiningDocumentId(), outcome);
+            }
+            if (targetFlow == null)
+            {
+                targetFlow = flowHandler.getFlow(facesContext, "", outcome);
+            }
+            boolean startFlow = false;
+            boolean checkFlowNode = false;
+            if (currentFlow != null)
+            {
+                // JSF 2.2 section 7.4.2: When inside a flow, a view identifier has 
+                // the additional possibility of being the id of any node within the 
+                // current flow or the id of another flow
+                if (targetFlow != null)
+                {
+                    if (!currentFlow.getId().equals(targetFlow.getId()))
+                    {
+                        //Start sub flow!
+                        startFlow = true;
+                    }
+                }
                 else
                 {
-                    casesSet = casesMap.get(fromViewId);
-                    if (casesSet != null)
+                    // Check if thie 
+                    checkFlowNode = true;
+                }
+            }
+            else
+            {
+                if (targetFlow != null)
+                {
+                    // start flow!
+                    startFlow = true;
+                }
+            }
+            // If is necessary to enter a flow or there is a current
+            // flow and it is necessary to check a flow node
+            if (startFlow || checkFlowNode)
+            {
+                String outcomeToGo = outcome;
+                String actionToGo = fromAction;
+                boolean complete = false;
+                boolean checkNavCase = true;
+
+                while (!complete && (startFlow || checkFlowNode))
+                {
+                    if (startFlow)
                     {
-                        navigationCase = calcMatchingNavigationCase(facesContext, casesSet, fromAction, outcome);
-                        if (navigationCase != null)
+                        navigationContext.setSourceFlow(currentFlow);
+                        navigationContext.addTargetFlow(targetFlow, targetFlowCallNode);
+                        targetFlowCallNode = null;
+                        // Since we start a new flow, the current flow is now the
+                        // target flow.
+                        navigationContext.pushFlow(facesContext, targetFlow);
+                        currentFlow = targetFlow;
+                        //No outboundCallNode.
+                        //Resolve start node.
+                        if (targetFlow.getStartNodeId() == null)
                         {
-                            break;
+                            // In faces-config javadoc says:
+                            // "If there is no <start-node> element declared, it 
+                            //  is assumed to be <flowName>.xhtml."
+                            outcomeToGo = "/" + targetFlow.getId()+ "/" + 
+                                targetFlow.getId() + ".xhtml";
+                        }
+                        else
+                        {
+                            outcomeToGo = targetFlow.getStartNodeId();
+                        }
+                        checkFlowNode = true;
+                        startFlow = false;
+                    }
+                    if (checkFlowNode)
+                    {
+                        FlowNode flowNode = currentFlow.getNode(outcomeToGo);
+                        if (flowNode != null)
+                        {
+                            checkNavCase = true;
+                            if (!complete && flowNode instanceof SwitchNode)
+                            {
+                                SwitchNode switchNode = (SwitchNode) flowNode;
+                                boolean resolved = false;
+                                // "... iterate over the NavigationCase instances returned from its getCases()
+                                // method. For each, one call getCondition(). If the result is true, let vdl 
+                                // view identifier be the value of its fromOutcome property.
+                                for (SwitchCase switchCase : switchNode.getCases())
+                                {
+                                    Boolean isConditionTrue = switchCase.getCondition(facesContext);
+                                    if (Boolean.TRUE.equals(isConditionTrue))
+                                    {
+                                        outcomeToGo = switchCase.getFromOutcome();
+                                        resolved = true;
+                                        break;
+                                    }
+                                }
+                                if (!resolved)
+                                {
+                                    outcomeToGo = switchNode.getDefaultOutcome(facesContext);
+                                }
+
+                                // Start over again checking if the node exists.
+                                //fromAction = currentFlow.getId();
+                                actionToGo = currentFlow.getId();
+                                flowNode = currentFlow.getNode(outcomeToGo);
+                                continue;
+                            }
+                            if (!complete && flowNode instanceof FlowCallNode)
+                            {
+                                // "... If the node is a FlowCallNode, save it aside as facesFlowCallNode. ..."
+                                FlowCallNode flowCallNode = (FlowCallNode) flowNode;
+
+                                // " ... Let flowId be the value of its calledFlowId property and flowDocumentId 
+                                // be the value of its calledFlowDocumentId property. .."
+
+                                // " ... If no flowDocumentId exists for the node, let it be the string 
+                                // resulting from flowId + "/" + flowId + ".xhtml". ..." 
+                                // -=Leonardo Uribe=- flowDocumentId is inconsistent, waiting for answer of the EG,
+                                // for not let it be null.
+
+                                String calledFlowDocumentId = flowCallNode.getCalledFlowDocumentId(facesContext);
+                                if (calledFlowDocumentId == null)
+                                {
+                                    calledFlowDocumentId = currentFlow.getDefiningDocumentId();
+                                }
+                                targetFlow = flowHandler.getFlow(facesContext, 
+                                    calledFlowDocumentId, 
+                                    flowCallNode.getCalledFlowId(facesContext));
+                                if (targetFlow == null && !"".equals(calledFlowDocumentId))
+                                {
+                                    targetFlow = flowHandler.getFlow(facesContext, 
+                                        "", 
+                                        flowCallNode.getCalledFlowId(facesContext));
+                                }
+                                if (targetFlow != null)
+                                {
+                                    targetFlowCallNode = flowCallNode;
+                                    startFlow = true;
+                                    continue;
+                                }
+                                else
+                                {
+                                    // Ask the FlowHandler for a Flow for this flowId, flowDocumentId pair. Obtain a 
+                                    // reference to the start node and execute this algorithm again, on that start node.
+                                    complete = true;
+                                }
+                                //complete = true;
+                            }
+                            if (!complete && flowNode instanceof MethodCallNode)
+                            {
+                                MethodCallNode methodCallNode = (MethodCallNode) flowNode;
+                                String vdlViewIdentifier = null;
+                                MethodExpression method = methodCallNode.getMethodExpression();
+                                if (method != null)
+                                {
+                                    Object value = invokeMethodCallNode(facesContext, methodCallNode);
+                                    if (value != null)
+                                    {
+                                        vdlViewIdentifier = value.toString();
+                                    }
+                                    else if (methodCallNode.getOutcome() != null)
+                                    {
+                                        vdlViewIdentifier = (String) methodCallNode.getOutcome().getValue(
+                                            facesContext.getELContext());
+                                    }
+                                }
+                                // note a vdlViewIdentifier could be a flow node too
+                                if (vdlViewIdentifier != null)
+                                {
+                                    //navigationCase = createNavigationCase(viewId, outcomeToGo, vdlViewIdentifier);
+                                    outcomeToGo = vdlViewIdentifier;
+                                    actionToGo = currentFlow.getId();
+                                    continue;
+                                }
+                                else
+                                {
+                                    complete = true;
+                                }
+                            }
+                            if (!complete && flowNode instanceof ReturnNode)
+                            {
+                                ReturnNode returnNode = (ReturnNode) flowNode;
+                                String fromOutcome = returnNode.getFromOutcome(facesContext);
+                                
+                                actionToGo = currentFlow.getId();
+                                if (navigationContext.getSourceFlow() == null)
+                                {
+                                    navigationContext.setSourceFlow(
+                                        navigationContext.getCurrentFlow(facesContext));
+                                }                                    
+                                // This is the part when the pseudo "recursive call" is done. 
+                                navigationContext.popFlow(facesContext);
+                                //getNavigationCommand(
+                                //    facesContext, navigationContext, currentFlow.getId(), fromOutcome);
+                                
+                                // TODO: add logic for exit the flow properly
+                                currentFlow = navigationContext.getCurrentFlow(facesContext);
+                                navigationContext.addTargetFlow(currentFlow, null);
+                                outcomeToGo = fromOutcome;
+                                
+                                navigationCase = getNavigationCommand(facesContext, 
+                                        navigationContext, actionToGo, outcomeToGo);
+                                if (navigationCase != null)
+                                {
+                                    complete = true;
+                                }
+                                if (currentFlow == null)
+                                {
+                                    complete = true;
+                                }
+                                continue;
+                                //complete = true;
+                            }
+                            if (!complete && flowNode instanceof ViewNode)
+                            {
+                                ViewNode viewNode = (ViewNode) flowNode;
+                                navigationCase = createNavigationCase(viewId, flowNode.getId(), 
+                                    viewNode.getVdlDocumentId());
+                                complete = true;
+                            }
+                            else
+                            {
+                                //Should not happen
+                                complete = true;
+                            }
+                        }
+                        else if (checkNavCase)
+                        {
+                            // Not found in current flow.
+                            _FlowNavigationStructure flowNavigationStructure = _flowNavigationStructureMap.get(
+                                    currentFlow.getId());
+                            navigationCase = getNavigationCaseFromFlowStructure(facesContext, 
+                                    flowNavigationStructure, actionToGo, outcomeToGo, viewId);
+                            
+                            // JSF 2.2 section 7.4.2 "... any text that references a view identifier, such as 
+                            // <from-view-id> or <to-view-id>,
+                            // can also refer to a flow node ..."
+                            if (navigationCase != null)
+                            {
+                                outcomeToGo = navigationCase.getToViewId(facesContext);
+                                checkNavCase = false;
+                            }
+                            else
+                            {
+                                // No matter if navigationCase is null or not, complete the look.
+                                complete = true;
+                            }
+                        }
+                        else
+                        {
+                            complete = true;
                         }
                     }
                 }
+                // Apply implicit navigation rules over outcomeToGo
+                if (outcomeToGo != null && navigationCase == null)
+                {
+                    navigationCase = getOutcomeNavigationCase (facesContext, actionToGo, outcomeToGo);
+                }
             }
         }
-        
         if (outcome != null && navigationCase == null)
         {
             //if outcome is null, we don't check outcome based nav cases
             //otherwise, if navgiationCase is still null, check outcome-based nav cases
             navigationCase = getOutcomeNavigationCase (facesContext, fromAction, outcome);
         }
-        
         if (outcome != null && navigationCase == null && !facesContext.isProjectStage(ProjectStage.Production))
         {
             final FacesMessage facesMessage = new FacesMessage("No navigation case match for viewId " + viewId + 
@@ -360,9 +677,99 @@ public class NavigationHandlerImpl
             facesMessage.setSeverity(FacesMessage.SEVERITY_WARN);
             facesContext.addMessage(null, facesMessage);
         }
-
-        return navigationCase;  //if navigationCase == null, will stay on current view
-
+        if (navigationCase != null)
+        {
+            navigationContext.setNavigationCase(navigationCase);
+        }
+        return navigationContext.getNavigationCase();
+        // if navigationCase == null, will stay on current view
+    }
+    
+    private Object invokeMethodCallNode(FacesContext facesContext, MethodCallNode methodCallNode)
+    {
+        MethodExpression method = methodCallNode.getMethodExpression();
+        Object value = null;
+        
+        if (methodCallNode.getParameters() != null &&
+            !methodCallNode.getParameters().isEmpty())
+        {
+            Object[] parameters = new Object[methodCallNode.getParameters().size()];
+            Class[] clazzes = new Class[methodCallNode.getParameters().size()];
+            for (int i = 0; i < methodCallNode.getParameters().size(); i++)
+            {
+                Parameter param = methodCallNode.getParameters().get(i);
+                parameters[i] = param.getValue().getValue(facesContext.getELContext());
+                clazzes[i] = param.getName() != null ? 
+                    ClassUtils.simpleJavaTypeToClass(param.getName()) :
+                    (parameters[i] == null ? String.class : parameters[i].getClass());
+            }
+            
+            // Now we need to recreate the EL method expression with the correct clazzes as parameters.
+            // We should do it per invocation, because we don't know the parameter type.
+            method = facesContext.getApplication().getExpressionFactory().createMethodExpression(
+                facesContext.getELContext(), method.getExpressionString(), null, clazzes);
+            value = method.invoke(facesContext.getELContext(), parameters);
+        }
+        else
+        {
+            value = method.invoke(facesContext.getELContext(), null);
+        }
+        return value;
+    }
+    
+    private NavigationCase getNavigationCaseFromFlowStructure(FacesContext facesContext, 
+            _FlowNavigationStructure flowNavigationStructure, String fromAction, String outcome, String viewId)
+    {
+        Set<NavigationCase> casesSet = null;
+        NavigationCase navigationCase = null;
+        
+        if (viewId != null)
+        {
+            casesSet = flowNavigationStructure.getNavigationCases().get(viewId);
+            if (casesSet != null)
+            {
+                // Exact match?
+                navigationCase = calcMatchingNavigationCase(facesContext, casesSet, fromAction, outcome);
+            }
+        }
+        if (navigationCase == null)
+        {
+            List<_WildcardPattern> wildcardPatterns = flowNavigationStructure.getWildcardKeys();
+            for (int i = 0; i < wildcardPatterns.size(); i++)
+            {
+                _WildcardPattern wildcardPattern = wildcardPatterns.get(i);
+                if (wildcardPattern.match(viewId))
+                {
+                    casesSet = flowNavigationStructure.getNavigationCases().get(wildcardPattern.getPattern());
+                    if (casesSet != null)
+                    {
+                        navigationCase = calcMatchingNavigationCase(facesContext, casesSet, fromAction, outcome);
+                        if (navigationCase != null)
+                        {
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        return navigationCase;
+    }
+    
+    private NavigationContext getFlowNavigationCommand (FacesContext facesContext, Flow targetFlow, String node)
+    {
+        return null;
+        
+    }
+    
+    /**
+     * Derive a NavigationCase from a flow node. 
+     * 
+     * @param flowNode
+     * @return 
+     */
+    private NavigationCase createNavigationCase(String fromViewId, String outcome, String toViewId)
+    {
+        return new NavigationCase(fromViewId, null, outcome, null, toViewId, null, false, false);
     }
     
     /**
@@ -745,9 +1152,9 @@ public class NavigationHandlerImpl
         return noConditionCase;
     }
 
-    private List<String> getSortedWildcardKeys()
+    private List<_WildcardPattern> getSortedWildcardPatterns()
     {
-        return _wildcardKeys;
+        return _wildcardPatterns;
     }
 
     @Override
@@ -782,6 +1189,54 @@ public class NavigationHandlerImpl
             return _navigationCases;
         }
     }
+
+    @Override
+    public void inspectFlow(FacesContext context, Flow flow)
+    {
+        Map<String, Set<NavigationCase>> rules = flow.getNavigationCases();
+        int rulesSize = rules.size();
+
+        Map<String, Set<NavigationCase>> cases = new HashMap<String, Set<NavigationCase>>(
+                HashMapUtils.calcCapacity(rulesSize));
+
+        List<_WildcardPattern> wildcardPatterns = new ArrayList<_WildcardPattern>();
+
+        for (Map.Entry<String, Set<NavigationCase>> entry : rules.entrySet())
+        {
+            String fromViewId = entry.getKey();
+
+            //specification 7.4.2 footnote 4 - missing fromViewId is allowed:
+            if (fromViewId == null)
+            {
+                fromViewId = ASTERISK;
+            }
+            else
+            {
+                fromViewId = fromViewId.trim();
+            }
+
+            Set<NavigationCase> set = cases.get(fromViewId);
+            if (set == null)
+            {
+                set = new HashSet<NavigationCase>(entry.getValue());
+                cases.put(fromViewId, set);
+                if (fromViewId.endsWith(ASTERISK))
+                {
+                    wildcardPatterns.add(new _WildcardPattern(fromViewId));
+                }
+            }
+            else
+            {
+                set.addAll(entry.getValue());
+            }
+        }
+
+        Collections.sort(wildcardPatterns, new KeyComparator());
+
+        _flowNavigationStructureMap.put(
+            flow.getId(), 
+            new _FlowNavigationStructure(flow.getDefiningDocumentId(), flow.getId(), cases, wildcardPatterns) );
+    }
     
     private synchronized void calculateNavigationCases(FacesContext facesContext, RuntimeConfig runtimeConfig)
     {
@@ -793,7 +1248,7 @@ public class NavigationHandlerImpl
             Map<String, Set<NavigationCase>> cases = new HashMap<String, Set<NavigationCase>>(
                     HashMapUtils.calcCapacity(rulesSize));
 
-            List<String> wildcardKeys = new ArrayList<String>();
+            List<_WildcardPattern> wildcardPatterns = new ArrayList<_WildcardPattern>();
 
             for (NavigationRule rule : rules)
             {
@@ -816,7 +1271,7 @@ public class NavigationHandlerImpl
                     cases.put(fromViewId, set);
                     if (fromViewId.endsWith(ASTERISK))
                     {
-                        wildcardKeys.add(fromViewId);
+                        wildcardPatterns.add(new _WildcardPattern(fromViewId));
                     }
                 }
                 else
@@ -825,7 +1280,7 @@ public class NavigationHandlerImpl
                 }
             }
 
-            Collections.sort(wildcardKeys, new KeyComparator());
+            Collections.sort(wildcardPatterns, new KeyComparator());
 
             synchronized (cases)
             {
@@ -834,18 +1289,18 @@ public class NavigationHandlerImpl
                 // will not rearrange the execution of the assignment to an
                 // earlier time, before all init code completes
                 _navigationCases = cases;
-                _wildcardKeys = wildcardKeys;
+                _wildcardPatterns = wildcardPatterns;
 
                 runtimeConfig.setNavigationRulesChanged(false);
             }
         }
     }
 
-    private static final class KeyComparator implements Comparator<String>
+    private static final class KeyComparator implements Comparator<_WildcardPattern>
     {
-        public int compare(String s1, String s2)
+        public int compare(_WildcardPattern s1, _WildcardPattern s2)
         {
-            return -s1.compareTo(s2);
+            return -s1.getPattern().compareTo(s2.getPattern());
         }
     }
     
@@ -878,5 +1333,125 @@ public class NavigationHandlerImpl
         
         return apiCases;
     }
+    
+    /**
+     * A navigation command is an operation to do by the navigation handler like
+     * do a redirect, execute a normal navigation or enter or exit a flow. 
+     * 
+     * To resolve a navigation command, it is necessary to get an snapshot of the
+     * current "navigation context" and try to resolve the command.
+     */
+    protected static class NavigationContext
+    {
+        private NavigationCase navigationCase;
+        private Flow sourceFlow;
+        private List<Flow> targetFlows;
+        private List<FlowCallNode> targetFlowCallNodes;
+        private List<Flow> currentFlows;
 
+        public NavigationContext()
+        {
+        }
+
+        public NavigationContext(NavigationCase navigationCase)
+        {
+            this.navigationCase = navigationCase;
+        }
+        
+        public NavigationCase getNavigationCase()
+        {
+            return navigationCase;
+        }
+
+        public void setNavigationCase(NavigationCase navigationCase)
+        {
+            this.navigationCase = navigationCase;
+        }
+
+        public Flow getSourceFlow()
+        {
+            return sourceFlow;
+        }
+
+        public void setSourceFlow(Flow sourceFlow)
+        {
+            this.sourceFlow = sourceFlow;
+        }
+
+        public List<Flow> getTargetFlows()
+        {
+            return targetFlows;
+        }
+        
+        public List<FlowCallNode> getFlowCallNodes()
+        {
+            return targetFlowCallNodes;
+        }
+
+        public void addTargetFlow(Flow targetFlow, FlowCallNode flowCallNode)
+        {
+            if (targetFlows == null)
+            {
+                targetFlows = new ArrayList<Flow>(4);
+                targetFlowCallNodes = new ArrayList<FlowCallNode>(4);
+            }
+            this.targetFlows.add(targetFlow);
+            this.targetFlowCallNodes.add(flowCallNode);
+        }
+        
+        public Flow getCurrentFlow(FacesContext facesContext)
+        {
+            Flow currentFlow = null;
+            if (currentFlows == null)
+            {
+                FlowHandler flowHandler = facesContext.getApplication().getFlowHandler();
+                
+                // Fill the stack with the current flows.
+                Flow curFlow = flowHandler.getCurrentFlow(facesContext);
+                // Save the top one
+                currentFlow = curFlow;
+                currentFlows = new ArrayList<Flow>();                
+                if (curFlow != null)
+                {
+                    // Fill the stack
+                    while (curFlow != null)
+                    {
+                        currentFlows.add(0,curFlow);
+                        flowHandler.pushReturnMode(facesContext);
+                        curFlow = flowHandler.getCurrentFlow(facesContext);
+                    }
+                
+                    for (int i = 0; i < currentFlows.size(); i++)
+                    {
+                        flowHandler.popReturnMode(facesContext);
+                    }
+                }
+            }
+            if (currentFlow != null)
+            {
+                return currentFlow;
+            }
+            else if (currentFlows != null && !currentFlows.isEmpty())
+            {
+                return currentFlows.get(currentFlows.size()-1);
+            }
+            else
+            {
+                return null;
+            }
+        }
+        
+        public void popFlow(FacesContext facesContext)
+        {
+            if (currentFlows.size() > 0)
+            {
+                currentFlows.remove(currentFlows.size()-1);
+            }
+        }
+        
+        public void pushFlow(FacesContext facesContext, Flow flow)
+        {
+            currentFlows.add(flow);
+        }
+    }
 }

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_FlowNavigationStructure.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_FlowNavigationStructure.java?rev=1507846&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_FlowNavigationStructure.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_FlowNavigationStructure.java Sun Jul 28 21:10:08 2013
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.application;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.faces.application.NavigationCase;
+
+/**
+ * This class contains the navigation structure of a flow, including
+ * navigation rules.
+ * 
+ * @author Leonardo Uribe
+ */
+class _FlowNavigationStructure
+{
+    private String _definingDocumentId;
+    private String _id;
+    
+    private Map<String, Set<NavigationCase>> _navigationCases = null;
+    private List<_WildcardPattern> _wildcardKeys = new ArrayList<_WildcardPattern>();
+
+    public _FlowNavigationStructure(String definingDocumentId, String id, 
+        Map<String, Set<NavigationCase>> navigationCases, List<_WildcardPattern> wildcardKeys)
+    {
+        this._definingDocumentId = definingDocumentId;
+        this._id = id;
+        this._navigationCases = navigationCases;
+        this._wildcardKeys = wildcardKeys;
+    }
+
+    public String getDefiningDocumentId()
+    {
+        return _definingDocumentId;
+    }
+
+    public String getId()
+    {
+        return _id;
+    }
+
+    public Map<String, Set<NavigationCase>> getNavigationCases()
+    {
+        return _navigationCases;
+    }
+
+    public List<_WildcardPattern> getWildcardKeys()
+    {
+        return _wildcardKeys;
+    }
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_FlowNavigationStructure.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_WildcardPattern.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_WildcardPattern.java?rev=1507846&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_WildcardPattern.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_WildcardPattern.java Sun Jul 28 21:10:08 2013
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.application;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+class _WildcardPattern
+{
+    private final String pattern;
+    private final boolean checkPrefix;
+    private final String prefix;
+
+    public _WildcardPattern(String pattern)
+    {
+        this.pattern = pattern;
+        if (pattern.length() > 2)
+        {
+            checkPrefix = true;
+            prefix = pattern.substring(0, pattern.length() - 1);
+        }
+        else
+        {
+            //It is a plain asterisk.
+            checkPrefix = false;
+            prefix = null;
+        }
+    }
+
+    public String getPattern()
+    {
+        return pattern;
+    }
+
+    public boolean match(String value)
+    {
+        if (checkPrefix)
+        {
+            if (value != null && value.startsWith(prefix))
+            {
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+        else
+        {
+            // Plain asterisk always match.
+            return true;
+        }
+    }
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/_WildcardPattern.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/DefaultFacesConfigurationMerger.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/DefaultFacesConfigurationMerger.java?rev=1507846&r1=1507845&r2=1507846&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/DefaultFacesConfigurationMerger.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/DefaultFacesConfigurationMerger.java Sun Jul 28 21:10:08 2013
@@ -107,6 +107,9 @@ public class DefaultFacesConfigurationMe
         appConfigResources.addAll(facesConfigProvider.
             getApplicationConfigurationResourceDocumentPopulatorFacesConfig(externalContext));
 
+        // JSF 2.2 Faces Flow
+        appConfigResources.addAll(facesConfigProvider.getFacesFlowFacesConfig(externalContext));
+        
         // apply the ordering and sorting algorithm 
         orderAndFeedArtifacts(dispenser, appConfigResources, webAppFacesConfig);
 

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/DefaultFacesConfigurationProvider.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/DefaultFacesConfigurationProvider.java?rev=1507846&r1=1507845&r2=1507846&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/DefaultFacesConfigurationProvider.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/DefaultFacesConfigurationProvider.java Sun Jul 28 21:10:08 2013
@@ -35,7 +35,9 @@ import javax.faces.context.ExternalConte
 import javax.faces.webapp.FacesServlet;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.PushbackInputStream;
 import java.io.StringReader;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.ArrayList;
@@ -59,6 +61,9 @@ import javax.xml.transform.TransformerEx
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
+import org.apache.myfaces.config.impl.digester.elements.FacesFlowDefinitionImpl;
+import org.apache.myfaces.config.impl.digester.elements.FacesFlowReturnImpl;
+import org.apache.myfaces.config.impl.digester.elements.NavigationCase;
 import org.apache.myfaces.shared.util.FastWriter;
 import org.apache.myfaces.spi.ServiceProviderFinder;
 import org.w3c.dom.DOMImplementation;
@@ -541,4 +546,178 @@ public class DefaultFacesConfigurationPr
         }
         return Collections.emptyList();
     }
+
+    @Override
+    public List<FacesConfig> getFacesFlowFacesConfig(ExternalContext ectx)
+    {
+        List<FacesConfig> configFilesList;
+        Set<String> directoryPaths = ectx.getResourcePaths("/");
+        if (directoryPaths == null)
+        {
+            return Collections.emptyList();
+        }
+        configFilesList = new ArrayList<FacesConfig>();
+        
+        List<String> contextSpecifiedList = getConfigFilesList(ectx);
+        
+        for (String dirPath : directoryPaths)
+        {
+            if (dirPath.equals("/WEB-INF/"))
+            {
+                // Look on /WEB-INF/<flow-Name>/<flowName>-flow.xml
+                Set<String> webDirectoryPaths = ectx.getResourcePaths(dirPath);
+                for (String webDirPath : webDirectoryPaths)
+                {
+                    if (webDirPath.endsWith("/") && 
+                        !webDirPath.equals("/WEB-INF/classes/"))
+                    {
+                        String flowName = webDirPath.substring(9, webDirPath.length() - 1);
+                        String filePath = webDirPath+flowName+"-flow.xml";
+                        if (!contextSpecifiedList.contains(filePath))
+                        {
+                            try
+                            {
+                                URL url = ectx.getResource(filePath);
+                                if (url != null)
+                                {
+                                    FacesConfig fc = parseFacesConfig(ectx, filePath, url);
+                                    if (fc != null)
+                                    {
+                                        configFilesList.add(fc);
+                                    }
+                                }
+                            }
+                            catch (MalformedURLException ex)
+                            {
+                            }
+                        }
+                    }
+                }
+            }
+            else if (!dirPath.startsWith("/META-INF") && dirPath.endsWith("/"))
+            {
+                // Look on /<flowName>/<flowName>-flow.xml
+                String flowName = dirPath.substring(1, dirPath.length() - 1);
+                String filePath = dirPath+flowName+"-flow.xml";
+                if (!contextSpecifiedList.contains(filePath))
+                {
+                    try
+                    {
+                        URL url = ectx.getResource(filePath);
+                        if (url != null)
+                        {
+                            FacesConfig fc = parseFacesConfig(ectx, filePath, url);
+                            if (fc != null)
+                            {
+                                configFilesList.add(fc);
+                            }
+                        }
+                    }
+                    catch (MalformedURLException ex)
+                    {
+                    }
+                }
+            }
+        }
+        
+        return configFilesList;
+    }
+    
+    private FacesConfig parseFacesConfig(ExternalContext ectx, String systemId, URL url)
+    {
+        try
+        {
+            if (MyfacesConfig.getCurrentInstance(ectx).isValidateXML())
+            {
+                //URL url = ectx.getResource(systemId);
+                //if (url != null)
+                //{
+                    validateFacesConfig(ectx, url);
+                //}
+            }            
+        }
+        catch (IOException e)
+        {
+            throw new FacesException(e);
+        }
+        catch (SAXException e)
+        {
+            throw new FacesException(e);
+        }
+        InputStream stream = ectx.getResourceAsStream(systemId);
+        PushbackInputStream pbstream = new PushbackInputStream(stream, 10);
+        try
+        {
+            if (stream == null)
+            {
+                log.severe("Faces config resource " + systemId + " not found");
+                return null;
+            }
+            int c = pbstream.read();
+            if (c != -1)
+            {
+                pbstream.unread(c);
+            }
+            else
+            {
+                // Zero lenght, if that so the flow definition must be implicitly derived. 
+                // See JSF 2.2 section 11.4.3.3
+                // 
+                FacesConfig facesConfig = new org.apache.myfaces.config.impl.digester.elements.FacesConfig();
+                FacesFlowDefinitionImpl flow = new FacesFlowDefinitionImpl();
+                String flowName = systemId.substring(systemId.lastIndexOf('/')+1, systemId.lastIndexOf("-flow.xml"));
+                flow.setId(flowName);
+                // In this case the defining document id is implicit associated
+                flow.setDefiningDocumentId(systemId);
+                
+                String startNodePath = systemId.substring(0, systemId.lastIndexOf('/')+1)+flowName+".xhtml";
+                URL startNodeUrl = ectx.getResource(startNodePath);
+                if (startNodeUrl != null)
+                {
+                    flow.setStartNode(startNodePath);
+                }
+                
+                // There is a default return node with name [flow-name]-return and 
+                // that by default points to an outer /[flow-name]-return outcome
+                FacesFlowReturnImpl returnNode = new FacesFlowReturnImpl();
+                returnNode.setId(flowName+"-return");
+                NavigationCase returnNavCase = new NavigationCase();
+                returnNavCase.setFromOutcome("/"+flowName+"-return");
+                returnNode.setNavigationCase(returnNavCase);
+                flow.addReturn(returnNode);
+                
+                facesConfig.getFacesFlowDefinitions().add(flow);
+                return facesConfig;
+            }
+
+            if (log.isLoggable(Level.INFO))
+            {
+                log.info("Reading config " + systemId);
+            }
+            return getUnmarshaller(ectx).getFacesConfig(pbstream, systemId);
+            //getDispenser().feed(getUnmarshaller().getFacesConfig(stream, systemId));
+        }
+        catch (IOException e)
+        {
+            throw new FacesException(e);
+        }
+        catch (SAXException e)
+        {
+            throw new FacesException(e);
+        }
+        finally
+        {
+            if (stream != null)
+            {
+                try
+                {
+                    stream.close();
+                }
+                catch (IOException ex)
+                {
+                    // No op
+                }
+            }
+        }
+    }
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java?rev=1507846&r1=1507845&r2=1507846&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java Sun Jul 28 21:10:08 2013
@@ -61,6 +61,7 @@ import javax.faces.event.PreDestroyViewM
 import javax.faces.event.SystemEvent;
 import javax.faces.flow.FlowHandler;
 import javax.faces.flow.FlowHandlerFactory;
+import javax.faces.lifecycle.ClientWindow;
 import javax.faces.lifecycle.Lifecycle;
 import javax.faces.lifecycle.LifecycleFactory;
 import javax.faces.render.RenderKit;
@@ -85,6 +86,7 @@ import org.apache.myfaces.config.element
 import org.apache.myfaces.config.element.FacesFlowCall;
 import org.apache.myfaces.config.element.FacesFlowDefinition;
 import org.apache.myfaces.config.element.FacesFlowMethodCall;
+import org.apache.myfaces.config.element.FacesFlowMethodParameter;
 import org.apache.myfaces.config.element.FacesFlowParameter;
 import org.apache.myfaces.config.element.FacesFlowReturn;
 import org.apache.myfaces.config.element.FacesFlowSwitch;
@@ -116,6 +118,7 @@ import org.apache.myfaces.flow.ReturnNod
 import org.apache.myfaces.flow.SwitchCaseImpl;
 import org.apache.myfaces.flow.SwitchNodeImpl;
 import org.apache.myfaces.flow.ViewNodeImpl;
+import org.apache.myfaces.flow.cdi.AnnotatedFlowConfigurator;
 import org.apache.myfaces.lifecycle.LifecycleFactoryImpl;
 import org.apache.myfaces.renderkit.RenderKitFactoryImpl;
 import org.apache.myfaces.renderkit.html.HtmlRenderKitImpl;
@@ -124,6 +127,7 @@ import org.apache.myfaces.shared.util.Cl
 import org.apache.myfaces.shared.util.LocaleUtils;
 import org.apache.myfaces.shared.util.StateUtils;
 import org.apache.myfaces.shared.util.StringUtils;
+import org.apache.myfaces.shared.util.WebConfigParamUtils;
 import org.apache.myfaces.shared_impl.util.serial.DefaultSerialFactory;
 import org.apache.myfaces.shared_impl.util.serial.SerialFactory;
 import org.apache.myfaces.spi.FacesConfigurationMerger;
@@ -173,6 +177,12 @@ public class FacesConfigurator
     private static final String DEFAULT_CLIENT_WINDOW_FACTORY = ClientWindowFactoryImpl.class.getName();
     private static final String DEFAULT_FLOW_FACTORY = FlowHandlerFactoryImpl.class.getName();
     private static final String DEFAULT_FACES_CONFIG = "/WEB-INF/faces-config.xml";
+    
+    /**
+     * Set this attribute if the current configuration requires enable window mode
+     */
+    public static final String ENABLE_DEFAULT_WINDOW_MODE = 
+        "org.apache.myfaces.ENABLE_DEFAULT_WINDOW_MODE";
 
     private final ExternalContext _externalContext;
     private FacesConfigUnmarshaller<? extends FacesConfig> _unmarshaller;
@@ -1190,6 +1200,12 @@ public class FacesConfigurator
         
         FacesConfigData dispenser = getDispenser();
         
+        if (!dispenser.getFacesFlowDefinitions().isEmpty())
+        {
+            // Faces Flow require client window enabled to work.
+            FacesConfigurator.enableDefaultWindowMode(facesContext);
+        }
+        
         for (FacesFlowDefinition flowDefinition : dispenser.getFacesFlowDefinitions())
         {
             FlowImpl flow = new FlowImpl();
@@ -1214,7 +1230,11 @@ public class FacesConfigurator
             for (FacesFlowCall call : flowDefinition.getFlowCallList())
             {
                 FlowCallNodeImpl node = new FlowCallNodeImpl(call.getId());
-                node.setCalledFlowId(call.getCalledFlowId());
+                if (call.getFlowReference() != null)
+                {
+                    node.setCalledFlowId(call.getFlowReference().getFlowId());
+                    node.setCalledFlowDocumentId(call.getFlowReference().getFlowDocumentId());
+                }
 
                 for (FacesFlowParameter parameter : call.getOutboundParameterList())
                 {
@@ -1241,10 +1261,10 @@ public class FacesConfigurator
                         application.getExpressionFactory().createValueExpression(
                                 facesContext.getELContext(), methodCall.getDefaultOutcome(), Object.class));
                 }
-                for (FacesFlowParameter parameter : methodCall.getParameterList())
+                for (FacesFlowMethodParameter parameter : methodCall.getParameterList())
                 {
                     node.addParameter(
-                        new ParameterImpl(parameter.getName(),
+                        new ParameterImpl(parameter.getClassName(),
                         application.getExpressionFactory().createValueExpression(
                             facesContext.getELContext(), parameter.getValue(), Object.class)) );
                 }
@@ -1334,9 +1354,40 @@ public class FacesConfigurator
             // navigation system.
             application.getFlowHandler().addFlow(facesContext, flow);
         }
+        
+        AnnotatedFlowConfigurator.configureAnnotatedFlows(facesContext);
     }
     
-
+    public static void enableDefaultWindowMode(FacesContext facesContext)
+    {
+        if (!isEnableDefaultWindowMode(facesContext))
+        {
+            String windowMode = WebConfigParamUtils.getStringInitParameter(
+                    facesContext.getExternalContext(), 
+                    ClientWindow.CLIENT_WINDOW_MODE_PARAM_NAME, null);
+            
+            if (windowMode == null)
+            {
+                //No window mode set, force window mode to url
+                String defaultWindowMode = WebConfigParamUtils.getStringInitParameter(
+                    facesContext.getExternalContext(), 
+                    ClientWindowFactoryImpl.INIT_PARAM_DEFAULT_WINDOW_MODE, 
+                    ClientWindowFactoryImpl.WINDOW_MODE_URL);
+                
+                log.info("The current configuration requires client window enabled, setting it to '"+
+                    defaultWindowMode+"'");
+                
+                facesContext.getExternalContext().getApplicationMap().put(
+                    ENABLE_DEFAULT_WINDOW_MODE, Boolean.TRUE);
+            }
+        }
+    }
+    
+    public static boolean isEnableDefaultWindowMode(FacesContext facesContext)
+    {
+        return Boolean.TRUE.equals(facesContext.getExternalContext().
+            getApplicationMap().get(ENABLE_DEFAULT_WINDOW_MODE));
+    }
     
     private boolean isEmptyString(String value)
     {

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesFlowCall.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesFlowCall.java?rev=1507846&r1=1507845&r2=1507846&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesFlowCall.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesFlowCall.java Sun Jul 28 21:10:08 2013
@@ -29,7 +29,7 @@ public abstract class FacesFlowCall impl
 {
     public abstract String getId();
     
-    public abstract String getCalledFlowId();
+    public abstract FacesFlowReference getFlowReference();
     
     public abstract List<FacesFlowParameter> getOutboundParameterList();
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesFlowMethodCall.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesFlowMethodCall.java?rev=1507846&r1=1507845&r2=1507846&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesFlowMethodCall.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesFlowMethodCall.java Sun Jul 28 21:10:08 2013
@@ -33,6 +33,6 @@ public abstract class FacesFlowMethodCal
     
     public abstract String getDefaultOutcome();
     
-    public abstract List<FacesFlowParameter> getParameterList();
+    public abstract List<FacesFlowMethodParameter> getParameterList();
     
 }

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesFlowReference.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesFlowReference.java?rev=1507846&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesFlowReference.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesFlowReference.java Sun Jul 28 21:10:08 2013
@@ -0,0 +1,34 @@
+/*
+ * 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.config.element;
+
+import java.io.Serializable;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+public abstract class FacesFlowReference implements Serializable
+{
+    
+    public abstract String getFlowId();
+    
+    public abstract String getFlowDocumentId();
+    
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/element/FacesFlowReference.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/DigesterFacesConfigUnmarshallerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/DigesterFacesConfigUnmarshallerImpl.java?rev=1507846&r1=1507845&r2=1507846&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/DigesterFacesConfigUnmarshallerImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/DigesterFacesConfigUnmarshallerImpl.java Sun Jul 28 21:10:08 2013
@@ -255,7 +255,15 @@ public class DigesterFacesConfigUnmarsha
         digester.addSetNext("faces-config/navigation-rule/navigation-case/redirect/view-param", "addViewParam");
         digester.addCallMethod("faces-config/navigation-rule/navigation-case/redirect/view-param/name", "setName",0);
         digester.addCallMethod("faces-config/navigation-rule/navigation-case/redirect/view-param/value", "setValue",0);
-        
+
+        digester.addObjectCreate("faces-config/navigation-rule/navigation-case/redirect/redirect-param", 
+            ViewParam.class);
+        digester.addSetNext("faces-config/navigation-rule/navigation-case/redirect/redirect-param", 
+            "addViewParam");
+        digester.addCallMethod("faces-config/navigation-rule/navigation-case/redirect/redirect-param/name", 
+            "setName",0);
+        digester.addCallMethod("faces-config/navigation-rule/navigation-case/redirect/redirect-param/value", 
+            "setValue",0);
 
         digester.addObjectCreate("faces-config/render-kit", RenderKit.class);
         digester.addSetNext("faces-config/render-kit", "addRenderKit");
@@ -351,6 +359,11 @@ public class DigesterFacesConfigUnmarsha
         digester.addSetNext(prefix+"/redirect/view-param", "addViewParam");
         digester.addCallMethod(prefix+"/redirect/view-param/name", "setName",0);
         digester.addCallMethod(prefix+"/redirect/view-param/value", "setValue",0);
+
+        digester.addObjectCreate(prefix+"/redirect/redirect-param", ViewParam.class);
+        digester.addSetNext(prefix+"/redirect/redirect-param", "addViewParam");
+        digester.addCallMethod(prefix+"/redirect/redirect-param/name", "setName",0);
+        digester.addCallMethod(prefix+"/redirect/redirect-param/value", "setValue",0);
     }
     
     private void addFacesFlowRules(ExternalContext externalContext)
@@ -377,20 +390,20 @@ public class DigesterFacesConfigUnmarsha
             NavigationCase.class);
         digester.addSetNext("faces-config/flow-definition/switch/default-outcome", 
             "setDefaultOutcome");
-        digester.addCallMethod("faces-config/flow-definition/switch/default-outcome/from-outcome", 
+        digester.addCallMethod("faces-config/flow-definition/switch/default-outcome", 
             "setFromOutcome", 0);
         
-        addNavigationCases(externalContext, "faces-config/flow-definition/switch/navigation-case",
+        addNavigationCases(externalContext, "faces-config/flow-definition/switch/case",
             "addNavigationCase");
         
         digester.addObjectCreate("faces-config/flow-definition/flow-return", FacesFlowReturnImpl.class);
         digester.addSetNext("faces-config/flow-definition/flow-return", "addReturn");
         digester.addSetProperties("faces-config/flow-definition/flow-return", "id", "id");
-        digester.addObjectCreate("faces-config/flow-definition/flow-return/navigation-case", 
+        digester.addObjectCreate("faces-config/flow-definition/flow-return/from-outcome", 
             NavigationCase.class);
-        digester.addSetNext("faces-config/flow-definition/flow-return/navigation-case", 
+        digester.addSetNext("faces-config/flow-definition/flow-return/from-outcome", 
             "setNavigationCase");
-        digester.addCallMethod("faces-config/flow-definition/flow-return/navigation-case/from-outcome", 
+        digester.addCallMethod("faces-config/flow-definition/flow-return/from-outcome", 
             "setFromOutcome", 0);
         
         addNavigationRules(externalContext, "faces-config/flow-definition/navigation-rule", "addNavigationRule");
@@ -398,9 +411,12 @@ public class DigesterFacesConfigUnmarsha
         digester.addObjectCreate("faces-config/flow-definition/flow-call", FacesFlowCallImpl.class);
         digester.addSetNext("faces-config/flow-definition/flow-call", "addFlowCall");
         digester.addSetProperties("faces-config/flow-definition/flow-call", "id", "id");
-        digester.addCallMethod(
-            "faces-config/flow-definition/flow-call/faces-flow-reference/faces-flow-id", 
-            "setCalledFlowId", 0);
+        digester.addObjectCreate("faces-config/flow-definition/flow-call/flow-reference", FacesFlowReferenceImpl.class);
+        digester.addSetNext("faces-config/flow-definition/flow-call/flow-reference", "setFlowReference");        
+        digester.addCallMethod("faces-config/flow-definition/flow-call/flow-reference/flow-document-id", 
+                "setFlowDocumentId", 0);
+        digester.addCallMethod("faces-config/flow-definition/flow-call/flow-reference/flow-id", "setFlowId", 0);
+        
         digester.addObjectCreate("faces-config/flow-definition/flow-call/outbound-parameter", 
             FacesFlowParameterImpl.class);
         digester.addSetNext("faces-config/flow-definition/flow-call/outbound-parameter", 
@@ -410,8 +426,8 @@ public class DigesterFacesConfigUnmarsha
         
         digester.addObjectCreate("faces-config/flow-definition/method-call", FacesFlowMethodCallImpl.class);
         digester.addSetNext("faces-config/flow-definition/method-call", "addMethodCall");
+        digester.addSetProperties("faces-config/flow-definition/method-call", "id", "id");
         digester.addCallMethod("faces-config/flow-definition/method-call/method", "setMethod", 0);
-        digester.addSetProperties("faces-config/flow-definition/method-call/method", "id", "id");
         digester.addCallMethod("faces-config/flow-definition/method-call/default-outcome", 
             "setDefaultOutcome", 0);
         digester.addObjectCreate("faces-config/flow-definition/method-call/parameter", 

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesFlowCallImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesFlowCallImpl.java?rev=1507846&r1=1507845&r2=1507846&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesFlowCallImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesFlowCallImpl.java Sun Jul 28 21:10:08 2013
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.List;
 import org.apache.myfaces.config.element.FacesFlowCall;
 import org.apache.myfaces.config.element.FacesFlowParameter;
+import org.apache.myfaces.config.element.FacesFlowReference;
 
 /**
  *
@@ -29,7 +30,7 @@ import org.apache.myfaces.config.element
  */
 public class FacesFlowCallImpl extends FacesFlowCall
 {
-    private String _calledFlowId;
+    private FacesFlowReference _flowReference;
     private List<FacesFlowParameter> _outboundParameterList;
     private String _id;
 
@@ -37,12 +38,6 @@ public class FacesFlowCallImpl extends F
     {
         _outboundParameterList = new ArrayList<FacesFlowParameter>();
     }
-    
-    @Override
-    public String getCalledFlowId()
-    {
-        return _calledFlowId;
-    }
 
     @Override
     public List<FacesFlowParameter> getOutboundParameterList()
@@ -55,14 +50,6 @@ public class FacesFlowCallImpl extends F
         _outboundParameterList.add(parameter);
     }
 
-    /**
-     * @param calledFlowId the calledFlowId to set
-     */
-    public void setCalledFlowId(String calledFlowId)
-    {
-        this._calledFlowId = calledFlowId;
-    }
-
     @Override
     public String getId()
     {
@@ -73,5 +60,16 @@ public class FacesFlowCallImpl extends F
     {
         this._id = id;
     }
-    
+
+    @Override
+    public FacesFlowReference getFlowReference()
+    {
+        return _flowReference;
+    }
+
+    public void setFlowReference(FacesFlowReference flowReference)
+    {
+        this._flowReference = flowReference;
+    }
+
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesFlowMethodCallImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesFlowMethodCallImpl.java?rev=1507846&r1=1507845&r2=1507846&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesFlowMethodCallImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesFlowMethodCallImpl.java Sun Jul 28 21:10:08 2013
@@ -20,7 +20,7 @@ package org.apache.myfaces.config.impl.d
 
 import java.util.ArrayList;
 import java.util.List;
-import org.apache.myfaces.config.element.FacesFlowParameter;
+import org.apache.myfaces.config.element.FacesFlowMethodParameter;
 
 /**
  *
@@ -32,11 +32,11 @@ public class FacesFlowMethodCallImpl ext
     private String _method;
     private String _defaultOutcome;
     
-    private List<FacesFlowParameter> _parameterList;
+    private List<FacesFlowMethodParameter> _parameterList;
     
     public FacesFlowMethodCallImpl()
     {
-        _parameterList = new ArrayList<FacesFlowParameter>();
+        _parameterList = new ArrayList<FacesFlowMethodParameter>();
     }
 
     @Override
@@ -79,12 +79,12 @@ public class FacesFlowMethodCallImpl ext
     }
 
     @Override
-    public List<FacesFlowParameter> getParameterList()
+    public List<FacesFlowMethodParameter> getParameterList()
     {
         return _parameterList;
     }
     
-    public void addParameter(FacesFlowParameter parameter)
+    public void addParameter(FacesFlowMethodParameter parameter)
     {
         _parameterList.add(parameter);
     }

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesFlowReferenceImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesFlowReferenceImpl.java?rev=1507846&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesFlowReferenceImpl.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesFlowReferenceImpl.java Sun Jul 28 21:10:08 2013
@@ -0,0 +1,61 @@
+/*
+ * 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.config.impl.digester.elements;
+
+import org.apache.myfaces.config.element.FacesFlowReference;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+public class FacesFlowReferenceImpl extends FacesFlowReference
+{
+    
+    private String _flowId;
+    
+    private String _flowDocumentId;
+
+    public FacesFlowReferenceImpl()
+    {
+        
+    }
+
+    @Override
+    public String getFlowId()
+    {
+        return _flowId;
+    }
+
+    public void setFlowId(String flowId)
+    {
+        this._flowId = flowId;
+    }
+
+    @Override
+    public String getFlowDocumentId()
+    {
+        return _flowDocumentId;
+    }
+
+    public void setFlowDocumentId(String flowDocumentId)
+    {
+        this._flowDocumentId = flowDocumentId;
+    }
+    
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/impl/digester/elements/FacesFlowReferenceImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/implicitobject/FlowScopeImplicitObject.java (from r1505853, myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/implicitobject/SessionScopeImplicitObject.java)
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/implicitobject/FlowScopeImplicitObject.java?p2=myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/implicitobject/FlowScopeImplicitObject.java&p1=myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/implicitobject/SessionScopeImplicitObject.java&r1=1505853&r2=1507846&rev=1507846&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/implicitobject/SessionScopeImplicitObject.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/implicitobject/FlowScopeImplicitObject.java Sun Jul 28 21:10:08 2013
@@ -21,26 +21,28 @@ package org.apache.myfaces.el.unified.re
 import javax.el.ELContext;
 import java.beans.FeatureDescriptor;
 import java.util.Map;
+import javax.faces.context.FacesContext;
 
 /**
  * Encapsulates information needed by the ImplicitObjectResolver
  * 
- * @author Stan Silvert
+ * @author Leonardo Uribe
  */
-public class SessionScopeImplicitObject extends ImplicitObject
+public class FlowScopeImplicitObject extends ImplicitObject
 {
 
-    private static final String NAME = "sessionScope";
+    private static final String NAME = "flowScope";
 
-    /** Creates a new instance of SessionScopeImplicitObject */
-    public SessionScopeImplicitObject()
+    /** Creates a new instance of FlowScopeImplicitObject */
+    public FlowScopeImplicitObject()
     {
     }
 
     @Override
     public Object getValue(ELContext context)
     {
-        return externalContext(context).getSessionMap();
+        FacesContext facesContext = facesContext(context);
+        return facesContext.getApplication().getFlowHandler().getCurrentFlowScope();
     }
 
     @Override
@@ -58,7 +60,7 @@ public class SessionScopeImplicitObject 
     @Override
     public FeatureDescriptor getDescriptor()
     {
-        return makeDescriptor(NAME, "Session scope attributes", Map.class);
+        return makeDescriptor(NAME, "Flow scope attributes", Map.class);
     }
 
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/implicitobject/ImplicitObjectResolver.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/implicitobject/ImplicitObjectResolver.java?rev=1507846&r1=1507845&r2=1507846&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/implicitobject/ImplicitObjectResolver.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/el/unified/resolver/implicitobject/ImplicitObjectResolver.java Sun Jul 28 21:10:08 2013
@@ -96,6 +96,8 @@ public class ImplicitObjectResolver exte
         forFacesList.put(io17.getName(), io17);
         ImplicitObject io18 = new CompositeComponentImplicitObject();
         forFacesList.put(io18.getName(), io18);
+        ImplicitObject io19 = new FlowScopeImplicitObject();
+        forFacesList.put(io19.getName(), io19);
         return new ImplicitObjectResolver(forFacesList);
     }
 

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/FlowCallNodeImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/FlowCallNodeImpl.java?rev=1507846&r1=1507845&r2=1507846&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/FlowCallNodeImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/FlowCallNodeImpl.java Sun Jul 28 21:10:08 2013
@@ -40,7 +40,7 @@ public class FlowCallNodeImpl extends Fl
     private ValueExpression _calledFlowDocumentIdEL;
     
     private Map<String, Parameter> _outboundParametersMap;
-    private Map<String, Parameter>_unmodifiableOutboundParametersMap;
+    private Map<String, Parameter> _unmodifiableOutboundParametersMap;
     
     private boolean _initialized;