You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by jd...@apache.org on 2007/05/26 23:06:13 UTC

svn commit: r541938 [2/2] - in /maven/components/trunk: ./ maven-core/ maven-core/src/main/java/org/apache/maven/lifecycle/ maven-core/src/main/java/org/apache/maven/lifecycle/binding/ maven-core/src/main/java/org/apache/maven/lifecycle/plan/ maven-cor...

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/plan/DefaultBuildPlanner.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/plan/DefaultBuildPlanner.java?view=diff&rev=541938&r1=541937&r2=541938
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/plan/DefaultBuildPlanner.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/plan/DefaultBuildPlanner.java Sat May 26 14:06:12 2007
@@ -8,7 +8,6 @@
 import org.apache.maven.lifecycle.binding.MojoBindingFactory;
 import org.apache.maven.lifecycle.model.LifecycleBindings;
 import org.apache.maven.lifecycle.model.MojoBinding;
-import org.apache.maven.lifecycle.model.Phase;
 import org.apache.maven.plugin.descriptor.MojoDescriptor;
 import org.apache.maven.plugin.descriptor.PluginDescriptor;
 import org.apache.maven.plugin.loader.PluginLoader;
@@ -17,21 +16,20 @@
 import org.codehaus.plexus.logging.LogEnabled;
 import org.codehaus.plexus.logging.Logger;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Stack;
 
 /**
- * Responsible for creating a plan of execution for a given project and list of tasks. This build plan
- * consists of MojoBinding instances that carry all the information necessary to execute a mojo,
- * including configuration from the POM and other sources. NOTE: the build plan may be constructed
- * of a main lifecycle binding-set, plus any number of lifecycle modifiers and direct-invocation
- * modifiers, to handle cases of forked execution.
+ * Responsible for creating a plan of execution for a given project and list of tasks. This build plan consists of
+ * MojoBinding instances that carry all the information necessary to execute a mojo, including configuration from the
+ * POM and other sources. NOTE: the build plan may be constructed of a main lifecycle binding-set, plus any number of
+ * lifecycle modifiers and direct-invocation modifiers, to handle cases of forked execution.
  * 
  * @author jdcasey
- *
+ * 
  */
 public class DefaultBuildPlanner
     implements BuildPlanner, LogEnabled
@@ -48,159 +46,177 @@
     /**
      * Orchestrates construction of the build plan which will be used by the user of LifecycleExecutor.
      */
-    public BuildPlan constructBuildPlan( List tasks, MavenProject project )
+    public BuildPlan constructBuildPlan( final List tasks, final MavenProject project )
         throws LifecycleLoaderException, LifecycleSpecificationException, LifecyclePlannerException
     {
         LifecycleBindings defaultBindings = lifecycleBindingManager.getDefaultBindings( project );
         LifecycleBindings packagingBindings = lifecycleBindingManager.getBindingsForPackaging( project );
         LifecycleBindings projectBindings = lifecycleBindingManager.getProjectCustomBindings( project );
 
-        LifecycleBindings merged = LifecycleUtils.mergeBindings( packagingBindings, projectBindings, defaultBindings, true, false );
+        BuildPlan plan = new BuildPlan( packagingBindings, projectBindings, defaultBindings, tasks );
 
-        // foreach task, find the binding list from the merged lifecycle-bindings.
-        // if the binding list is a super-set of a previous task, forget the previous task/binding
-        //     list, and use the new one.
-        // if the binding list is null, treat it like a one-off mojo invocation, and parse/validate
-        //     that it can be called as such.
-        // as binding lists accumulate, push them onto an aggregated "plan" listing...
-        BuildPlan plan = new LifecycleBuildPlan( tasks, merged );
+        initializeDirectInvocations( plan, project );
 
         // Inject forked lifecycles as plan modifiers for each mojo that has @execute in it.
-        addForkedLifecycleModifiers( plan, merged, project, tasks );
-        addReportingLifecycleModifiers( plan, merged, project, tasks );
+        addForkedLifecycleModifiers( plan, project );
+        addReportingLifecycleModifiers( plan, project );
 
         // TODO: Inject relative-ordered project/plugin executions as plan modifiers.
 
         return plan;
     }
 
-    public void enableLogging( Logger logger )
+    private void initializeDirectInvocations( final BuildPlan plan, final MavenProject project )
+        throws LifecycleSpecificationException, LifecycleLoaderException
+    {
+        List tasks = plan.getTasks();
+        for ( Iterator it = tasks.iterator(); it.hasNext(); )
+        {
+            String task = (String) it.next();
+
+            if ( !LifecycleUtils.isValidPhaseName( task ) )
+            {
+                MojoBinding binding = mojoBindingFactory.parseMojoBinding( task, project, true );
+                plan.addDirectInvocationBinding( task, binding );
+            }
+        }
+    }
+
+    public void enableLogging( final Logger logger )
     {
         this.logger = logger;
     }
 
     /**
-     * Traverses all MojoBinding instances discovered from the POM and its packaging-mappings, and
-     * orchestrates the process of injecting any modifiers that are necessary to accommodate forked
-     * execution.
+     * Traverses all MojoBinding instances discovered from the POM and its packaging-mappings, and orchestrates the
+     * process of injecting any modifiers that are necessary to accommodate forked execution.
      */
-    private void addForkedLifecycleModifiers( ModifiablePlanElement planElement, LifecycleBindings lifecycleBindings,
-                                              MavenProject project, List tasks )
+    private void addForkedLifecycleModifiers( final BuildPlan plan, final MavenProject project )
         throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException
     {
-        List planBindings = lifecycleBindingManager.assembleMojoBindingList( tasks, lifecycleBindings, project );
+        List planBindings = plan.renderExecutionPlan( new Stack() );
+        plan.resetExecutionProgress();
 
         for ( Iterator it = planBindings.iterator(); it.hasNext(); )
         {
             MojoBinding mojoBinding = (MojoBinding) it.next();
 
-            findForkModifiers( mojoBinding, planElement, lifecycleBindings, project );
+            findForkModifiers( mojoBinding, plan, project );
         }
     }
 
-    private void findForkModifiers( MojoBinding mojoBinding, ModifiablePlanElement planElement,
-                                    LifecycleBindings lifecycleBindings, MavenProject project )
+    private void findForkModifiers( final MojoBinding mojoBinding, final BuildPlan plan, final MavenProject project )
         throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException
     {
-        PluginDescriptor pluginDescriptor;
+        PluginDescriptor pluginDescriptor = null;
         try
         {
             pluginDescriptor = pluginLoader.loadPlugin( mojoBinding, project );
         }
         catch ( PluginLoaderException e )
         {
-            throw new LifecyclePlannerException( e.getMessage(), e );
+            String message =
+                "Failed to load plugin: " + MojoBindingUtils.createPluginKey( mojoBinding )
+                                + ". Adding to late-bound plugins list.\nReason: " + e.getMessage();
+
+            if ( logger.isDebugEnabled() )
+            {
+                logger.debug( message, e );
+            }
+            else
+            {
+                logger.warn( message );
+            }
+
+            plan.addLateBoundMojo( mojoBinding );
+        }
+
+        if ( pluginDescriptor == null )
+        {
+            return;
         }
 
         MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( mojoBinding.getGoal() );
         if ( mojoDescriptor == null )
         {
             throw new LifecyclePlannerException( "Mojo: " + mojoBinding.getGoal() + " does not exist in plugin: "
-                + pluginDescriptor.getId() + "." );
+                                                 + pluginDescriptor.getId() + "." );
         }
 
-        findForkModifiers( mojoBinding, pluginDescriptor, planElement, lifecycleBindings, project, new LinkedList() );
+        findForkModifiers( mojoBinding, pluginDescriptor, plan, project );
     }
 
     /**
-     * Traverses all MojoBinding instances discovered from the POM and its packaging-mappings, and
-     * orchestrates the process of injecting any modifiers that are necessary to accommodate mojos
-     * that require access to the project's configured reports.
+     * Traverses all MojoBinding instances discovered from the POM and its packaging-mappings, and orchestrates the
+     * process of injecting any modifiers that are necessary to accommodate mojos that require access to the project's
+     * configured reports.
      */
-    private void addReportingLifecycleModifiers( ModifiablePlanElement planElement, LifecycleBindings lifecycleBindings,
-                                                 MavenProject project, List tasks )
+    private void addReportingLifecycleModifiers( final BuildPlan plan, final MavenProject project )
         throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException
     {
-        List planBindings = lifecycleBindingManager.assembleMojoBindingList( tasks, lifecycleBindings, project );
+        List planBindings = plan.renderExecutionPlan( new Stack() );
+        plan.resetExecutionProgress();
 
         for ( Iterator it = planBindings.iterator(); it.hasNext(); )
         {
             MojoBinding mojoBinding = (MojoBinding) it.next();
 
-            PluginDescriptor pluginDescriptor;
+            PluginDescriptor pluginDescriptor = null;
             try
             {
                 pluginDescriptor = pluginLoader.loadPlugin( mojoBinding, project );
             }
             catch ( PluginLoaderException e )
             {
-                throw new LifecyclePlannerException( e.getMessage(), e );
+                String message =
+                    "Failed to load plugin: " + MojoBindingUtils.createPluginKey( mojoBinding )
+                                    + ". Adding to late-bound plugins list.\nReason: " + e.getMessage();
+
+                if ( logger.isDebugEnabled() )
+                {
+                    logger.debug( message, e );
+                }
+                else
+                {
+                    logger.warn( message );
+                }
+
+                plan.addLateBoundMojo( mojoBinding );
+            }
+
+            if ( pluginDescriptor == null )
+            {
+                continue;
             }
 
             MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( mojoBinding.getGoal() );
             if ( mojoDescriptor == null )
             {
                 throw new LifecyclePlannerException( "Mojo: " + mojoBinding.getGoal() + " does not exist in plugin: "
-                    + pluginDescriptor.getId() + "." );
+                                                     + pluginDescriptor.getId() + "." );
             }
 
             if ( mojoDescriptor.isRequiresReports() )
             {
                 List reportBindings = lifecycleBindingManager.getReportBindings( project );
 
-                // findForkModifiers( mojoBinding, pluginDescriptor, planElement, lifecycleBindings, 
-                //                    project, forkingBindings, tasks );
                 for ( Iterator reportBindingIt = reportBindings.iterator(); reportBindingIt.hasNext(); )
                 {
                     MojoBinding reportBinding = (MojoBinding) reportBindingIt.next();
-                    
-                    PluginDescriptor pd;
+
                     try
                     {
-                        pd = pluginLoader.loadReportPlugin( mojoBinding, project );
+                        pluginLoader.loadReportPlugin( mojoBinding, project );
                     }
                     catch ( PluginLoaderException e )
                     {
                         throw new LifecyclePlannerException( "Failed to load report-plugin descriptor for: "
-                            + MojoBindingUtils.toString( reportBinding ) + ". Reason: " + e.getMessage(), e );
-                    }
-
-//                    findForkModifiers( reportBinding, planElement, lifecycleBindings, project );
-                }
-
-                Phase phase = LifecycleUtils.findPhaseForMojoBinding( mojoBinding, lifecycleBindings, true );
-
-                if ( phase == null )
-                {
-                    if ( planElement instanceof DirectInvocationOriginElement )
-                    {
-                        DirectInvocationModifier modder = new SimpleDirectInvocationModifier( mojoBinding, reportBindings );
-
-                        ( (DirectInvocationOriginElement) planElement ).addDirectInvocationModifier( modder );
-                    }
-                    else
-                    {
-                        throw new LifecyclePlannerException( "Cannot inject reports for direct invocation: "
-                            + MojoBindingUtils.toString( mojoBinding )
-                            + "; current plan element does not accept direct-invocation modifiers." );
+                                                             + MojoBindingUtils.toString( reportBinding )
+                                                             + ". Reason: " + e.getMessage(), e );
                     }
                 }
-                else
-                {
-                    BuildPlanModifier modder = new ReportingPlanModifier( mojoBinding, reportBindings );
 
-                    planElement.addModifier( modder );
-                }
+                plan.addForkedExecution( mojoBinding, reportBindings );
 
                 // NOTE: the first sighting of a mojo requiring reports should satisfy this condition.
                 // therefore, we can break out as soon as we find one.
@@ -210,159 +226,38 @@
     }
 
     /**
-     * Explores a single MojoBinding, and injects any necessary plan modifiers to accommodate any
-     * of the three types of forked execution, along with any new mojos/lifecycles that entails.
+     * Explores a single MojoBinding, and injects any necessary plan modifiers to accommodate any of the three types of
+     * forked execution, along with any new mojos/lifecycles that entails.
      */
-    private void findForkModifiers( MojoBinding mojoBinding, PluginDescriptor pluginDescriptor,
-                                    ModifiablePlanElement planElement, LifecycleBindings mergedBindings, MavenProject project,
-                                    LinkedList forkingBindings )
+    private void findForkModifiers( final MojoBinding mojoBinding, final PluginDescriptor pluginDescriptor,
+                                    final BuildPlan plan, final MavenProject project )
         throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException
     {
-        forkingBindings.addLast( mojoBinding );
-
-        try
-        {
-            String referencingGoal = mojoBinding.getGoal();
-
-            MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( referencingGoal );
-
-            if ( mojoDescriptor.getExecuteGoal() != null )
-            {
-                recurseSingleMojoFork( mojoBinding, pluginDescriptor, planElement, mergedBindings, project, forkingBindings );
-            }
-            else if ( mojoDescriptor.getExecutePhase() != null )
-            {
-                recursePhaseMojoFork( mojoBinding, pluginDescriptor, planElement, mergedBindings, project, forkingBindings );
-            }
-        }
-        finally
-        {
-            forkingBindings.removeLast();
-        }
-    }
-
-    /**
-     * Handles exploration of a single-mojo forked execution for further forkings, and also performs
-     * the actual build-plan modification for that single-mojo forked execution.
-     */
-    private void modifyBuildPlanForForkedDirectInvocation( MojoBinding invokedBinding, MojoBinding invokedVia,
-                                                           PluginDescriptor pluginDescriptor, ModifiablePlanElement planElement,
-                                                           LifecycleBindings mergedBindings, MavenProject project,
-                                                           LinkedList forkingBindings )
-        throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException
-    {
-        if ( planElement instanceof DirectInvocationOriginElement )
-        {
-            List noTasks = Collections.EMPTY_LIST;
-
-            LifecycleBindings forkedBindings = new LifecycleBindings();
-            LifecycleBuildPlan forkedPlan = new LifecycleBuildPlan( noTasks, forkedBindings );
-
-            forkingBindings.addLast( invokedBinding );
-            try
-            {
-                findForkModifiers( invokedBinding, pluginDescriptor, forkedPlan, forkedBindings, project, forkingBindings );
-            }
-            finally
-            {
-                forkingBindings.removeLast();
-            }
-
-            List forkedMojos = new ArrayList();
-            forkedMojos.addAll( lifecycleBindingManager.assembleMojoBindingList( noTasks, forkedBindings, project ) );
-            forkedMojos.add( invokedBinding );
-
-            DirectInvocationModifier modifier = new ForkedDirectInvocationModifier( invokedVia, forkedMojos );
-
-            ( (DirectInvocationOriginElement) planElement ).addDirectInvocationModifier( modifier );
-        }
-        else
-        {
-            throw new LifecyclePlannerException( "Mojo: " + MojoBindingUtils.toString( invokedVia )
-                + " is not bound to the lifecycle; you cannot attach this mojo to a build-plan modifier." );
-        }
-    }
-
-    /**
-     * Handles exploration of a lifecycle-based forked execution for further forkings, and also performs
-     * the actual build-plan modification for that lifecycle-based forked execution.
-     */
-    private void modifyBuildPlanForForkedLifecycle( MojoBinding mojoBinding, PluginDescriptor pluginDescriptor,
-                                                    ModifiablePlanElement planElement, LifecycleBindings bindings,
-                                                    MavenProject project, LinkedList forkingBindings )
-        throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException
-    {
-        MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( mojoBinding.getGoal() );
-        String phase = mojoDescriptor.getExecutePhase();
-
-        List forkedPhaseBindingList = lifecycleBindingManager.assembleMojoBindingList( Collections.singletonList( phase ),
-                                                                                       bindings, project );
-
-        ModifiablePlanElement mpe;
-
-        // setup the ModifiablePlanElement, into which we'll recurse to find further modifications.
-        if ( LifecycleUtils.findPhaseForMojoBinding( mojoBinding, bindings, true ) != null )
-        {
-            mpe = new ForkPlanModifier( mojoBinding, forkedPhaseBindingList );
-        }
-        else if ( planElement instanceof BuildPlan )
-        {
-            mpe = new SubLifecycleBuildPlan( phase, bindings );
-        }
-        else
-        {
-            throw new LifecyclePlannerException( "Mojo: " + MojoBindingUtils.toString( mojoBinding )
-                + " is not bound to the lifecycle; you cannot attach this mojo to a build-plan modifier." );
-        }
-
-        // recurse, to find further modifications, using the ModifiablePlanElement from above, along
-        // with the modified task list (which doesn't contain the direct-invocation task that landed
-        // us here...
-        for ( Iterator it = forkedPhaseBindingList.iterator(); it.hasNext(); )
-        {
-            MojoBinding forkedBinding = (MojoBinding) it.next();
-
-            PluginDescriptor forkedPluginDescriptor;
-            try
-            {
-                forkedPluginDescriptor = pluginLoader.loadPlugin( forkedBinding, project );
-            }
-            catch ( PluginLoaderException e )
-            {
-                throw new LifecyclePlannerException( e.getMessage(), e );
-            }
+        String referencingGoal = mojoBinding.getGoal();
 
-            findForkModifiers( forkedBinding, forkedPluginDescriptor, mpe, bindings, project, forkingBindings );
-        }
+        MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( referencingGoal );
 
-        // now that we've discovered any deeper modifications, add the current MPE to the parent MPE
-        // in the appropriate location.
-        if ( LifecycleUtils.findPhaseForMojoBinding( mojoBinding, bindings, true ) != null )
+        if ( mojoDescriptor.getExecuteGoal() != null )
         {
-            planElement.addModifier( (BuildPlanModifier) mpe );
+            recurseSingleMojoFork( mojoBinding, pluginDescriptor, plan, project );
         }
-        else if ( planElement instanceof DirectInvocationOriginElement )
+        else if ( mojoDescriptor.getExecutePhase() != null )
         {
-            List planMojoBindings = ( (BuildPlan) mpe ).getPlanMojoBindings( project, lifecycleBindingManager );
-
-            ForkedDirectInvocationModifier modifier = new ForkedDirectInvocationModifier( mojoBinding, planMojoBindings );
-
-            ( (DirectInvocationOriginElement) planElement ).addDirectInvocationModifier( modifier );
+            recursePhaseMojoFork( mojoBinding, pluginDescriptor, plan, project );
         }
     }
 
     /**
-     * Constructs the lifecycle bindings used to execute a particular fork, given the forking mojo
-     * binding. If the mojo binding specifies a lifecycle overlay, this method will add that into
-     * the forked lifecycle, and calculate the bindings to inject based on the phase in that new
-     * lifecycle which should be executed.
+     * Constructs the lifecycle bindings used to execute a particular fork, given the forking mojo binding. If the mojo
+     * binding specifies a lifecycle overlay, this method will add that into the forked lifecycle, and calculate the
+     * bindings to inject based on the phase in that new lifecycle which should be executed.
      * 
-     * Hands off to the {@link DefaultBuildPlanner#modifyBuildPlanForForkedLifecycle(MojoBinding, PluginDescriptor, ModifiablePlanElement, LifecycleBindings, MavenProject, LinkedList, List)}
+     * Hands off to the
+     * {@link DefaultBuildPlanner#modifyBuildPlanForForkedLifecycle(MojoBinding, PluginDescriptor, ModifiablePlanElement, LifecycleBindings, MavenProject, LinkedList, List)}
      * method to handle the actual plan modification.
      */
-    private void recursePhaseMojoFork( MojoBinding mojoBinding, PluginDescriptor pluginDescriptor,
-                                       ModifiablePlanElement planElement, LifecycleBindings mergedBindings, MavenProject project,
-                                       LinkedList forkingBindings )
+    private void recursePhaseMojoFork( final MojoBinding mojoBinding, final PluginDescriptor pluginDescriptor,
+                                       final BuildPlan plan, final MavenProject project )
         throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException
     {
         String referencingGoal = mojoBinding.getGoal();
@@ -376,48 +271,44 @@
             return;
         }
 
-        if ( LifecycleUtils.findLifecycleBindingForPhase( phase, mergedBindings ) == null )
+        if ( !LifecycleUtils.isValidPhaseName( phase ) )
         {
             throw new LifecyclePlannerException( "Cannot find lifecycle for phase: " + phase );
         }
 
-        LifecycleBindings cloned;
-        if ( mojoDescriptor.getExecuteLifecycle() != null )
-        {
-            String executeLifecycle = mojoDescriptor.getExecuteLifecycle();
+        BuildPlan clonedPlan = plan.copy( Collections.singletonList( phase ) );
 
+        String executeLifecycle = mojoDescriptor.getExecuteLifecycle();
+        if ( executeLifecycle != null )
+        {
             LifecycleBindings overlayBindings;
             try
             {
-                overlayBindings = lifecycleBindingManager.getPluginLifecycleOverlay( pluginDescriptor, executeLifecycle, project );
+                overlayBindings =
+                    lifecycleBindingManager.getPluginLifecycleOverlay( pluginDescriptor, executeLifecycle, project );
             }
             catch ( LifecycleLoaderException e )
             {
-                throw new LifecyclePlannerException( "Failed to load overlay lifecycle: " + executeLifecycle + ". Reason: "
-                    + e.getMessage(), e );
+                throw new LifecyclePlannerException( "Failed to load overlay lifecycle: " + executeLifecycle
+                                                     + ". Reason: " + e.getMessage(), e );
             }
 
-            cloned = LifecycleUtils.cloneBindings( mergedBindings );
-            cloned = LifecycleUtils.mergeBindings( overlayBindings, cloned, null, true, true );
-        }
-        else
-        {
-            cloned = LifecycleUtils.cloneBindings( mergedBindings );
+            clonedPlan.addLifecycleOverlay( overlayBindings );
         }
 
-        LifecycleUtils.removeMojoBindings( forkingBindings, cloned, false );
+        plan.addForkedExecution( mojoBinding, clonedPlan );
 
-        modifyBuildPlanForForkedLifecycle( mojoBinding, pluginDescriptor, planElement, cloned, project, forkingBindings );
+        addForkedLifecycleModifiers( clonedPlan, project );
     }
 
     /**
-     * Retrieves the information necessary to create a new MojoBinding for a single-mojo forked
-     * execution, then hands off to the {@link DefaultBuildPlanner#modifyBuildPlanForForkedDirectInvocation(MojoBinding, MojoBinding, PluginDescriptor, ModifiablePlanElement, LifecycleBindings, MavenProject, LinkedList, List)}
+     * Retrieves the information necessary to create a new MojoBinding for a single-mojo forked execution, then hands
+     * off to the
+     * {@link DefaultBuildPlanner#modifyBuildPlanForForkedDirectInvocation(MojoBinding, MojoBinding, PluginDescriptor, ModifiablePlanElement, LifecycleBindings, MavenProject, LinkedList, List)}
      * method to actually inject the modification.
      */
-    private void recurseSingleMojoFork( MojoBinding mojoBinding, PluginDescriptor pluginDescriptor,
-                                        ModifiablePlanElement planElement, LifecycleBindings mergedBindings,
-                                        MavenProject project, LinkedList forkingBindings )
+    private void recurseSingleMojoFork( final MojoBinding mojoBinding, final PluginDescriptor pluginDescriptor,
+                                        final BuildPlan plan, final MavenProject project )
         throws LifecyclePlannerException, LifecycleSpecificationException, LifecycleLoaderException
     {
         String referencingGoal = mojoBinding.getGoal();
@@ -435,20 +326,16 @@
         if ( otherDescriptor == null )
         {
             throw new LifecyclePlannerException( "Mojo: " + executeGoal + " (referenced by: " + referencingGoal
-                + ") does not exist in plugin: " + pluginDescriptor.getId() + "." );
+                                                 + ") does not exist in plugin: " + pluginDescriptor.getId() + "." );
         }
 
-        MojoBinding binding = mojoBindingFactory.createMojoBinding( pluginDescriptor.getGroupId(),
-                                                                    pluginDescriptor.getArtifactId(),
-                                                                    pluginDescriptor.getVersion(), executeGoal, project );
+        MojoBinding binding =
+            mojoBindingFactory.createMojoBinding( pluginDescriptor.getGroupId(), pluginDescriptor.getArtifactId(),
+                                                  pluginDescriptor.getVersion(), executeGoal, project );
 
         binding.setOrigin( "Forked from " + referencingGoal );
 
-        if ( !LifecycleUtils.isMojoBindingPresent( binding, forkingBindings, false ) )
-        {
-            modifyBuildPlanForForkedDirectInvocation( binding, mojoBinding, pluginDescriptor, planElement, mergedBindings,
-                                                      project, forkingBindings );
-        }
+        plan.addForkedExecution( mojoBinding, Collections.singletonList( binding ) );
     }
 
 }

Added: maven/components/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/statemgmt/ResolveLateBoundPluginMojo.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/statemgmt/ResolveLateBoundPluginMojo.java?view=auto&rev=541938
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/statemgmt/ResolveLateBoundPluginMojo.java (added)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/statemgmt/ResolveLateBoundPluginMojo.java Sat May 26 14:06:12 2007
@@ -0,0 +1,57 @@
+package org.apache.maven.lifecycle.statemgmt;
+
+import org.apache.maven.lifecycle.MojoBindingUtils;
+import org.apache.maven.lifecycle.binding.MojoBindingFactory;
+import org.apache.maven.lifecycle.model.MojoBinding;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.plugin.loader.PluginLoader;
+import org.apache.maven.plugin.loader.PluginLoaderException;
+import org.apache.maven.project.MavenProject;
+
+public class ResolveLateBoundPluginMojo extends AbstractMojo
+{
+
+    /**
+     * @component
+     */
+    private PluginLoader pluginLoader;
+
+    private String groupId;
+
+    private String artifactId;
+
+    private String version;
+
+    private String goal;
+
+    private MavenProject project;
+
+    private MojoBindingFactory bindingFactory;
+
+    public void execute() throws MojoExecutionException, MojoFailureException
+    {
+        MojoBinding binding = bindingFactory.createMojoBinding( groupId, artifactId, version, artifactId, project );
+        try
+        {
+            PluginDescriptor descriptor = pluginLoader.loadPlugin( binding, project );
+
+            MojoDescriptor mojoDescriptor = descriptor.getMojo( goal );
+
+            if ( mojoDescriptor == null )
+            {
+                throw new MojoExecutionException( "Resolved plugin: " + descriptor.getId()
+                                + " does not contain a mojo called \'" + goal + "\'." );
+            }
+        }
+        catch ( PluginLoaderException e )
+        {
+            throw new MojoExecutionException( "Failed to load late-bound plugin: "
+                            + MojoBindingUtils.createPluginKey( binding ) );
+        }
+    }
+
+}

Propchange: maven/components/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/statemgmt/ResolveLateBoundPluginMojo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/components/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/statemgmt/ResolveLateBoundPluginMojo.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/statemgmt/StateManagementUtils.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/statemgmt/StateManagementUtils.java?view=diff&rev=541938&r1=541937&r2=541938
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/statemgmt/StateManagementUtils.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/statemgmt/StateManagementUtils.java Sat May 26 14:06:12 2007
@@ -4,11 +4,10 @@
 import org.codehaus.plexus.util.xml.Xpp3Dom;
 
 /**
- * Constructs and matches MojoBinding instances that refer to the forked-execution context manager
- * mojos.
+ * Constructs and matches MojoBinding instances that refer to the forked-execution context manager mojos.
  * 
  * @author jdcasey
- *
+ * 
  */
 public final class StateManagementUtils
 {
@@ -27,6 +26,8 @@
 
     public static final String CLEAR_FORKED_EXECUTION_GOAL = "clear-fork-context";
 
+    public static final String RESOLVE_LATE_BOUND_PLUGIN_GOAL = "resolve-late-bound-plugin";
+
     private static int CURRENT_FORK_ID = 0;
 
     private StateManagementUtils()
@@ -34,9 +35,8 @@
     }
 
     /**
-     * Create a new MojoBinding instance that refers to the internal mojo used to setup a new 
-     * forked-execution context. Also, set the configuration to contain the forkId for this new
-     * context.
+     * Create a new MojoBinding instance that refers to the internal mojo used to setup a new forked-execution context.
+     * Also, set the configuration to contain the forkId for this new context.
      */
     public static MojoBinding createStartForkedExecutionMojoBinding()
     {
@@ -49,22 +49,21 @@
         binding.setOrigin( ORIGIN );
 
         CURRENT_FORK_ID = (int) System.currentTimeMillis();
-        
+
         Xpp3Dom config = new Xpp3Dom( "configuration" );
         Xpp3Dom forkId = new Xpp3Dom( "forkId" );
         forkId.setValue( "" + CURRENT_FORK_ID );
-        
+
         config.addChild( forkId );
-        
+
         binding.setConfiguration( config );
 
         return binding;
     }
 
     /**
-     * Create a new MojoBinding instance that refers to the internal mojo used to end a 
-     * forked-execution context. Also, set the configuration to contain the forkId for this new
-     * context.
+     * Create a new MojoBinding instance that refers to the internal mojo used to end a forked-execution context. Also,
+     * set the configuration to contain the forkId for this new context.
      */
     public static MojoBinding createEndForkedExecutionMojoBinding()
     {
@@ -79,18 +78,17 @@
         Xpp3Dom config = new Xpp3Dom( "configuration" );
         Xpp3Dom forkId = new Xpp3Dom( "forkId" );
         forkId.setValue( "" + CURRENT_FORK_ID );
-        
+
         config.addChild( forkId );
-        
+
         binding.setConfiguration( config );
 
         return binding;
     }
 
     /**
-     * Create a new MojoBinding instance that refers to the internal mojo used to cleanup a completed 
-     * forked-execution context. Also, set the configuration to contain the forkId for this new
-     * context.
+     * Create a new MojoBinding instance that refers to the internal mojo used to cleanup a completed forked-execution
+     * context. Also, set the configuration to contain the forkId for this new context.
      */
     public static MojoBinding createClearForkedExecutionMojoBinding()
     {
@@ -105,45 +103,99 @@
         Xpp3Dom config = new Xpp3Dom( "configuration" );
         Xpp3Dom forkId = new Xpp3Dom( "forkId" );
         forkId.setValue( "" + CURRENT_FORK_ID );
-        
+
         config.addChild( forkId );
-        
+
         binding.setConfiguration( config );
 
         return binding;
     }
-    
+
     /**
-     * Return true if the specified MojoBinding refers to the internal mojo used to setup a new
-     * forked-execution context. This is useful for formatting when listing the build plan, when
-     * expression of these actual mojo names isn't necessarily useful, and can be confusing.
+     * Return true if the specified MojoBinding refers to the internal mojo used to setup a new forked-execution
+     * context. This is useful for formatting when listing the build plan, when expression of these actual mojo names
+     * isn't necessarily useful, and can be confusing.
      */
-    public static boolean isForkedExecutionStartMarker( MojoBinding binding )
+    public static boolean isForkedExecutionStartMarker( final MojoBinding binding )
     {
         return GROUP_ID.equals( binding.getGroupId() ) && ARTIFACT_ID.equals( binding.getArtifactId() )
-            && START_FORKED_EXECUTION_GOAL.equals( binding.getGoal() );
+                        && START_FORKED_EXECUTION_GOAL.equals( binding.getGoal() );
     }
 
     /**
-     * Return true if the specified MojoBinding refers to the internal mojo used to end a
-     * forked-execution context. This is useful for formatting when listing the build plan, when
-     * expression of these actual mojo names isn't necessarily useful, and can be confusing.
+     * Return true if the specified MojoBinding refers to the internal mojo used to end a forked-execution context. This
+     * is useful for formatting when listing the build plan, when expression of these actual mojo names isn't
+     * necessarily useful, and can be confusing.
      */
-    public static boolean isForkedExecutionEndMarker( MojoBinding binding )
+    public static boolean isForkedExecutionEndMarker( final MojoBinding binding )
     {
         return GROUP_ID.equals( binding.getGroupId() ) && ARTIFACT_ID.equals( binding.getArtifactId() )
-            && END_FORKED_EXECUTION_GOAL.equals( binding.getGoal() );
+                        && END_FORKED_EXECUTION_GOAL.equals( binding.getGoal() );
     }
 
     /**
      * Return true if the specified MojoBinding refers to the internal mojo used to clean up a completed
-     * forked-execution context. This is useful for formatting when listing the build plan, when
-     * expression of these actual mojo names isn't necessarily useful, and can be confusing.
+     * forked-execution context. This is useful for formatting when listing the build plan, when expression of these
+     * actual mojo names isn't necessarily useful, and can be confusing.
+     */
+    public static boolean isForkedExecutionClearMarker( final MojoBinding binding )
+    {
+        return GROUP_ID.equals( binding.getGroupId() ) && ARTIFACT_ID.equals( binding.getArtifactId() )
+                        && CLEAR_FORKED_EXECUTION_GOAL.equals( binding.getGoal() );
+    }
+
+    /**
+     * Create a new MojoBinding instance that refers to the internal mojo used to resolve a late-bound plugin just
+     * before it is to be used. Also, set the configuration to contain the parameters necessary for this resolution.
+     */
+    public static MojoBinding createResolveLateBoundMojoBinding( final MojoBinding lateBound )
+    {
+        MojoBinding binding = new MojoBinding();
+
+        binding.setGroupId( GROUP_ID );
+        binding.setArtifactId( ARTIFACT_ID );
+        binding.setVersion( VERSION );
+        binding.setGoal( RESOLVE_LATE_BOUND_PLUGIN_GOAL );
+        binding.setOrigin( ORIGIN );
+
+        Xpp3Dom config = new Xpp3Dom( "configuration" );
+        Xpp3Dom param = new Xpp3Dom( "groupId" );
+        param.setValue( lateBound.getGroupId() );
+
+        config.addChild( param );
+
+        param = new Xpp3Dom( "artifactId" );
+        param.setValue( lateBound.getArtifactId() );
+
+        config.addChild( param );
+
+        if ( lateBound.getVersion() != null )
+        {
+            param = new Xpp3Dom( "version" );
+            param.setValue( lateBound.getVersion() );
+
+            config.addChild( param );
+        }
+
+        param = new Xpp3Dom( "goal" );
+        param.setValue( lateBound.getGoal() );
+
+        config.addChild( param );
+
+        binding.setConfiguration( config );
+
+        return binding;
+    }
+
+    /**
+     * Return true if the specified MojoBinding refers to the internal mojo used to resolve a late-bound mojo. This is
+     * useful for formatting when listing the build plan, when expression of these actual mojo names isn't necessarily
+     * useful, and can be confusing.
      */
-    public static boolean isForkedExecutionClearMarker( MojoBinding binding )
+    public static boolean isResolveLateBoundMojoBinding( final MojoBinding binding )
     {
         return GROUP_ID.equals( binding.getGroupId() ) && ARTIFACT_ID.equals( binding.getArtifactId() )
-            && CLEAR_FORKED_EXECUTION_GOAL.equals( binding.getGoal() );
+                        && RESOLVE_LATE_BOUND_PLUGIN_GOAL.equals( binding.getGoal() );
     }
 
 }

Modified: maven/components/trunk/maven-core/src/main/resources/META-INF/maven/plugin.xml
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/resources/META-INF/maven/plugin.xml?view=diff&rev=541938&r1=541937&r2=541938
==============================================================================
--- maven/components/trunk/maven-core/src/main/resources/META-INF/maven/plugin.xml (original)
+++ maven/components/trunk/maven-core/src/main/resources/META-INF/maven/plugin.xml Sat May 26 14:06:12 2007
@@ -113,5 +113,73 @@
         <forkId implementation="int" default-value="-1">${forkId}</forkId>
       </configuration>
     </mojo>
+    <mojo>
+      <goal>resolve-plugin</goal>
+      <description>Resolve a late-bound plugin during a build, right before it is to be used.</description>
+      <requiresDirectInvocation>false</requiresDirectInvocation>
+      <requiresProject>true</requiresProject>
+      <requiresReports>false</requiresReports>
+      <aggregator>false</aggregator>
+      <requiresOnline>false</requiresOnline>
+      <inheritedByDefault>true</inheritedByDefault>
+      <implementation>org.apache.maven.lifecycle.statemgmt.ResolveLateBoundPluginMojo</implementation>
+      <language>java</language>
+      <instantiationStrategy>per-lookup</instantiationStrategy>
+      <executionStrategy>once-per-session</executionStrategy>
+      <parameters>
+        <parameter>
+          <name>project</name>
+          <type>org.apache.maven.project.MavenProject</type>
+          <required>true</required>
+          <editable>false</editable>
+          <description>The current MavenProject instance, for building a new MojoBinding instance.</description>
+        </parameter>
+        <parameter>
+          <name>groupId</name>
+          <type>java.lang.String</type>
+          <required>true</required>
+          <editable>true</editable>
+          <description>The plugin's groupId.</description>
+        </parameter>
+        <parameter>
+          <name>artifactId</name>
+          <type>java.lang.String</type>
+          <required>true</required>
+          <editable>true</editable>
+          <description>The plugin's artifactId.</description>
+        </parameter>
+        <parameter>
+          <name>version</name>
+          <type>java.lang.String</type>
+          <required>false</required>
+          <editable>true</editable>
+          <description>The plugin's version.</description>
+        </parameter>
+        <parameter>
+          <name>gaol</name>
+          <type>java.lang.String</type>
+          <required>true</required>
+          <editable>true</editable>
+          <description>The mojo's goal that we're looking for, as an extra validation step.</description>
+        </parameter>
+      </parameters>
+      <configuration>
+        <project implementation="org.apache.maven.project.MavenProject" default-value="${project}"/>
+        <groupId implementation="java.lang.String">${groupId}</groupId>
+        <artifactId implementation="java.lang.String">${artifactId}</artifactId>
+        <version implementation="java.lang.String">${version}</version>
+        <goal implementation="java.lang.String">${goal}</goal>
+      </configuration>
+      <requirements>
+        <requirement>
+          <role>org.apache.maven.plugin.loader.PluginLoader</role>
+          <field-name>pluginLoader</field-name>
+        </requirement>
+        <requirement>
+          <role>org.apache.maven.lifecycle.binding.MojoBindingFactory</role>
+          <field-name>bindingFactory</field-name>
+        </requirement>
+      </requirements>
+    </mojo>
   </mojos>
 </plugin>

Modified: maven/components/trunk/maven-core/src/main/resources/META-INF/plexus/components.xml
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/resources/META-INF/plexus/components.xml?view=diff&rev=541938&r1=541937&r2=541938
==============================================================================
--- maven/components/trunk/maven-core/src/main/resources/META-INF/plexus/components.xml (original)
+++ maven/components/trunk/maven-core/src/main/resources/META-INF/plexus/components.xml Sat May 26 14:06:12 2007
@@ -267,9 +267,6 @@
           <role>org.apache.maven.context.BuildContextManager</role>
         </requirement>
         <requirement>
-          <role>org.apache.maven.lifecycle.binding.LifecycleBindingManager</role>
-        </requirement>
-        <requirement>
           <role>org.apache.maven.plugin.loader.PluginLoader</role>
         </requirement>
         <requirement>

Modified: maven/components/trunk/maven-core/src/test/java/org/apache/maven/lifecycle/binding/DefaultLifecycleBindingManagerTest.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/test/java/org/apache/maven/lifecycle/binding/DefaultLifecycleBindingManagerTest.java?view=diff&rev=541938&r1=541937&r2=541938
==============================================================================
--- maven/components/trunk/maven-core/src/test/java/org/apache/maven/lifecycle/binding/DefaultLifecycleBindingManagerTest.java (original)
+++ maven/components/trunk/maven-core/src/test/java/org/apache/maven/lifecycle/binding/DefaultLifecycleBindingManagerTest.java Sat May 26 14:06:12 2007
@@ -4,7 +4,6 @@
 import org.apache.maven.lifecycle.LifecycleSpecificationException;
 import org.apache.maven.lifecycle.model.LifecycleBindings;
 import org.apache.maven.lifecycle.model.MojoBinding;
-import org.apache.maven.lifecycle.plan.LifecyclePlannerException;
 import org.apache.maven.model.Build;
 import org.apache.maven.model.Model;
 import org.apache.maven.model.Plugin;
@@ -14,24 +13,21 @@
 import org.codehaus.plexus.PlexusTestCase;
 import org.codehaus.plexus.util.xml.Xpp3Dom;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Properties;
 
-public class DefaultLifecycleBindingManagerTest
-    extends PlexusTestCase
+public class DefaultLifecycleBindingManagerTest extends PlexusTestCase
 {
 
     private LifecycleBindingManager mgr;
 
-    public void setUp()
-        throws Exception
+    public void setUp() throws Exception
     {
         super.setUp();
 
-        this.mgr = (LifecycleBindingManager) lookup( LifecycleBindingManager.ROLE, "default" );
+        mgr = (LifecycleBindingManager) lookup( LifecycleBindingManager.ROLE, "default" );
     }
 
     public void testLookup()
@@ -92,7 +88,7 @@
 
         Build build = new Build();
         model.setBuild( build );
-        
+
         PluginManagement plugMgmt = new PluginManagement();
         build.setPluginManagement( plugMgmt );
 
@@ -182,7 +178,7 @@
         assertEquals( "other-value", config.getChild( "test2" ).getValue() );
     }
 
-    private Object createConfiguration( Properties configProperties )
+    private Object createConfiguration( final Properties configProperties )
     {
         Xpp3Dom config = new Xpp3Dom( "configuration" );
         for ( Iterator it = configProperties.keySet().iterator(); it.hasNext(); )
@@ -199,164 +195,4 @@
         return config;
     }
 
-    public void testAssembleMojoBindingList_ReturnBindingsUpToStopPhaseForSinglePhaseTaskList()
-        throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException
-    {
-        LifecycleBindings bindings = new LifecycleBindings();
-        bindings.getCleanBinding().getPreClean().addBinding( newMojoBinding( "goal", "artifact", "pre-clean" ) );
-        bindings.getCleanBinding().getClean().addBinding( newMojoBinding( "goal", "artifact", "clean" ) );
-        bindings.getCleanBinding().getPostClean().addBinding( newMojoBinding( "goal", "artifact", "post-clean" ) );
-
-        List result = mgr.assembleMojoBindingList( Collections.singletonList( "clean" ), bindings, new MavenProject( new Model() ) );
-
-        assertEquals( 2, result.size() );
-
-        MojoBinding binding = (MojoBinding) result.get( 0 );
-
-        assertEquals( "goal", binding.getGroupId() );
-        assertEquals( "artifact", binding.getArtifactId() );
-        assertEquals( "pre-clean", binding.getGoal() );
-
-        binding = (MojoBinding) result.get( 1 );
-
-        assertEquals( "goal", binding.getGroupId() );
-        assertEquals( "artifact", binding.getArtifactId() );
-        assertEquals( "clean", binding.getGoal() );
-    }
-
-    public void testAssembleMojoBindingList_CombinePreviousBindingsWhenSubsetOfNextBindingsForTwoPhaseTaskList()
-        throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException
-    {
-        LifecycleBindings bindings = new LifecycleBindings();
-        bindings.getCleanBinding().getPreClean().addBinding( newMojoBinding( "goal", "artifact", "pre-clean" ) );
-        bindings.getCleanBinding().getClean().addBinding( newMojoBinding( "goal", "artifact", "clean" ) );
-        bindings.getCleanBinding().getClean().addBinding( newMojoBinding( "goal", "artifact", "post-clean" ) );
-
-        List tasks = new ArrayList( 2 );
-        tasks.add( "clean" );
-        tasks.add( "post-clean" );
-
-        List result = mgr.assembleMojoBindingList( tasks, bindings, new MavenProject( new Model() ) );
-
-        assertEquals( 3, result.size() );
-
-        MojoBinding binding = (MojoBinding) result.get( 0 );
-
-        assertEquals( "goal", binding.getGroupId() );
-        assertEquals( "artifact", binding.getArtifactId() );
-        assertEquals( "pre-clean", binding.getGoal() );
-
-        binding = (MojoBinding) result.get( 1 );
-
-        assertEquals( "goal", binding.getGroupId() );
-        assertEquals( "artifact", binding.getArtifactId() );
-        assertEquals( "clean", binding.getGoal() );
-
-        binding = (MojoBinding) result.get( 2 );
-
-        assertEquals( "goal", binding.getGroupId() );
-        assertEquals( "artifact", binding.getArtifactId() );
-        assertEquals( "post-clean", binding.getGoal() );
-    }
-
-    public void testAssembleMojoBindingList_IgnoreSuccessiveBindingsWhenSameAsPreviousOnesForTwoPhaseTaskList()
-        throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException
-    {
-        LifecycleBindings bindings = new LifecycleBindings();
-        bindings.getCleanBinding().getPreClean().addBinding( newMojoBinding( "goal", "artifact", "pre-clean" ) );
-        bindings.getCleanBinding().getClean().addBinding( newMojoBinding( "goal", "artifact", "clean" ) );
-
-        List tasks = new ArrayList( 2 );
-        tasks.add( "clean" );
-        tasks.add( "post-clean" );
-
-        List result = mgr.assembleMojoBindingList( tasks, bindings, new MavenProject( new Model() ) );
-
-        assertEquals( 2, result.size() );
-
-        MojoBinding binding = (MojoBinding) result.get( 0 );
-
-        assertEquals( "goal", binding.getGroupId() );
-        assertEquals( "artifact", binding.getArtifactId() );
-        assertEquals( "pre-clean", binding.getGoal() );
-
-        binding = (MojoBinding) result.get( 1 );
-
-        assertEquals( "goal", binding.getGroupId() );
-        assertEquals( "artifact", binding.getArtifactId() );
-        assertEquals( "clean", binding.getGoal() );
-    }
-
-    public void testAssembleMojoBindingList_ReturnBindingsUpToStopPhasesForTwoPhaseTaskList()
-        throws LifecycleSpecificationException, LifecyclePlannerException, LifecycleLoaderException
-    {
-        LifecycleBindings bindings = new LifecycleBindings();
-
-        bindings.getCleanBinding().getPreClean().addBinding( newMojoBinding( "goal", "artifact", "pre-clean" ) );
-        bindings.getCleanBinding().getClean().addBinding( newMojoBinding( "goal", "artifact", "clean" ) );
-        bindings.getCleanBinding().getPostClean().addBinding( newMojoBinding( "goal", "artifact", "post-clean" ) );
-
-        bindings.getBuildBinding().getInitialize().addBinding( newMojoBinding( "goal", "artifact", "initialize" ) );
-        bindings.getBuildBinding().getCompile().addBinding( newMojoBinding( "goal", "artifact", "compile" ) );
-        bindings.getBuildBinding().getCreatePackage().addBinding( newMojoBinding( "goal", "artifact", "package" ) );
-
-        List tasks = new ArrayList( 2 );
-        tasks.add( "clean" );
-        tasks.add( "compile" );
-
-        List result = mgr.assembleMojoBindingList( tasks, bindings, new MavenProject( new Model() ) );
-
-        assertEquals( 4, result.size() );
-
-        MojoBinding binding = (MojoBinding) result.get( 0 );
-
-        assertEquals( "goal", binding.getGroupId() );
-        assertEquals( "artifact", binding.getArtifactId() );
-        assertEquals( "pre-clean", binding.getGoal() );
-
-        binding = (MojoBinding) result.get( 1 );
-
-        assertEquals( "goal", binding.getGroupId() );
-        assertEquals( "artifact", binding.getArtifactId() );
-        assertEquals( "clean", binding.getGoal() );
-
-        binding = (MojoBinding) result.get( 2 );
-
-        assertEquals( "goal", binding.getGroupId() );
-        assertEquals( "artifact", binding.getArtifactId() );
-        assertEquals( "initialize", binding.getGoal() );
-
-        binding = (MojoBinding) result.get( 3 );
-
-        assertEquals( "goal", binding.getGroupId() );
-        assertEquals( "artifact", binding.getArtifactId() );
-        assertEquals( "compile", binding.getGoal() );
-
-    }
-
-    public void testAssembleMojoBindingList_ThrowErrorForInvalidPhaseNameAsSingletonTaskList()
-        throws LifecyclePlannerException, LifecycleLoaderException
-    {
-        try
-        {
-            mgr.assembleMojoBindingList( Collections.singletonList( "dud" ), new LifecycleBindings(),
-                                         new MavenProject( new Model() ) );
-
-            fail( "Should fail with LifecycleSpecificationException due to invalid phase/direct mojo reference." );
-        }
-        catch ( LifecycleSpecificationException e )
-        {
-            // expected.
-        }
-    }
-
-    private MojoBinding newMojoBinding( String groupId, String artifactId, String goal )
-    {
-        MojoBinding binding = new MojoBinding();
-        binding.setGroupId( groupId );
-        binding.setArtifactId( artifactId );
-        binding.setGoal( goal );
-
-        return binding;
-    }
 }

Added: maven/components/trunk/maven-core/src/test/java/org/apache/maven/lifecycle/plan/BuildPlanTest.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/test/java/org/apache/maven/lifecycle/plan/BuildPlanTest.java?view=auto&rev=541938
==============================================================================
--- maven/components/trunk/maven-core/src/test/java/org/apache/maven/lifecycle/plan/BuildPlanTest.java (added)
+++ maven/components/trunk/maven-core/src/test/java/org/apache/maven/lifecycle/plan/BuildPlanTest.java Sat May 26 14:06:12 2007
@@ -0,0 +1,98 @@
+package org.apache.maven.lifecycle.plan;
+
+import org.apache.maven.lifecycle.LifecycleLoaderException;
+import org.apache.maven.lifecycle.LifecycleSpecificationException;
+import org.apache.maven.lifecycle.MojoBindingUtils;
+import org.apache.maven.lifecycle.model.BuildBinding;
+import org.apache.maven.lifecycle.model.LifecycleBindings;
+import org.apache.maven.lifecycle.model.MojoBinding;
+import org.apache.maven.lifecycle.statemgmt.StateManagementUtils;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Stack;
+
+import junit.framework.TestCase;
+
+public class BuildPlanTest
+    extends TestCase
+{
+
+    public void testRender_OneDirectInvocationWithForkedPhase_NoLifecycleOverlay()
+        throws LifecycleSpecificationException, LifecycleLoaderException
+    {
+        List check = new ArrayList();
+
+        check.add( StateManagementUtils.createStartForkedExecutionMojoBinding() );
+
+        MojoBinding mb = new MojoBinding();
+        mb.setGroupId( "test" );
+        mb.setArtifactId( "test-plugin" );
+        mb.setVersion( "1" );
+        mb.setGoal( "validate" );
+
+        check.add( mb );
+
+        BuildBinding binding = new BuildBinding();
+        binding.getValidate().addBinding( mb );
+
+        mb = new MojoBinding();
+        mb.setGroupId( "test" );
+        mb.setArtifactId( "test-plugin" );
+        mb.setVersion( "1" );
+        mb.setGoal( "generate-sources" );
+
+        check.add( mb );
+
+        check.add( StateManagementUtils.createClearForkedExecutionMojoBinding() );
+
+        binding.getGenerateSources().addBinding( mb );
+
+        LifecycleBindings bindings = new LifecycleBindings();
+        bindings.setBuildBinding( binding );
+
+        List tasks = Collections.singletonList( "eclipse:eclipse" );
+
+        MojoBinding eclipseBinding = new MojoBinding();
+        eclipseBinding.setGroupId( "org.apache.maven.plugins" );
+        eclipseBinding.setArtifactId( "maven-eclipse-plugin" );
+        eclipseBinding.setVersion( "2.3" );
+        eclipseBinding.setGoal( "eclipse" );
+
+        check.add( eclipseBinding );
+
+        check.add( StateManagementUtils.createEndForkedExecutionMojoBinding() );
+
+        BuildPlan plan = new BuildPlan( new LifecycleBindings(), tasks );
+
+        plan.addDirectInvocationBinding( "eclipse:eclipse", eclipseBinding );
+
+        plan.addForkedExecution( eclipseBinding, new BuildPlan( bindings,
+                                                                Collections.singletonList( "generate-sources" ) ) );
+
+        List executionPlan = plan.renderExecutionPlan( new Stack() );
+
+        assertBindings( check, executionPlan );
+    }
+
+    private void assertBindings( final List check, final List executionPlan )
+    {
+        assertNotNull( executionPlan );
+
+        System.out.println( "Expected execution plan:\n" + String.valueOf( check ).replace( ',', '\n' ) );
+        System.out.println( "\nActual execution plan:\n" + String.valueOf( executionPlan ).replace( ',', '\n' ) );
+
+        assertEquals( "Execution plan does not contain the expected number of mojo bindings.", check.size(),
+                      executionPlan.size() );
+        for ( int i = 0; i < check.size(); i++ )
+        {
+            MojoBinding checkBinding = (MojoBinding) check.get( i );
+            MojoBinding realBinding = (MojoBinding) executionPlan.get( i );
+
+            assertEquals( "Expected mojo binding does not match execution plan.",
+                          MojoBindingUtils.createMojoBindingKey( checkBinding, true ),
+                          MojoBindingUtils.createMojoBindingKey( realBinding, true ) );
+        }
+    }
+}

Propchange: maven/components/trunk/maven-core/src/test/java/org/apache/maven/lifecycle/plan/BuildPlanTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/components/trunk/maven-core/src/test/java/org/apache/maven/lifecycle/plan/BuildPlanTest.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Modified: maven/components/trunk/maven-embedder/pom.xml
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-embedder/pom.xml?view=diff&rev=541938&r1=541937&r2=541938
==============================================================================
--- maven/components/trunk/maven-embedder/pom.xml (original)
+++ maven/components/trunk/maven-embedder/pom.xml Sat May 26 14:06:12 2007
@@ -42,7 +42,7 @@
     <plugins>
       <plugin>
         <artifactId>maven-assembly-plugin</artifactId>
-        <version>2.1</version>
+        <version>2.2-beta-1</version>
         <configuration>
           <descriptor>src/main/assembly/bin.xml</descriptor>
           <finalName>maven-${version}</finalName>
@@ -51,7 +51,7 @@
           <execution>
             <phase>install</phase>
             <goals>
-              <goal>attached</goal>
+              <goal>single</goal>
             </goals>
           </execution>
         </executions>

Modified: maven/components/trunk/maven-lifecycle/src/main/java/org/apache/maven/lifecycle/LifecycleUtils.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-lifecycle/src/main/java/org/apache/maven/lifecycle/LifecycleUtils.java?view=diff&rev=541938&r1=541937&r2=541938
==============================================================================
--- maven/components/trunk/maven-lifecycle/src/main/java/org/apache/maven/lifecycle/LifecycleUtils.java (original)
+++ maven/components/trunk/maven-lifecycle/src/main/java/org/apache/maven/lifecycle/LifecycleUtils.java Sat May 26 14:06:12 2007
@@ -22,7 +22,7 @@
     {
     }
 
-    public static void setOrigin( LifecycleBindings bindings, String origin )
+    public static void setOrigin( final LifecycleBindings bindings, final String origin )
     {
         for ( Iterator bindingIt = bindings.getBindingList().iterator(); bindingIt.hasNext(); )
         {
@@ -52,7 +52,7 @@
         }
     }
 
-    public static List getMojoBindingListForLifecycle( String stopPhase, LifecycleBindings bindings )
+    public static List getMojoBindingListForLifecycle( final String stopPhase, final LifecycleBindings bindings )
         throws NoSuchPhaseException
     {
         LifecycleBinding binding = findLifecycleBindingForPhase( stopPhase, bindings );
@@ -65,7 +65,7 @@
         return getMojoBindingListForLifecycle( stopPhase, binding );
     }
 
-    public static List getMojoBindingListForLifecycle( String stopPhase, LifecycleBinding lifecycle )
+    public static List getMojoBindingListForLifecycle( final String stopPhase, final LifecycleBinding lifecycle )
         throws NoSuchPhaseException
     {
         List phaseNames = lifecycle.getPhaseNamesInOrder();
@@ -85,7 +85,7 @@
             Phase phase = (Phase) phases.get( i );
             List phaseBindings = phase.getBindings();
 
-            if ( phaseBindings != null && !phaseBindings.isEmpty() )
+            if ( ( phaseBindings != null ) && !phaseBindings.isEmpty() )
             {
                 bindings.addAll( phaseBindings );
             }
@@ -97,7 +97,8 @@
     /**
      * @return null if the phase is not contained in any of the lifecycles.
      */
-    public static LifecycleBinding findLifecycleBindingForPhase( String phaseName, LifecycleBindings lifecycles )
+    public static LifecycleBinding findLifecycleBindingForPhase( final String phaseName,
+                                                                 final LifecycleBindings lifecycles )
     {
         List lifecyclesAvailable = lifecycles.getBindingList();
 
@@ -114,8 +115,8 @@
         return null;
     }
 
-    public static void removeMojoBinding( String phaseName, MojoBinding mojoBinding, LifecycleBinding lifecycleBinding,
-                                          boolean considerExecutionId )
+    public static void removeMojoBinding( final String phaseName, final MojoBinding mojoBinding,
+                                          final LifecycleBinding lifecycleBinding, final boolean considerExecutionId )
         throws NoSuchPhaseException
     {
         List phaseNames = lifecycleBinding.getPhaseNamesInOrder();
@@ -125,7 +126,7 @@
         if ( idx < 0 )
         {
             throw new NoSuchPhaseException( phaseName, "Phase: " + phaseName + " not found in lifecycle: "
-                + lifecycleBinding.getId() );
+                            + lifecycleBinding.getId() );
         }
 
         List phases = lifecycleBinding.getPhasesInOrder();
@@ -136,13 +137,13 @@
         {
             List mojoBindings = phase.getBindings();
 
-            String targetKey = createMojoBindingKey( mojoBinding, considerExecutionId );
+            String targetKey = MojoBindingUtils.createMojoBindingKey( mojoBinding, considerExecutionId );
 
             for ( Iterator it = mojoBindings.iterator(); it.hasNext(); )
             {
                 MojoBinding candidate = (MojoBinding) it.next();
 
-                String candidateKey = createMojoBindingKey( candidate, considerExecutionId );
+                String candidateKey = MojoBindingUtils.createMojoBindingKey( candidate, considerExecutionId );
                 if ( candidateKey.equals( targetKey ) )
                 {
                     it.remove();
@@ -153,8 +154,8 @@
         }
     }
 
-    public static void addMojoBinding( String phaseName, MojoBinding mojoBinding, LifecycleBinding lifecycleBinding )
-        throws NoSuchPhaseException
+    public static void addMojoBinding( final String phaseName, final MojoBinding mojoBinding,
+                                       final LifecycleBinding lifecycleBinding ) throws NoSuchPhaseException
     {
         List phaseNames = lifecycleBinding.getPhaseNamesInOrder();
 
@@ -163,7 +164,7 @@
         if ( idx < 0 )
         {
             throw new NoSuchPhaseException( phaseName, "Phase: " + phaseName + " not found in lifecycle: "
-                + lifecycleBinding.getId() );
+                            + lifecycleBinding.getId() );
         }
 
         List phases = lifecycleBinding.getPhasesInOrder();
@@ -172,7 +173,7 @@
         phase.addBinding( mojoBinding );
     }
 
-    public static void addMojoBinding( String phaseName, MojoBinding mojo, LifecycleBindings bindings )
+    public static void addMojoBinding( final String phaseName, final MojoBinding mojo, final LifecycleBindings bindings )
         throws LifecycleSpecificationException
     {
         LifecycleBinding binding = findLifecycleBindingForPhase( phaseName, bindings );
@@ -185,21 +186,25 @@
         addMojoBinding( phaseName, mojo, binding );
     }
 
-    public static LifecycleBindings mergeBindings( LifecycleBindings existingBindings, LifecycleBindings newBindings,
-                                                   LifecycleBindings defaultBindings, boolean mergeConfigIfExecutionIdMatches )
+    public static LifecycleBindings mergeBindings( final LifecycleBindings existingBindings,
+                                                   final LifecycleBindings newBindings,
+                                                   final LifecycleBindings defaultBindings,
+                                                   final boolean mergeConfigIfExecutionIdMatches )
     {
         return mergeBindings( existingBindings, newBindings, defaultBindings, mergeConfigIfExecutionIdMatches, false );
     }
 
-    public static LifecycleBindings mergeBindings( LifecycleBindings existingBindings, LifecycleBindings newBindings,
-                                                   LifecycleBindings defaultBindings, boolean mergeConfigIfExecutionIdMatches,
-                                                   boolean reverseConfigMergeDirection )
+    public static LifecycleBindings mergeBindings( final LifecycleBindings existingBindings,
+                                                   final LifecycleBindings newBindings,
+                                                   final LifecycleBindings defaultBindings,
+                                                   final boolean mergeConfigIfExecutionIdMatches,
+                                                   final boolean reverseConfigMergeDirection )
     {
         LifecycleBindings result = new LifecycleBindings();
         result.setPackaging( newBindings.getPackaging() );
 
         CleanBinding cb = (CleanBinding) cloneBinding( existingBindings.getCleanBinding() );
-        if ( defaultBindings != null && isNullOrEmpty( cb ) )
+        if ( ( defaultBindings != null ) && isNullOrEmpty( cb ) )
         {
             cb = (CleanBinding) cloneBinding( defaultBindings.getCleanBinding() );
         }
@@ -212,7 +217,7 @@
         result.setCleanBinding( cb );
 
         BuildBinding bb = (BuildBinding) cloneBinding( existingBindings.getBuildBinding() );
-        if ( defaultBindings != null && isNullOrEmpty( bb ) )
+        if ( ( defaultBindings != null ) && isNullOrEmpty( bb ) )
         {
             bb = (BuildBinding) cloneBinding( defaultBindings.getBuildBinding() );
         }
@@ -225,7 +230,7 @@
         result.setBuildBinding( bb );
 
         SiteBinding sb = (SiteBinding) cloneBinding( existingBindings.getSiteBinding() );
-        if ( defaultBindings != null && isNullOrEmpty( sb ) )
+        if ( ( defaultBindings != null ) && isNullOrEmpty( sb ) )
         {
             sb = (SiteBinding) cloneBinding( defaultBindings.getSiteBinding() );
         }
@@ -251,7 +256,7 @@
                     Phase phase = (Phase) phases.get( i );
                     String name = (String) phaseNames.get( i );
 
-                    if ( phase != null && phase.getBindings() != null && !phase.getBindings().isEmpty() )
+                    if ( ( phase != null ) && ( phase.getBindings() != null ) && !phase.getBindings().isEmpty() )
                     {
                         for ( Iterator phaseIt = phase.getBindings().iterator(); phaseIt.hasNext(); )
                         {
@@ -261,40 +266,46 @@
 
                             if ( mergeConfigIfExecutionIdMatches )
                             {
-                                MojoBinding matchingBinding = findMatchingMojoBinding( mojoBinding, existingBindings, true );
+                                MojoBinding matchingBinding =
+                                    findMatchingMojoBinding( mojoBinding, existingBindings, true );
 
                                 if ( matchingBinding != null )
                                 {
                                     Xpp3Dom existingConfig = new Xpp3Dom( (Xpp3Dom) matchingBinding.getConfiguration() );
-                                    
+
                                     Xpp3Dom configuration;
                                     if ( reverseConfigMergeDirection )
                                     {
-                                        configuration = Xpp3Dom.mergeXpp3Dom( existingConfig, (Xpp3Dom) mojoBinding.getConfiguration() );
+                                        configuration =
+                                            Xpp3Dom.mergeXpp3Dom( existingConfig,
+                                                                  (Xpp3Dom) mojoBinding.getConfiguration() );
                                     }
                                     else
                                     {
-                                        configuration = Xpp3Dom.mergeXpp3Dom( (Xpp3Dom) mojoBinding.getConfiguration(), existingConfig );
+                                        configuration =
+                                            Xpp3Dom.mergeXpp3Dom( (Xpp3Dom) mojoBinding.getConfiguration(),
+                                                                  existingConfig );
                                     }
 
                                     mojoBinding.setConfiguration( configuration );
-                                    
-                                    if ( mojoBinding.getOrigin() == null && matchingBinding.getOrigin() != null )
+
+                                    if ( ( mojoBinding.getOrigin() == null ) && ( matchingBinding.getOrigin() != null ) )
                                     {
                                         mojoBinding.setOrigin( matchingBinding.getOrigin() );
                                     }
-                                    
+
                                     LifecycleBinding resultBinding = findLifecycleBindingForPhase( name, result );
-                                    
+
                                     try
                                     {
                                         removeMojoBinding( name, matchingBinding, resultBinding, true );
                                     }
                                     catch ( NoSuchPhaseException e )
                                     {
-                                        IllegalStateException error = new IllegalStateException(
-                                                                                                 e.getMessage()
-                                                                                                     + "\nSomething strange is going on. Merging should not encounter such inconsistencies." );
+                                        IllegalStateException error =
+                                            new IllegalStateException(
+                                                                       e.getMessage()
+                                                                                       + "\nSomething strange is going on. Merging should not encounter such inconsistencies." );
 
                                         error.initCause( e );
 
@@ -311,9 +322,9 @@
                             {
                                 // NOTE: this shouldn't happen as long as normal components are used
                                 // to create/read these LifecycleBindings instances.
-                                IllegalArgumentException error = new IllegalArgumentException(
-                                                                                               "Project bindings are invalid. Reason: "
-                                                                                                   + e.getMessage() );
+                                IllegalArgumentException error =
+                                    new IllegalArgumentException( "Project bindings are invalid. Reason: "
+                                                    + e.getMessage() );
 
                                 error.initCause( e );
 
@@ -328,35 +339,36 @@
         return result;
     }
 
-    private static boolean isNullOrEmpty( LifecycleBinding binding )
+    private static boolean isNullOrEmpty( final LifecycleBinding binding )
     {
         if ( binding == null )
         {
             return true;
         }
-        
+
         for ( Iterator it = binding.getPhasesInOrder().iterator(); it.hasNext(); )
         {
             Phase phase = (Phase) it.next();
-            
+
             if ( !phase.getBindings().isEmpty() )
             {
                 return false;
             }
         }
-        
+
         return true;
     }
 
-    public static MojoBinding findMatchingMojoBinding( MojoBinding mojoBinding, LifecycleBindings inBindings,
-                                                       boolean considerExecutionId )
+    public static MojoBinding findMatchingMojoBinding( final MojoBinding mojoBinding,
+                                                       final LifecycleBindings inBindings,
+                                                       final boolean considerExecutionId )
     {
-        String key = createMojoBindingKey( mojoBinding, considerExecutionId );
+        String key = MojoBindingUtils.createMojoBindingKey( mojoBinding, considerExecutionId );
 
         return (MojoBinding) mapMojoBindingsByKey( inBindings, considerExecutionId ).get( key );
     }
 
-    private static Map mapMojoBindingsByKey( LifecycleBindings bindings, boolean considerExecutionId )
+    private static Map mapMojoBindingsByKey( final LifecycleBindings bindings, final boolean considerExecutionId )
     {
         Map byKey = new HashMap();
 
@@ -376,7 +388,8 @@
                         {
                             MojoBinding mojoBinding = (MojoBinding) mojoIt.next();
 
-                            byKey.put( createMojoBindingKey( mojoBinding, considerExecutionId ), mojoBinding );
+                            byKey.put( MojoBindingUtils.createMojoBindingKey( mojoBinding, considerExecutionId ),
+                                       mojoBinding );
                         }
                     }
                 }
@@ -386,8 +399,8 @@
         return byKey;
     }
 
-    public static void removeMojoBindings( List toRemove, LifecycleBindings bindings, boolean considerExecutionId )
-        throws NoSuchPhaseException
+    public static void removeMojoBindings( final List toRemove, final LifecycleBindings bindings,
+                                           final boolean considerExecutionId ) throws NoSuchPhaseException
     {
         if ( bindings.getCleanBinding() != null )
         {
@@ -405,8 +418,8 @@
         }
     }
 
-    public static void removeMojoBindings( List toRemove, LifecycleBinding removeFrom, boolean considerExecutionId )
-        throws NoSuchPhaseException
+    public static void removeMojoBindings( final List toRemove, final LifecycleBinding removeFrom,
+                                           final boolean considerExecutionId ) throws NoSuchPhaseException
     {
         // remove where gid:aid:goal matches.
         List targets = new ArrayList();
@@ -414,7 +427,7 @@
         {
             MojoBinding binding = (MojoBinding) it.next();
 
-            targets.add( createMojoBindingKey( binding, considerExecutionId ) );
+            targets.add( MojoBindingUtils.createMojoBindingKey( binding, considerExecutionId ) );
         }
 
         List phases = removeFrom.getPhasesInOrder();
@@ -427,7 +440,7 @@
             for ( Iterator mojoIt = phaseBindings.iterator(); mojoIt.hasNext(); )
             {
                 MojoBinding binding = (MojoBinding) mojoIt.next();
-                String key = createMojoBindingKey( binding, considerExecutionId );
+                String key = MojoBindingUtils.createMojoBindingKey( binding, considerExecutionId );
                 if ( targets.contains( key ) )
                 {
                     mojoIt.remove();
@@ -438,19 +451,7 @@
         }
     }
 
-    public static String createMojoBindingKey( MojoBinding mojoBinding, boolean considerExecutionId )
-    {
-        String key = mojoBinding.getGroupId() + ":" + mojoBinding.getArtifactId() + ":" + mojoBinding.getGoal();
-
-        if ( considerExecutionId )
-        {
-            key += ":" + mojoBinding.getExecutionId();
-        }
-
-        return key;
-    }
-
-    public static LifecycleBindings cloneBindings( LifecycleBindings bindings )
+    public static LifecycleBindings cloneBindings( final LifecycleBindings bindings )
     {
         LifecycleBindings result = new LifecycleBindings();
 
@@ -472,7 +473,7 @@
         return result;
     }
 
-    public static LifecycleBinding cloneBinding( LifecycleBinding binding )
+    public static LifecycleBinding cloneBinding( final LifecycleBinding binding )
     {
         if ( binding == null )
         {
@@ -495,7 +496,7 @@
         else
         {
             throw new IllegalArgumentException( "Unrecognized LifecycleBinding type: " + binding.getClass().getName()
-                + "; cannot clone." );
+                            + "; cannot clone." );
         }
 
         List phases = binding.getPhasesInOrder();
@@ -518,8 +519,10 @@
                 }
                 catch ( NoSuchPhaseException e )
                 {
-                    IllegalStateException error = new IllegalStateException( e.getMessage()
-                        + "\nSomething strange is going on. Cloning should not encounter such inconsistencies." );
+                    IllegalStateException error =
+                        new IllegalStateException(
+                                                   e.getMessage()
+                                                                   + "\nSomething strange is going on. Cloning should not encounter such inconsistencies." );
 
                     error.initCause( e );
 
@@ -531,7 +534,7 @@
         return result;
     }
 
-    public static MojoBinding cloneMojoBinding( MojoBinding binding )
+    public static MojoBinding cloneMojoBinding( final MojoBinding binding )
     {
         MojoBinding result = new MojoBinding();
 
@@ -546,10 +549,11 @@
         return result;
     }
 
-    public static Phase findPhaseForMojoBinding( MojoBinding mojoBinding, LifecycleBindings lifecycleBindings,
-                                                 boolean considerExecutionId )
+    public static Phase findPhaseForMojoBinding( final MojoBinding mojoBinding,
+                                                 final LifecycleBindings lifecycleBindings,
+                                                 final boolean considerExecutionId )
     {
-        String targetKey = createMojoBindingKey( mojoBinding, considerExecutionId );
+        String targetKey = MojoBindingUtils.createMojoBindingKey( mojoBinding, considerExecutionId );
 
         for ( Iterator lifecycleIt = lifecycleBindings.getBindingList().iterator(); lifecycleIt.hasNext(); )
         {
@@ -562,7 +566,7 @@
                 for ( Iterator mojoIt = phase.getBindings().iterator(); mojoIt.hasNext(); )
                 {
                     MojoBinding candidate = (MojoBinding) mojoIt.next();
-                    String key = createMojoBindingKey( candidate, considerExecutionId );
+                    String key = MojoBindingUtils.createMojoBindingKey( candidate, considerExecutionId );
                     if ( key.equals( targetKey ) )
                     {
                         return phase;
@@ -574,15 +578,16 @@
         return null;
     }
 
-    public static boolean isMojoBindingPresent( MojoBinding binding, List candidates, boolean considerExecutionId )
+    public static boolean isMojoBindingPresent( final MojoBinding binding, final List candidates,
+                                                final boolean considerExecutionId )
     {
-        String key = createMojoBindingKey( binding, considerExecutionId );
+        String key = MojoBindingUtils.createMojoBindingKey( binding, considerExecutionId );
 
         for ( Iterator it = candidates.iterator(); it.hasNext(); )
         {
             MojoBinding candidate = (MojoBinding) it.next();
 
-            String candidateKey = createMojoBindingKey( candidate, considerExecutionId );
+            String candidateKey = MojoBindingUtils.createMojoBindingKey( candidate, considerExecutionId );
 
             if ( candidateKey.equals( key ) )
             {
@@ -593,79 +598,87 @@
         return false;
     }
 
-    public static boolean isValidPhaseName( String phaseName )
+    public static boolean isValidPhaseName( final String phaseName )
     {
         LifecycleBindings test = new LifecycleBindings();
         for ( Iterator it = test.getBindingList().iterator(); it.hasNext(); )
         {
             LifecycleBinding binding = (LifecycleBinding) it.next();
-            
+
             if ( binding.getPhaseNamesInOrder().contains( phaseName ) )
             {
                 return true;
             }
         }
-        
+
         return false;
     }
 
     public static List getValidPhaseNames()
     {
         List phaseNames = new ArrayList();
-        
+
         LifecycleBindings bindings = new LifecycleBindings();
         for ( Iterator bindingIt = bindings.getBindingList().iterator(); bindingIt.hasNext(); )
         {
             LifecycleBinding binding = (LifecycleBinding) bindingIt.next();
-            
+
             for ( Iterator phaseNameIt = binding.getPhaseNamesInOrder().iterator(); phaseNameIt.hasNext(); )
             {
                 phaseNames.add( phaseNameIt.next() );
             }
         }
-        
+
         return phaseNames;
     }
 
     public static List getValidBuildPhaseNames()
     {
         List phaseNames = new ArrayList();
-        
+
         LifecycleBinding binding = new BuildBinding();
-        
+
         for ( Iterator phaseNameIt = binding.getPhaseNamesInOrder().iterator(); phaseNameIt.hasNext(); )
         {
             phaseNames.add( phaseNameIt.next() );
         }
-        
+
         return phaseNames;
     }
 
     public static List getValidCleanPhaseNames()
     {
         List phaseNames = new ArrayList();
-        
+
         LifecycleBinding binding = new CleanBinding();
-        
+
         for ( Iterator phaseNameIt = binding.getPhaseNamesInOrder().iterator(); phaseNameIt.hasNext(); )
         {
             phaseNames.add( phaseNameIt.next() );
         }
-        
+
         return phaseNames;
     }
 
     public static List getValidSitePhaseNames()
     {
         List phaseNames = new ArrayList();
-        
+
         LifecycleBinding binding = new SiteBinding();
-        
+
         for ( Iterator phaseNameIt = binding.getPhaseNamesInOrder().iterator(); phaseNameIt.hasNext(); )
         {
             phaseNames.add( phaseNameIt.next() );
         }
-        
+
         return phaseNames;
+    }
+
+    /**
+     * @deprecated Use {@link MojoBindingUtils#createMojoBindingKey(MojoBinding, boolean)} instead.
+     */
+    public static String createMojoBindingKey( final MojoBinding mojoBinding, final boolean considerExecutionId )
+    {
+        return MojoBindingUtils.createMojoBindingKey( mojoBinding, considerExecutionId );
     }
 }

Modified: maven/components/trunk/maven-lifecycle/src/main/java/org/apache/maven/lifecycle/MojoBindingUtils.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-lifecycle/src/main/java/org/apache/maven/lifecycle/MojoBindingUtils.java?view=diff&rev=541938&r1=541937&r2=541938
==============================================================================
--- maven/components/trunk/maven-lifecycle/src/main/java/org/apache/maven/lifecycle/MojoBindingUtils.java (original)
+++ maven/components/trunk/maven-lifecycle/src/main/java/org/apache/maven/lifecycle/MojoBindingUtils.java Sat May 26 14:06:12 2007
@@ -9,10 +9,35 @@
     {
     }
 
-    public static String toString( MojoBinding mojoBinding )
+    public static String toString( final MojoBinding mojoBinding )
     {
         return mojoBinding.getGroupId() + ":" + mojoBinding.getArtifactId() + ":"
-            + ( mojoBinding.getVersion() == null ? "" : mojoBinding.getVersion() + ":" ) + mojoBinding.getGoal();
+                        + ( mojoBinding.getVersion() == null ? "" : mojoBinding.getVersion() + ":" )
+                        + mojoBinding.getGoal();
+    }
+
+    public static String createMojoBindingKey( final MojoBinding mojoBinding, final boolean considerExecutionId )
+    {
+        String key = mojoBinding.getGroupId() + ":" + mojoBinding.getArtifactId() + ":" + mojoBinding.getGoal();
+
+        if ( considerExecutionId )
+        {
+            key += ":" + mojoBinding.getExecutionId();
+        }
+
+        return key;
+    }
+
+    public static String createPluginKey( final MojoBinding binding )
+    {
+        String result = binding.getGroupId() + ":" + binding.getArtifactId();
+
+        if ( binding.getVersion() != null )
+        {
+            result += ":" + binding.getVersion();
+        }
+
+        return result;
     }
 
 }

Modified: maven/components/trunk/maven-lifecycle/src/main/mdo/maven-lifecycle.mdo
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-lifecycle/src/main/mdo/maven-lifecycle.mdo?view=diff&rev=541938&r1=541937&r2=541938
==============================================================================
--- maven/components/trunk/maven-lifecycle/src/main/mdo/maven-lifecycle.mdo (original)
+++ maven/components/trunk/maven-lifecycle/src/main/mdo/maven-lifecycle.mdo Sat May 26 14:06:12 2007
@@ -615,6 +615,18 @@
           <type>boolean</type>
         </field>
       </fields>
+      <codeSegments>
+        <codeSegment>
+          <version>1.0.0</version>
+          <code><![CDATA[
+
+    public String toString()
+    {
+        return getGroupId() + ":" + getArtifactId() + ":" + getVersion() + ":" + getGoal() + ":" + getExecutionId();
+    }
+          ]]></code>
+        </codeSegment>
+      </codeSegments>
     </class>
   </classes>
 </model>

Modified: maven/components/trunk/pom.xml
URL: http://svn.apache.org/viewvc/maven/components/trunk/pom.xml?view=diff&rev=541938&r1=541937&r2=541938
==============================================================================
--- maven/components/trunk/pom.xml (original)
+++ maven/components/trunk/pom.xml Sat May 26 14:06:12 2007
@@ -1,5 +1,4 @@
 <?xml version="1.0" encoding="UTF-8"?>
-
 <!--
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
@@ -17,10 +16,7 @@
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
--->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
     <groupId>org.apache.maven</groupId>