You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ah...@apache.org on 2015/04/01 02:24:03 UTC

[21/50] [abbrv] maven git commit: MNG-5775 Make the project graph building code pluggable to allow for new/different implementations.

MNG-5775 Make the project graph building code pluggable to allow for new/different implementations.


Project: http://git-wip-us.apache.org/repos/asf/maven/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven/commit/be3fb200
Tree: http://git-wip-us.apache.org/repos/asf/maven/tree/be3fb200
Diff: http://git-wip-us.apache.org/repos/asf/maven/diff/be3fb200

Branch: refs/heads/slf4j-log4j2
Commit: be3fb200326208ca4b8c41ebf16d5ae6b8049792
Parents: 7997634
Author: Jason van Zyl <ja...@tesla.io>
Authored: Wed Sep 3 11:48:28 2014 -0700
Committer: Jason van Zyl <ja...@tesla.io>
Committed: Sun Mar 1 12:39:30 2015 -0800

----------------------------------------------------------------------
 .../DefaultArtifactDescriptorReader.java        |  14 +-
 .../internal/MavenWorkspaceReader.java          |  32 ++
 .../java/org/apache/maven/DefaultMaven.java     | 500 +++----------------
 .../maven/DefaultProjectDependencyGraph.java    | 134 -----
 .../maven/FilteredProjectDependencyGraph.java   | 111 ----
 .../org/apache/maven/ProjectCycleException.java |   5 +
 .../java/org/apache/maven/ReactorReader.java    |  13 +-
 .../apache/maven/execution/MavenSession.java    |   9 +-
 .../apache/maven/graph/DefaultGraphBuilder.java | 487 ++++++++++++++++++
 .../graph/DefaultProjectDependencyGraph.java    | 134 +++++
 .../graph/FilteredProjectDependencyGraph.java   | 111 ++++
 .../org/apache/maven/graph/GraphBuilder.java    |  31 ++
 .../project/DefaultModelBuildingListener.java   |   2 +-
 .../org/apache/maven/project/MavenProject.java  |   2 +-
 .../maven/project/ProjectModelResolver.java     |   3 +-
 .../DefaultProjectDependencyGraphTest.java      | 172 -------
 .../DefaultProjectDependencyGraphTest.java      | 172 +++++++
 .../maven/lifecycle/LifecycleExecutorTest.java  |   5 +
 maven-model-builder/pom.xml                     |   5 +-
 .../model/building/DefaultModelBuilder.java     | 291 +++++++----
 .../building/DefaultModelBuildingRequest.java   |  32 ++
 .../building/FilterModelBuildingRequest.java    |  30 +-
 .../maven/model/building/ModelBuilder.java      |  13 +
 .../model/building/ModelBuildingRequest.java    |  22 +-
 .../org/apache/maven/model/building/Result.java | 255 ++++++++++
 .../resolution/UnresolvableModelException.java  |  16 +
 .../resolution/WorkspaceModelResolver.java      |  33 ++
 maven-model/src/main/mdo/maven.mdo              |   8 +-
 28 files changed, 1676 insertions(+), 966 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven/blob/be3fb200/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReader.java
----------------------------------------------------------------------
diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReader.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReader.java
index 0fea15a..a768de5 100644
--- a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReader.java
+++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultArtifactDescriptorReader.java
@@ -52,6 +52,7 @@ import org.eclipse.aether.impl.RemoteRepositoryManager;
 import org.eclipse.aether.impl.RepositoryEventDispatcher;
 import org.eclipse.aether.impl.VersionRangeResolver;
 import org.eclipse.aether.impl.VersionResolver;
+import org.eclipse.aether.repository.WorkspaceReader;
 import org.eclipse.aether.repository.WorkspaceRepository;
 import org.eclipse.aether.resolution.ArtifactDescriptorException;
 import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
@@ -215,7 +216,6 @@ public class DefaultArtifactDescriptorReader
         ArtifactDescriptorResult result = new ArtifactDescriptorResult( request );
 
         Model model = loadPom( session, request, result );
-
         if ( model != null )
         {
             Map<String, Object> config = session.getConfigProperties();
@@ -303,6 +303,18 @@ public class DefaultArtifactDescriptorReader
             }
 
             Model model;
+
+            // hack: don't rebuild model if it was already loaded during reactor resolution
+            final WorkspaceReader workspace = session.getWorkspaceReader();
+            if ( workspace instanceof MavenWorkspaceReader )
+            {
+                model = ( (MavenWorkspaceReader) workspace ).findModel( pomArtifact );
+                if ( model != null )
+                {
+                    return model;
+                }
+            }
+
             try
             {
                 ModelBuildingRequest modelRequest = new DefaultModelBuildingRequest();

http://git-wip-us.apache.org/repos/asf/maven/blob/be3fb200/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenWorkspaceReader.java
----------------------------------------------------------------------
diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenWorkspaceReader.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenWorkspaceReader.java
new file mode 100644
index 0000000..270cf58
--- /dev/null
+++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenWorkspaceReader.java
@@ -0,0 +1,32 @@
+package org.apache.maven.repository.internal;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.model.Model;
+import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.repository.WorkspaceReader;
+
+public interface MavenWorkspaceReader
+    extends WorkspaceReader
+{
+
+    Model findModel( Artifact artifact );
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven/blob/be3fb200/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
index 20d3758..3009301 100644
--- a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
+++ b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
@@ -9,7 +9,7 @@ package org.apache.maven;
  * "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
+ *   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
@@ -25,7 +25,6 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
@@ -39,20 +38,15 @@ import org.apache.maven.execution.MavenExecutionRequest;
 import org.apache.maven.execution.MavenExecutionResult;
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.graph.GraphBuilder;
 import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory;
 import org.apache.maven.lifecycle.internal.ExecutionEventCatapult;
 import org.apache.maven.lifecycle.internal.LifecycleStarter;
-import org.apache.maven.model.Plugin;
 import org.apache.maven.model.building.ModelProblem;
-import org.apache.maven.model.building.ModelProblemUtils;
-import org.apache.maven.model.building.ModelSource;
-import org.apache.maven.model.building.UrlModelSource;
+import org.apache.maven.model.building.Result;
 import org.apache.maven.plugin.LegacySupport;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.project.ProjectBuilder;
-import org.apache.maven.project.ProjectBuildingException;
-import org.apache.maven.project.ProjectBuildingRequest;
-import org.apache.maven.project.ProjectBuildingResult;
 import org.apache.maven.repository.LocalRepositoryNotAccessibleException;
 import org.apache.maven.session.scope.internal.SessionScope;
 import org.codehaus.plexus.PlexusContainer;
@@ -60,13 +54,13 @@ import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.component.annotations.Requirement;
 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
 import org.codehaus.plexus.logging.Logger;
-import org.codehaus.plexus.util.StringUtils;
-import org.codehaus.plexus.util.dag.CycleDetectedException;
 import org.eclipse.aether.DefaultRepositorySystemSession;
 import org.eclipse.aether.RepositorySystemSession;
 import org.eclipse.aether.repository.WorkspaceReader;
 import org.eclipse.aether.util.repository.ChainedWorkspaceReader;
 
+import com.google.common.collect.Iterables;
+
 /**
  * @author Jason van Zyl
  */
@@ -99,6 +93,9 @@ public class DefaultMaven
     @Requirement
     private DefaultRepositorySystemSessionFactory repositorySessionFactory;
 
+    @Requirement( hint = GraphBuilder.HINT )
+    private GraphBuilder graphBuilder;
+
     @Override
     public MavenExecutionResult execute( MavenExecutionRequest request )
     {
@@ -114,9 +111,18 @@ public class DefaultMaven
         }
         catch ( RuntimeException e )
         {
-            result =
-                addExceptionToResult( new DefaultMavenExecutionResult(), new InternalErrorException( "Internal error: "
-                    + e, e ) );
+            //TODO Hack to make the cycle detection the same for the new graph builder
+            if ( e.getCause() instanceof ProjectCycleException )
+            {
+                result = addExceptionToResult( new DefaultMavenExecutionResult(), e.getCause() );
+            }
+            else
+            {
+                result = addExceptionToResult( new DefaultMavenExecutionResult(), new InternalErrorException(
+                                                                                                              "Internal error: "
+                                                                                                                  + e,
+                                                                                                              e ) );
+            }
         }
         finally
         {
@@ -140,17 +146,17 @@ public class DefaultMaven
     // 6) Get reactor projects looking for general POM errors
     //
     // 7) Create ProjectDependencyGraph using trimming which takes into account --projects and reactor mode.
-    //    This ensures that the projects passed into the ReactorReader are only those specified.
+    // This ensures that the projects passed into the ReactorReader are only those specified.
     //
     // 8) Create ReactorReader with the getProjectMap( projects ). NOTE that getProjectMap(projects) is the code that
-    //    checks for duplicate projects definitions in the build. Ideally this type of duplicate checking should be
-    //    part of getting the reactor projects in 6). The duplicate checking is conflated with getProjectMap(projects).
+    // checks for duplicate projects definitions in the build. Ideally this type of duplicate checking should be
+    // part of getting the reactor projects in 6). The duplicate checking is conflated with getProjectMap(projects).
     //
     // 9) Execute AbstractLifecycleParticipant.afterProjectsRead(session)
     //
     // 10) Create ProjectDependencyGraph without trimming (as trimming was done in 7). A new topological sort is
-    //     required after the execution of 9) as the AbstractLifecycleParticipants are free to mutate the MavenProject
-    //     instances, which may change dependencies which can, in turn, affect the build order.
+    // required after the execution of 9) as the AbstractLifecycleParticipants are free to mutate the MavenProject
+    // instances, which may change dependencies which can, in turn, affect the build order.
     //
     // 11) Execute LifecycleStarter.start()
     //
@@ -171,7 +177,8 @@ public class DefaultMaven
         }
 
         //
-        // We enter the session scope right after the MavenSession creation and before any of the AbstractLifecycleParticipant lookups
+        // We enter the session scope right after the MavenSession creation and before any of the
+        // AbstractLifecycleParticipant lookups
         // so that @SessionScoped components can be @Injected into AbstractLifecycleParticipants.
         //
         sessionScope.enter();
@@ -198,7 +205,8 @@ public class DefaultMaven
     {
         try
         {
-            for ( AbstractMavenLifecycleParticipant listener : getLifecycleParticipants( Collections.<MavenProject>emptyList() ) )
+            for ( AbstractMavenLifecycleParticipant listener : getLifecycleParticipants( Collections
+                .<MavenProject>emptyList() ) )
             {
                 listener.afterSessionStart( session );
             }
@@ -210,36 +218,15 @@ public class DefaultMaven
 
         eventCatapult.fire( ExecutionEvent.Type.ProjectDiscoveryStarted, session, null );
 
-        List<MavenProject> projects;
-        try
-        {
-            projects = getProjectsForMavenReactor( session );
-            //
-            // Capture the full set of projects before any potential constraining is performed by --projects
-            //
-            session.setAllProjects( projects );
-        }
-        catch ( ProjectBuildingException e )
-        {
-            return addExceptionToResult( result, e );
-        }
-
-        validateProjects( projects );
-
-        //
-        // This creates the graph and trims the projects down based on the user request using something like:
-        //
-        // -pl project0,project2 eclipse:eclipse
-        //
-        ProjectDependencyGraph projectDependencyGraph = createProjectDependencyGraph( projects, request, result, true );
-
-        if ( result.hasExceptions() )
+        Result<? extends ProjectDependencyGraph> graphResult = buildGraph( session, result );
+        
+        if ( graphResult.hasErrors() )
         {
-            return result;
+            return addExceptionToResult( result,
+                                         Iterables.toArray( graphResult.getProblems(), ModelProblem.class )[0]
+                                             .getException() );
         }
 
-        session.setProjects( projectDependencyGraph.getSortedProjects() );
-
         try
         {
             session.setProjectMap( getProjectMap( session.getProjects() ) );
@@ -274,7 +261,7 @@ public class DefaultMaven
         ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
         try
         {
-            for ( AbstractMavenLifecycleParticipant listener : getLifecycleParticipants( projects ) )
+            for ( AbstractMavenLifecycleParticipant listener : getLifecycleParticipants( session.getProjects() ) )
             {
                 Thread.currentThread().setContextClassLoader( listener.getClass().getClassLoader() );
 
@@ -298,7 +285,15 @@ public class DefaultMaven
         // Note that participants may affect the topological order of the projects but it is
         // not expected that a participant will add or remove projects from the session.
         //
-        projectDependencyGraph = createProjectDependencyGraph( session.getProjects(), request, result, false );
+        
+        graphResult = buildGraph( session, result );
+        
+        if ( graphResult.hasErrors() )
+        {
+            return addExceptionToResult( result,
+                                         Iterables.toArray( graphResult.getProblems(), ModelProblem.class )[0]
+                                             .getException() );
+        }
 
         try
         {
@@ -307,10 +302,6 @@ public class DefaultMaven
                 return result;
             }
 
-            session.setProjects( projectDependencyGraph.getSortedProjects() );
-
-            session.setProjectDependencyGraph( projectDependencyGraph );
-
             result.setTopologicallySortedProjects( session.getProjects() );
 
             result.setProject( session.getTopLevelProject() );
@@ -328,7 +319,7 @@ public class DefaultMaven
         {
             try
             {
-                afterSessionEnd( projects, session );
+                afterSessionEnd( session.getProjects(), session );
             }
             catch ( MavenExecutionException e )
             {
@@ -357,7 +348,7 @@ public class DefaultMaven
             Thread.currentThread().setContextClassLoader( originalClassLoader );
         }
     }
-
+    
     public RepositorySystemSession newRepositorySession( MavenExecutionRequest request )
     {
         return repositorySessionFactory.newRepositorySession( request );
@@ -380,8 +371,7 @@ public class DefaultMaven
 
     private Collection<AbstractMavenLifecycleParticipant> getLifecycleParticipants( Collection<MavenProject> projects )
     {
-        Collection<AbstractMavenLifecycleParticipant> lifecycleListeners =
-            new LinkedHashSet<AbstractMavenLifecycleParticipant>();
+        Collection<AbstractMavenLifecycleParticipant> lifecycleListeners = new LinkedHashSet<AbstractMavenLifecycleParticipant>();
 
         ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
         try
@@ -436,72 +426,22 @@ public class DefaultMaven
         return result;
     }
 
-    private List<MavenProject> getProjectsForMavenReactor( MavenSession session )
-        throws ProjectBuildingException
-    {
-        MavenExecutionRequest request = session.getRequest();
-
-        request.getProjectBuildingRequest().setRepositorySession( session.getRepositorySession() );
-
-        List<MavenProject> projects = new ArrayList<MavenProject>();
-
-        // We have no POM file.
-        //
-        if ( request.getPom() == null )
-        {
-            ModelSource modelSource = new UrlModelSource( DefaultMaven.class.getResource( "project/standalone.xml" ) );
-            MavenProject project =
-                projectBuilder.build( modelSource, request.getProjectBuildingRequest() ).getProject();
-            project.setExecutionRoot( true );
-            projects.add( project );
-            request.setProjectPresent( false );
-            return projects;
-        }
-
-        List<File> files = Arrays.asList( request.getPom().getAbsoluteFile() );
-        collectProjects( projects, files, request );
-        return projects;
-    }
-
-    private void collectProjects( List<MavenProject> projects, List<File> files, MavenExecutionRequest request )
-        throws ProjectBuildingException
+    private void validateActivatedProfiles( List<MavenProject> projects, List<String> activeProfileIds )
     {
-        ProjectBuildingRequest projectBuildingRequest = request.getProjectBuildingRequest();
-
-        List<ProjectBuildingResult> results =
-            projectBuilder.build( files, request.isRecursive(), projectBuildingRequest );
-
-        boolean problems = false;
+        Collection<String> notActivatedProfileIds = new LinkedHashSet<String>( activeProfileIds );
 
-        for ( ProjectBuildingResult result : results )
+        for ( MavenProject project : projects )
         {
-            projects.add( result.getProject() );
-
-            if ( !result.getProblems().isEmpty() && logger.isWarnEnabled() )
+            for ( List<String> profileIds : project.getInjectedProfileIds().values() )
             {
-                logger.warn( "" );
-                logger.warn( "Some problems were encountered while building the effective model for "
-                    + result.getProject().getId() );
-
-                for ( ModelProblem problem : result.getProblems() )
-                {
-                    String loc = ModelProblemUtils.formatLocation( problem, result.getProjectId() );
-                    logger.warn( problem.getMessage() + ( StringUtils.isNotEmpty( loc ) ? " @ " + loc : "" ) );
-                }
-
-                problems = true;
+                notActivatedProfileIds.removeAll( profileIds );
             }
         }
 
-        if ( problems )
+        for ( String notActivatedProfileId : notActivatedProfileIds )
         {
-            logger.warn( "" );
-            logger.warn( "It is highly recommended to fix these problems"
-                + " because they threaten the stability of your build." );
-            logger.warn( "" );
-            logger.warn( "For this reason, future Maven versions might no"
-                + " longer support building such malformed projects." );
-            logger.warn( "" );
+            logger.warn( "The requested profile \"" + notActivatedProfileId
+                + "\" could not be activated because it does not exist." );
         }
     }
 
@@ -547,330 +487,36 @@ public class DefaultMaven
         return index;
     }
 
-    private void validateProjects( List<MavenProject> projects )
+    private Result<? extends ProjectDependencyGraph> buildGraph( MavenSession session, MavenExecutionResult result ) 
     {
-        Map<String, MavenProject> projectsMap = new HashMap<String, MavenProject>();
-
-        for ( MavenProject p : projects )
+        Result<? extends ProjectDependencyGraph> graphResult = graphBuilder.build( session );
+        for ( ModelProblem problem : graphResult.getProblems() )
         {
-            String projectKey = ArtifactUtils.key( p.getGroupId(), p.getArtifactId(), p.getVersion() );
-
-            projectsMap.put( projectKey, p );
-        }
-
-        for ( MavenProject project : projects )
-        {
-            // MNG-1911 / MNG-5572: Building plugins with extensions cannot be part of reactor
-            for ( Plugin plugin : project.getBuildPlugins() )
+            if ( problem.getSeverity() == ModelProblem.Severity.WARNING )
             {
-                if ( plugin.isExtensions() )
-                {
-                    String pluginKey =
-                        ArtifactUtils.key( plugin.getGroupId(), plugin.getArtifactId(), plugin.getVersion() );
-
-                    if ( projectsMap.containsKey( pluginKey ) )
-                    {
-                        logger.warn( project.getName() + " uses " + plugin.getKey()
-                            + " as extensions, which is not possible within the same reactor build. "
-                            + "This plugin was pulled from the local repository!" );
-                    }
-                }
+                logger.warn( problem.toString() );
             }
-        }
-    }
-
-    private void validateActivatedProfiles( List<MavenProject> projects, List<String> activeProfileIds )
-    {
-        Collection<String> notActivatedProfileIds = new LinkedHashSet<String>( activeProfileIds );
-
-        for ( MavenProject project : projects )
-        {
-            for ( List<String> profileIds : project.getInjectedProfileIds().values() )
+            else
             {
-                notActivatedProfileIds.removeAll( profileIds );
+                logger.error( problem.toString() );
             }
         }
 
-        for ( String notActivatedProfileId : notActivatedProfileIds )
+        if ( !graphResult.hasErrors() )
         {
-            logger.warn( "The requested profile \"" + notActivatedProfileId
-                + "\" could not be activated because it does not exist." );
+            ProjectDependencyGraph projectDependencyGraph = graphResult.get();
+            session.setProjects( projectDependencyGraph.getSortedProjects() );
+            session.setAllProjects( projectDependencyGraph.getSortedProjects() );
+            session.setProjectDependencyGraph( projectDependencyGraph );                
         }
+        
+        return graphResult;        
     }
-
-    @Deprecated // 5 January 2014
+    
+    @Deprecated
+    // 5 January 2014
     protected Logger getLogger()
     {
         return logger;
     }
-
-    private ProjectDependencyGraph createProjectDependencyGraph( Collection<MavenProject> projects,
-                                                                 MavenExecutionRequest request,
-                                                                 MavenExecutionResult result, boolean trimming )
-    {
-        ProjectDependencyGraph projectDependencyGraph = null;
-
-        try
-        {
-            projectDependencyGraph = new DefaultProjectDependencyGraph( projects );
-
-            if ( trimming )
-            {
-                List<MavenProject> activeProjects = projectDependencyGraph.getSortedProjects();
-
-                activeProjects = trimSelectedProjects( activeProjects, projectDependencyGraph, request );
-                activeProjects = trimExcludedProjects( activeProjects,  request );
-                activeProjects = trimResumedProjects( activeProjects, request );
-
-                if ( activeProjects.size() != projectDependencyGraph.getSortedProjects().size() )
-                {
-                    projectDependencyGraph =
-                        new FilteredProjectDependencyGraph( projectDependencyGraph, activeProjects );
-                }
-            }
-        }
-        catch ( CycleDetectedException e )
-        {
-            String message = "The projects in the reactor contain a cyclic reference: " + e.getMessage();
-
-            ProjectCycleException error = new ProjectCycleException( message, e );
-
-            addExceptionToResult( result, error );
-        }
-        catch ( org.apache.maven.project.DuplicateProjectException e )
-        {
-            addExceptionToResult( result, e );
-        }
-        catch ( MavenExecutionException e )
-        {
-            addExceptionToResult( result, e );
-        }
-
-        return projectDependencyGraph;
-    }
-
-    private List<MavenProject> trimSelectedProjects( List<MavenProject> projects, ProjectDependencyGraph graph,
-                                                     MavenExecutionRequest request )
-        throws MavenExecutionException
-    {
-        List<MavenProject> result = projects;
-
-        if ( !request.getSelectedProjects().isEmpty() )
-        {
-            File reactorDirectory = null;
-            if ( request.getBaseDirectory() != null )
-            {
-                reactorDirectory = new File( request.getBaseDirectory() );
-            }
-
-            Collection<MavenProject> selectedProjects = new LinkedHashSet<MavenProject>( projects.size() );
-
-            for ( String selector : request.getSelectedProjects() )
-            {
-                MavenProject selectedProject = null;
-
-                for ( MavenProject project : projects )
-                {
-                    if ( isMatchingProject( project, selector, reactorDirectory ) )
-                    {
-                        selectedProject = project;
-                        break;
-                    }
-                }
-
-                if ( selectedProject != null )
-                {
-                    selectedProjects.add( selectedProject );
-                }
-                else
-                {
-                    throw new MavenExecutionException( "Could not find the selected project in the reactor: "
-                        + selector, request.getPom() );
-                }
-            }
-
-            boolean makeUpstream = false;
-            boolean makeDownstream = false;
-
-            if ( MavenExecutionRequest.REACTOR_MAKE_UPSTREAM.equals( request.getMakeBehavior() ) )
-            {
-                makeUpstream = true;
-            }
-            else if ( MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM.equals( request.getMakeBehavior() ) )
-            {
-                makeDownstream = true;
-            }
-            else if ( MavenExecutionRequest.REACTOR_MAKE_BOTH.equals( request.getMakeBehavior() ) )
-            {
-                makeUpstream = true;
-                makeDownstream = true;
-            }
-            else if ( StringUtils.isNotEmpty( request.getMakeBehavior() ) )
-            {
-                throw new MavenExecutionException( "Invalid reactor make behavior: " + request.getMakeBehavior(),
-                                                   request.getPom() );
-            }
-
-            if ( makeUpstream || makeDownstream )
-            {
-                for ( MavenProject selectedProject : new ArrayList<MavenProject>( selectedProjects ) )
-                {
-                    if ( makeUpstream )
-                    {
-                        selectedProjects.addAll( graph.getUpstreamProjects( selectedProject, true ) );
-                    }
-                    if ( makeDownstream )
-                    {
-                        selectedProjects.addAll( graph.getDownstreamProjects( selectedProject, true ) );
-                    }
-                }
-            }
-
-            result = new ArrayList<MavenProject>( selectedProjects.size() );
-
-            for ( MavenProject project : projects )
-            {
-                if ( selectedProjects.contains( project ) )
-                {
-                    result.add( project );
-                }
-            }
-        }
-
-        return result;
-    }
-
-    private List<MavenProject> trimExcludedProjects( List<MavenProject> projects, MavenExecutionRequest request )
-        throws MavenExecutionException
-    {
-        List<MavenProject> result = projects;
-
-        if ( !request.getExcludedProjects().isEmpty() )
-        {
-            File reactorDirectory = null;
-
-            if ( request.getBaseDirectory() != null )
-            {
-                reactorDirectory = new File( request.getBaseDirectory() );
-            }
-
-            Collection<MavenProject> excludedProjects = new LinkedHashSet<MavenProject>( projects.size() );
-
-            for ( String selector : request.getExcludedProjects() )
-            {
-                MavenProject excludedProject = null;
-
-                for ( MavenProject project : projects )
-                {
-                    if ( isMatchingProject( project, selector, reactorDirectory ) )
-                    {
-                        excludedProject = project;
-                        break;
-                    }
-                }
-
-                if ( excludedProject != null )
-                {
-                    excludedProjects.add( excludedProject );
-                }
-                else
-                {
-                    throw new MavenExecutionException( "Could not find the selected project in the reactor: "
-                        + selector, request.getPom() );
-                }
-            }
-
-            result = new ArrayList<MavenProject>( projects.size() );
-            for ( MavenProject project : projects )
-            {
-                if ( !excludedProjects.contains( project ) )
-                {
-                    result.add( project );
-                }
-            }
-        }
-
-        return result;
-    }
-
-    private List<MavenProject> trimResumedProjects( List<MavenProject> projects, MavenExecutionRequest request )
-        throws MavenExecutionException
-    {
-        List<MavenProject> result = projects;
-
-        if ( StringUtils.isNotEmpty( request.getResumeFrom() ) )
-        {
-            File reactorDirectory = null;
-            if ( request.getBaseDirectory() != null )
-            {
-                reactorDirectory = new File( request.getBaseDirectory() );
-            }
-
-            String selector = request.getResumeFrom();
-
-            result = new ArrayList<MavenProject>( projects.size() );
-
-            boolean resumed = false;
-
-            for ( MavenProject project : projects )
-            {
-                if ( !resumed && isMatchingProject( project, selector, reactorDirectory ) )
-                {
-                    resumed = true;
-                }
-
-                if ( resumed )
-                {
-                    result.add( project );
-                }
-            }
-
-            if ( !resumed )
-            {
-                throw new MavenExecutionException( "Could not find project to resume reactor build from: " + selector
-                    + " vs " + projects, request.getPom() );
-            }
-        }
-
-        return result;
-    }
-
-    private boolean isMatchingProject( MavenProject project, String selector, File reactorDirectory )
-    {
-        // [groupId]:artifactId
-        if ( selector.indexOf( ':' ) >= 0 )
-        {
-            String id = ':' + project.getArtifactId();
-
-            if ( id.equals( selector ) )
-            {
-                return true;
-            }
-
-            id = project.getGroupId() + id;
-
-            if ( id.equals( selector ) )
-            {
-                return true;
-            }
-        }
-
-        // relative path, e.g. "sub", "../sub" or "."
-        else if ( reactorDirectory != null )
-        {
-            File selectedProject = new File( new File( reactorDirectory, selector ).toURI().normalize() );
-
-            if ( selectedProject.isFile() )
-            {
-                return selectedProject.equals( project.getFile() );
-            }
-            else if ( selectedProject.isDirectory() )
-            {
-                return selectedProject.equals( project.getBasedir() );
-            }
-        }
-
-        return false;
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/maven/blob/be3fb200/maven-core/src/main/java/org/apache/maven/DefaultProjectDependencyGraph.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/DefaultProjectDependencyGraph.java b/maven-core/src/main/java/org/apache/maven/DefaultProjectDependencyGraph.java
deleted file mode 100644
index 4074e58..0000000
--- a/maven-core/src/main/java/org/apache/maven/DefaultProjectDependencyGraph.java
+++ /dev/null
@@ -1,134 +0,0 @@
-package org.apache.maven;
-
-/*
- * 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.
- */
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.maven.execution.ProjectDependencyGraph;
-import org.apache.maven.project.DuplicateProjectException;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.project.ProjectSorter;
-import org.codehaus.plexus.util.dag.CycleDetectedException;
-
-/**
- * Describes the inter-dependencies between projects in the reactor.
- *
- * @author Benjamin Bentmann
- */
-class DefaultProjectDependencyGraph
-    implements ProjectDependencyGraph
-{
-
-    private ProjectSorter sorter;
-
-    /**
-     * Creates a new project dependency graph based on the specified projects.
-     *
-     * @param projects The projects to create the dependency graph with
-     * @throws DuplicateProjectException
-     * @throws CycleDetectedException
-     */
-    public DefaultProjectDependencyGraph( Collection<MavenProject> projects )
-        throws CycleDetectedException, DuplicateProjectException
-    {
-        this.sorter = new ProjectSorter( projects );
-    }
-
-    public List<MavenProject> getSortedProjects()
-    {
-        return new ArrayList<MavenProject>( sorter.getSortedProjects() );
-    }
-
-    public List<MavenProject> getDownstreamProjects( MavenProject project, boolean transitive )
-    {
-        if ( project == null )
-        {
-            throw new IllegalArgumentException( "project missing" );
-        }
-
-        Set<String> projectIds = new HashSet<String>();
-
-        getDownstreamProjects( ProjectSorter.getId( project ), projectIds, transitive );
-
-        return getSortedProjects( projectIds );
-    }
-
-    private void getDownstreamProjects( String projectId, Set<String> projectIds, boolean transitive )
-    {
-        for ( String id : sorter.getDependents( projectId ) )
-        {
-            if ( projectIds.add( id ) && transitive )
-            {
-                getDownstreamProjects( id, projectIds, transitive );
-            }
-        }
-    }
-
-    public List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive )
-    {
-        if ( project == null )
-        {
-            throw new IllegalArgumentException( "project missing" );
-        }
-
-        Set<String> projectIds = new HashSet<String>();
-
-        getUpstreamProjects( ProjectSorter.getId( project ), projectIds, transitive );
-
-        return getSortedProjects( projectIds );
-    }
-
-    private void getUpstreamProjects( String projectId, Collection<String> projectIds, boolean transitive )
-    {
-        for ( String id : sorter.getDependencies( projectId ) )
-        {
-            if ( projectIds.add( id ) && transitive )
-            {
-                getUpstreamProjects( id, projectIds, transitive );
-            }
-        }
-    }
-
-    private List<MavenProject> getSortedProjects( Set<String> projectIds )
-    {
-        List<MavenProject> result = new ArrayList<MavenProject>( projectIds.size() );
-
-        for ( MavenProject mavenProject : sorter.getSortedProjects() )
-        {
-            if ( projectIds.contains( ProjectSorter.getId( mavenProject ) ) )
-            {
-                result.add( mavenProject );
-            }
-        }
-
-        return result;
-    }
-
-    @Override
-    public String toString()
-    {
-        return sorter.getSortedProjects().toString();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/maven/blob/be3fb200/maven-core/src/main/java/org/apache/maven/FilteredProjectDependencyGraph.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/FilteredProjectDependencyGraph.java b/maven-core/src/main/java/org/apache/maven/FilteredProjectDependencyGraph.java
deleted file mode 100644
index e5db6bd..0000000
--- a/maven-core/src/main/java/org/apache/maven/FilteredProjectDependencyGraph.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package org.apache.maven;
-
-/*
- * 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.
- */
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.IdentityHashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.maven.execution.ProjectDependencyGraph;
-import org.apache.maven.project.MavenProject;
-
-/**
- * Provides a sub view of another dependency graph.
- *
- * @author Benjamin Bentmann
- */
-class FilteredProjectDependencyGraph
-    implements ProjectDependencyGraph
-{
-
-    private ProjectDependencyGraph projectDependencyGraph;
-
-    private Map<MavenProject, ?> whiteList;
-
-    private List<MavenProject> sortedProjects;
-
-    /**
-     * Creates a new project dependency graph from the specified graph.
-     *
-     * @param projectDependencyGraph The project dependency graph to create a sub view from, must not be {@code null}.
-     * @param whiteList The projects on which the dependency view should focus, must not be {@code null}.
-     */
-    public FilteredProjectDependencyGraph( ProjectDependencyGraph projectDependencyGraph,
-                                           Collection<? extends MavenProject> whiteList )
-    {
-        if ( projectDependencyGraph == null )
-        {
-            throw new IllegalArgumentException( "project dependency graph missing" );
-        }
-
-        this.projectDependencyGraph = projectDependencyGraph;
-
-        this.whiteList = new IdentityHashMap<MavenProject, Object>();
-
-        for ( MavenProject project : whiteList )
-        {
-            this.whiteList.put( project, null );
-        }
-    }
-
-    public List<MavenProject> getSortedProjects()
-    {
-        if ( sortedProjects == null )
-        {
-            sortedProjects = applyFilter( projectDependencyGraph.getSortedProjects() );
-        }
-
-        return new ArrayList<MavenProject>( sortedProjects );
-    }
-
-    public List<MavenProject> getDownstreamProjects( MavenProject project, boolean transitive )
-    {
-        return applyFilter( projectDependencyGraph.getDownstreamProjects( project, transitive ) );
-    }
-
-    public List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive )
-    {
-        return applyFilter( projectDependencyGraph.getUpstreamProjects( project, transitive ) );
-    }
-
-    private List<MavenProject> applyFilter( Collection<? extends MavenProject> projects )
-    {
-        List<MavenProject> filtered = new ArrayList<MavenProject>( projects.size() );
-
-        for ( MavenProject project : projects )
-        {
-            if ( whiteList.containsKey( project ) )
-            {
-                filtered.add( project );
-            }
-        }
-
-        return filtered;
-    }
-
-    @Override
-    public String toString()
-    {
-        return getSortedProjects().toString();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/maven/blob/be3fb200/maven-core/src/main/java/org/apache/maven/ProjectCycleException.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/ProjectCycleException.java b/maven-core/src/main/java/org/apache/maven/ProjectCycleException.java
index cba4462..ecd8eca 100644
--- a/maven-core/src/main/java/org/apache/maven/ProjectCycleException.java
+++ b/maven-core/src/main/java/org/apache/maven/ProjectCycleException.java
@@ -27,6 +27,11 @@ import org.codehaus.plexus.util.dag.CycleDetectedException;
 public class ProjectCycleException
     extends BuildFailureException
 {
+    public ProjectCycleException( String message )
+    {
+        super( message );
+    }
+    
     public ProjectCycleException( String message, CycleDetectedException cause )
     {
         super( message, cause );

http://git-wip-us.apache.org/repos/asf/maven/blob/be3fb200/maven-core/src/main/java/org/apache/maven/ReactorReader.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/ReactorReader.java b/maven-core/src/main/java/org/apache/maven/ReactorReader.java
index 3aca28d..252bdd0 100644
--- a/maven-core/src/main/java/org/apache/maven/ReactorReader.java
+++ b/maven-core/src/main/java/org/apache/maven/ReactorReader.java
@@ -34,9 +34,10 @@ import javax.inject.Named;
 
 import org.apache.maven.artifact.ArtifactUtils;
 import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Model;
 import org.apache.maven.project.MavenProject;
+import org.apache.maven.repository.internal.MavenWorkspaceReader;
 import org.eclipse.aether.artifact.Artifact;
-import org.eclipse.aether.repository.WorkspaceReader;
 import org.eclipse.aether.repository.WorkspaceRepository;
 import org.eclipse.aether.util.artifact.ArtifactIdUtils;
 
@@ -49,7 +50,7 @@ import org.eclipse.aether.util.artifact.ArtifactIdUtils;
 @Named( ReactorReader.HINT )
 @SessionScoped
 class ReactorReader
-    implements WorkspaceReader
+    implements MavenWorkspaceReader
 {
     public static final String HINT = "reactor";
 
@@ -136,6 +137,14 @@ class ReactorReader
         return Collections.unmodifiableList( versions );
     }
 
+    @Override
+    public Model findModel( Artifact artifact )
+    {
+        String projectKey = ArtifactUtils.key( artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion() );
+        MavenProject project = projectsByGAV.get( projectKey );
+        return project == null ? null : project.getModel();
+    }
+
     //
     // Implementation
     //

http://git-wip-us.apache.org/repos/asf/maven/blob/be3fb200/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java b/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java
index e463079..5fdbd07 100644
--- a/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java
+++ b/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java
@@ -271,8 +271,10 @@ public class MavenSession
     {
         this.projectMap = projectMap;
     }
-
-    public Map<String, MavenProject> getProjectMap()
+    
+    @Deprecated
+    /** @deprecated This appears to only be used in the ReactorReader and we can do any processing required there */
+    public Map<String, MavenProject> getProjectMap() 
     {
         return projectMap;
     }
@@ -288,7 +290,7 @@ public class MavenSession
     {
         this.allProjects = allProjects;
     }
-
+    
     /*if_not[MAVEN4]*/
 
     //
@@ -433,5 +435,4 @@ public class MavenSession
     }   
     
     /*end[MAVEN4]*/
-    
 }

http://git-wip-us.apache.org/repos/asf/maven/blob/be3fb200/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java b/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java
new file mode 100644
index 0000000..0a602ba
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java
@@ -0,0 +1,487 @@
+package org.apache.maven.graph;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.DefaultMaven;
+import org.apache.maven.MavenExecutionException;
+import org.apache.maven.ProjectCycleException;
+import org.apache.maven.artifact.ArtifactUtils;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionResult;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.building.DefaultModelProblem;
+import org.apache.maven.model.building.ModelProblem;
+import org.apache.maven.model.building.ModelProblemUtils;
+import org.apache.maven.model.building.ModelSource;
+import org.apache.maven.model.building.Result;
+import org.apache.maven.model.building.UrlModelSource;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuilder;
+import org.apache.maven.project.ProjectBuildingException;
+import org.apache.maven.project.ProjectBuildingRequest;
+import org.apache.maven.project.ProjectBuildingResult;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.dag.CycleDetectedException;
+
+import com.google.common.collect.Lists;
+
+@Component( role = GraphBuilder.class, hint = GraphBuilder.HINT )
+public class DefaultGraphBuilder
+    implements GraphBuilder
+{
+    @Requirement
+    private Logger logger;
+
+    @Requirement
+    protected ProjectBuilder projectBuilder;
+
+    @Override
+    public Result<ProjectDependencyGraph> build( MavenSession session )
+    {
+        if ( session.getProjectDependencyGraph() != null )
+        {
+            return dependencyGraph( session, session.getProjects(), false );
+        }
+        
+        List<MavenProject> projects = session.getProjects();
+
+        if ( projects == null )
+        {
+            try
+            {
+                projects = getProjectsForMavenReactor( session );
+            }
+            catch ( ProjectBuildingException e )
+            {
+                return Result.error( Lists.newArrayList( new DefaultModelProblem( null, null, null, null, 0, 0, e ) ) );
+            }
+
+            validateProjects( projects );
+
+            return dependencyGraph( session, projects, true );
+        }
+        else
+        {
+            return dependencyGraph( session, projects, false );
+        }
+    }
+    
+    private Result<ProjectDependencyGraph> dependencyGraph( MavenSession session, List<MavenProject> projects,
+                                                            boolean applyMakeBehaviour )
+    {
+        MavenExecutionRequest request = session.getRequest();
+
+        ProjectDependencyGraph projectDependencyGraph = null;
+
+        try
+        {
+            projectDependencyGraph = new DefaultProjectDependencyGraph( projects );
+
+            if ( applyMakeBehaviour )
+            {
+                List<MavenProject> activeProjects = projectDependencyGraph.getSortedProjects();
+
+                activeProjects = trimSelectedProjects( activeProjects, projectDependencyGraph, request );
+                activeProjects = trimExcludedProjects( activeProjects, request );
+                activeProjects = trimResumedProjects( activeProjects, request );
+
+                if ( activeProjects.size() != projectDependencyGraph.getSortedProjects().size() )
+                {
+                    projectDependencyGraph = new FilteredProjectDependencyGraph( projectDependencyGraph, activeProjects );
+                }
+            }
+        }
+        catch ( CycleDetectedException e )
+        {
+            String message = "The projects in the reactor contain a cyclic reference: " + e.getMessage();
+            ProjectCycleException error = new ProjectCycleException( message, e );
+            return Result.error( Lists.newArrayList( new DefaultModelProblem( null, null, null, null, 0, 0, error ) ) );
+        }
+        catch ( org.apache.maven.project.DuplicateProjectException e )
+        {
+            return Result.error( Lists.newArrayList( new DefaultModelProblem( null, null, null, null, 0, 0, e ) ) );
+        }
+        catch ( MavenExecutionException e )
+        {
+            return Result.error( Lists.newArrayList( new DefaultModelProblem( null, null, null, null, 0, 0, e ) ) );
+        }
+
+        session.setProjects( projectDependencyGraph.getSortedProjects() );
+        session.setProjectDependencyGraph( projectDependencyGraph );
+
+        return Result.success( projectDependencyGraph );
+    }
+
+    private List<MavenProject> trimSelectedProjects( List<MavenProject> projects, ProjectDependencyGraph graph,
+                                                     MavenExecutionRequest request )
+        throws MavenExecutionException
+    {
+        List<MavenProject> result = projects;
+
+        if ( !request.getSelectedProjects().isEmpty() )
+        {
+            File reactorDirectory = null;
+            if ( request.getBaseDirectory() != null )
+            {
+                reactorDirectory = new File( request.getBaseDirectory() );
+            }
+
+            Collection<MavenProject> selectedProjects = new LinkedHashSet<MavenProject>( projects.size() );
+
+            for ( String selector : request.getSelectedProjects() )
+            {
+                MavenProject selectedProject = null;
+
+                for ( MavenProject project : projects )
+                {
+                    if ( isMatchingProject( project, selector, reactorDirectory ) )
+                    {
+                        selectedProject = project;
+                        break;
+                    }
+                }
+
+                if ( selectedProject != null )
+                {
+                    selectedProjects.add( selectedProject );
+                }
+                else
+                {
+                    throw new MavenExecutionException( "Could not find the selected project in the reactor: "
+                        + selector, request.getPom() );
+                }
+            }
+
+            boolean makeUpstream = false;
+            boolean makeDownstream = false;
+
+            if ( MavenExecutionRequest.REACTOR_MAKE_UPSTREAM.equals( request.getMakeBehavior() ) )
+            {
+                makeUpstream = true;
+            }
+            else if ( MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM.equals( request.getMakeBehavior() ) )
+            {
+                makeDownstream = true;
+            }
+            else if ( MavenExecutionRequest.REACTOR_MAKE_BOTH.equals( request.getMakeBehavior() ) )
+            {
+                makeUpstream = true;
+                makeDownstream = true;
+            }
+            else if ( StringUtils.isNotEmpty( request.getMakeBehavior() ) )
+            {
+                throw new MavenExecutionException( "Invalid reactor make behavior: " + request.getMakeBehavior(),
+                                                   request.getPom() );
+            }
+
+            if ( makeUpstream || makeDownstream )
+            {
+                for ( MavenProject selectedProject : new ArrayList<MavenProject>( selectedProjects ) )
+                {
+                    if ( makeUpstream )
+                    {
+                        selectedProjects.addAll( graph.getUpstreamProjects( selectedProject, true ) );
+                    }
+                    if ( makeDownstream )
+                    {
+                        selectedProjects.addAll( graph.getDownstreamProjects( selectedProject, true ) );
+                    }
+                }
+            }
+
+            result = new ArrayList<MavenProject>( selectedProjects.size() );
+
+            for ( MavenProject project : projects )
+            {
+                if ( selectedProjects.contains( project ) )
+                {
+                    result.add( project );
+                }
+            }
+        }
+
+        return result;
+    }
+
+    private List<MavenProject> trimExcludedProjects( List<MavenProject> projects, MavenExecutionRequest request )
+        throws MavenExecutionException
+    {
+        List<MavenProject> result = projects;
+
+        if ( !request.getExcludedProjects().isEmpty() )
+        {
+            File reactorDirectory = null;
+
+            if ( request.getBaseDirectory() != null )
+            {
+                reactorDirectory = new File( request.getBaseDirectory() );
+            }
+
+            Collection<MavenProject> excludedProjects = new LinkedHashSet<MavenProject>( projects.size() );
+
+            for ( String selector : request.getExcludedProjects() )
+            {
+                MavenProject excludedProject = null;
+
+                for ( MavenProject project : projects )
+                {
+                    if ( isMatchingProject( project, selector, reactorDirectory ) )
+                    {
+                        excludedProject = project;
+                        break;
+                    }
+                }
+
+                if ( excludedProject != null )
+                {
+                    excludedProjects.add( excludedProject );
+                }
+                else
+                {
+                    throw new MavenExecutionException( "Could not find the selected project in the reactor: "
+                        + selector, request.getPom() );
+                }
+            }
+
+            result = new ArrayList<MavenProject>( projects.size() );
+            for ( MavenProject project : projects )
+            {
+                if ( !excludedProjects.contains( project ) )
+                {
+                    result.add( project );
+                }
+            }
+        }
+
+        return result;
+    }
+
+    private List<MavenProject> trimResumedProjects( List<MavenProject> projects, MavenExecutionRequest request )
+        throws MavenExecutionException
+    {
+        List<MavenProject> result = projects;
+
+        if ( StringUtils.isNotEmpty( request.getResumeFrom() ) )
+        {
+            File reactorDirectory = null;
+            if ( request.getBaseDirectory() != null )
+            {
+                reactorDirectory = new File( request.getBaseDirectory() );
+            }
+
+            String selector = request.getResumeFrom();
+
+            result = new ArrayList<MavenProject>( projects.size() );
+
+            boolean resumed = false;
+
+            for ( MavenProject project : projects )
+            {
+                if ( !resumed && isMatchingProject( project, selector, reactorDirectory ) )
+                {
+                    resumed = true;
+                }
+
+                if ( resumed )
+                {
+                    result.add( project );
+                }
+            }
+
+            if ( !resumed )
+            {
+                throw new MavenExecutionException( "Could not find project to resume reactor build from: " + selector
+                    + " vs " + projects, request.getPom() );
+            }
+        }
+
+        return result;
+    }
+
+    private boolean isMatchingProject( MavenProject project, String selector, File reactorDirectory )
+    {
+        // [groupId]:artifactId
+        if ( selector.indexOf( ':' ) >= 0 )
+        {
+            String id = ':' + project.getArtifactId();
+
+            if ( id.equals( selector ) )
+            {
+                return true;
+            }
+
+            id = project.getGroupId() + id;
+
+            if ( id.equals( selector ) )
+            {
+                return true;
+            }
+        }
+
+        // relative path, e.g. "sub", "../sub" or "."
+        else if ( reactorDirectory != null )
+        {
+            File selectedProject = new File( new File( reactorDirectory, selector ).toURI().normalize() );
+
+            if ( selectedProject.isFile() )
+            {
+                return selectedProject.equals( project.getFile() );
+            }
+            else if ( selectedProject.isDirectory() )
+            {
+                return selectedProject.equals( project.getBasedir() );
+            }
+        }
+
+        return false;
+    }
+
+    private MavenExecutionResult addExceptionToResult( MavenExecutionResult result, Throwable e )
+    {
+        if ( !result.getExceptions().contains( e ) )
+        {
+            result.addException( e );
+        }
+
+        return result;
+    }
+
+    // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    //
+    // Project collection
+    //
+    // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+    private List<MavenProject> getProjectsForMavenReactor( MavenSession session )
+        throws ProjectBuildingException
+    {
+        MavenExecutionRequest request = session.getRequest();
+
+        request.getProjectBuildingRequest().setRepositorySession( session.getRepositorySession() );
+
+        List<MavenProject> projects = new ArrayList<MavenProject>();
+
+        // We have no POM file.
+        //
+        if ( request.getPom() == null )
+        {
+            ModelSource modelSource = new UrlModelSource( DefaultMaven.class.getResource( "project/standalone.xml" ) );
+            MavenProject project = projectBuilder.build( modelSource, request.getProjectBuildingRequest() )
+                .getProject();
+            project.setExecutionRoot( true );
+            projects.add( project );
+            request.setProjectPresent( false );
+            return projects;
+        }
+
+        List<File> files = Arrays.asList( request.getPom().getAbsoluteFile() );
+        collectProjects( projects, files, request );
+        return projects;
+    }
+
+    private void collectProjects( List<MavenProject> projects, List<File> files, MavenExecutionRequest request )
+        throws ProjectBuildingException
+    {
+        ProjectBuildingRequest projectBuildingRequest = request.getProjectBuildingRequest();
+
+        List<ProjectBuildingResult> results = projectBuilder.build( files, request.isRecursive(),
+                                                                    projectBuildingRequest );
+
+        boolean problems = false;
+
+        for ( ProjectBuildingResult result : results )
+        {
+            projects.add( result.getProject() );
+
+            if ( !result.getProblems().isEmpty() && logger.isWarnEnabled() )
+            {
+                logger.warn( "" );
+                logger.warn( "Some problems were encountered while building the effective model for "
+                    + result.getProject().getId() );
+
+                for ( ModelProblem problem : result.getProblems() )
+                {
+                    String loc = ModelProblemUtils.formatLocation( problem, result.getProjectId() );
+                    logger.warn( problem.getMessage() + ( StringUtils.isNotEmpty( loc ) ? " @ " + loc : "" ) );
+                }
+
+                problems = true;
+            }
+        }
+
+        if ( problems )
+        {
+            logger.warn( "" );
+            logger.warn( "It is highly recommended to fix these problems"
+                + " because they threaten the stability of your build." );
+            logger.warn( "" );
+            logger.warn( "For this reason, future Maven versions might no"
+                + " longer support building such malformed projects." );
+            logger.warn( "" );
+        }
+    }
+
+    private void validateProjects( List<MavenProject> projects )
+    {
+        Map<String, MavenProject> projectsMap = new HashMap<String, MavenProject>();
+
+        for ( MavenProject p : projects )
+        {
+            String projectKey = ArtifactUtils.key( p.getGroupId(), p.getArtifactId(), p.getVersion() );
+
+            projectsMap.put( projectKey, p );
+        }
+
+        for ( MavenProject project : projects )
+        {
+            // MNG-1911 / MNG-5572: Building plugins with extensions cannot be part of reactor
+            for ( Plugin plugin : project.getBuildPlugins() )
+            {
+                if ( plugin.isExtensions() )
+                {
+                    String pluginKey = ArtifactUtils.key( plugin.getGroupId(), plugin.getArtifactId(),
+                                                          plugin.getVersion() );
+
+                    if ( projectsMap.containsKey( pluginKey ) )
+                    {
+                        logger.warn( project.getName() + " uses " + plugin.getKey()
+                            + " as extensions, which is not possible within the same reactor build. "
+                            + "This plugin was pulled from the local repository!" );
+                    }
+                }
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven/blob/be3fb200/maven-core/src/main/java/org/apache/maven/graph/DefaultProjectDependencyGraph.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/graph/DefaultProjectDependencyGraph.java b/maven-core/src/main/java/org/apache/maven/graph/DefaultProjectDependencyGraph.java
new file mode 100644
index 0000000..01fec33
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/graph/DefaultProjectDependencyGraph.java
@@ -0,0 +1,134 @@
+package org.apache.maven.graph;
+
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.project.DuplicateProjectException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectSorter;
+import org.codehaus.plexus.util.dag.CycleDetectedException;
+
+/**
+ * Describes the inter-dependencies between projects in the reactor.
+ *
+ * @author Benjamin Bentmann
+ */
+public class DefaultProjectDependencyGraph
+    implements ProjectDependencyGraph
+{
+
+    private ProjectSorter sorter;
+
+    /**
+     * Creates a new project dependency graph based on the specified projects.
+     *
+     * @param projects The projects to create the dependency graph with
+     * @throws DuplicateProjectException
+     * @throws CycleDetectedException
+     */
+    public DefaultProjectDependencyGraph( Collection<MavenProject> projects )
+        throws CycleDetectedException, DuplicateProjectException
+    {
+        this.sorter = new ProjectSorter( projects );
+    }
+
+    public List<MavenProject> getSortedProjects()
+    {
+        return new ArrayList<MavenProject>( sorter.getSortedProjects() );
+    }
+
+    public List<MavenProject> getDownstreamProjects( MavenProject project, boolean transitive )
+    {
+        if ( project == null )
+        {
+            throw new IllegalArgumentException( "project missing" );
+        }
+
+        Set<String> projectIds = new HashSet<String>();
+
+        getDownstreamProjects( ProjectSorter.getId( project ), projectIds, transitive );
+
+        return getSortedProjects( projectIds );
+    }
+
+    private void getDownstreamProjects( String projectId, Set<String> projectIds, boolean transitive )
+    {
+        for ( String id : sorter.getDependents( projectId ) )
+        {
+            if ( projectIds.add( id ) && transitive )
+            {
+                getDownstreamProjects( id, projectIds, transitive );
+            }
+        }
+    }
+
+    public List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive )
+    {
+        if ( project == null )
+        {
+            throw new IllegalArgumentException( "project missing" );
+        }
+
+        Set<String> projectIds = new HashSet<String>();
+
+        getUpstreamProjects( ProjectSorter.getId( project ), projectIds, transitive );
+
+        return getSortedProjects( projectIds );
+    }
+
+    private void getUpstreamProjects( String projectId, Collection<String> projectIds, boolean transitive )
+    {
+        for ( String id : sorter.getDependencies( projectId ) )
+        {
+            if ( projectIds.add( id ) && transitive )
+            {
+                getUpstreamProjects( id, projectIds, transitive );
+            }
+        }
+    }
+
+    private List<MavenProject> getSortedProjects( Set<String> projectIds )
+    {
+        List<MavenProject> result = new ArrayList<MavenProject>( projectIds.size() );
+
+        for ( MavenProject mavenProject : sorter.getSortedProjects() )
+        {
+            if ( projectIds.contains( ProjectSorter.getId( mavenProject ) ) )
+            {
+                result.add( mavenProject );
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public String toString()
+    {
+        return sorter.getSortedProjects().toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven/blob/be3fb200/maven-core/src/main/java/org/apache/maven/graph/FilteredProjectDependencyGraph.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/graph/FilteredProjectDependencyGraph.java b/maven-core/src/main/java/org/apache/maven/graph/FilteredProjectDependencyGraph.java
new file mode 100644
index 0000000..662bda4
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/graph/FilteredProjectDependencyGraph.java
@@ -0,0 +1,111 @@
+package org.apache.maven.graph;
+
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Provides a sub view of another dependency graph.
+ *
+ * @author Benjamin Bentmann
+ */
+class FilteredProjectDependencyGraph
+    implements ProjectDependencyGraph
+{
+
+    private ProjectDependencyGraph projectDependencyGraph;
+
+    private Map<MavenProject, ?> whiteList;
+
+    private List<MavenProject> sortedProjects;
+
+    /**
+     * Creates a new project dependency graph from the specified graph.
+     *
+     * @param projectDependencyGraph The project dependency graph to create a sub view from, must not be {@code null}.
+     * @param whiteList The projects on which the dependency view should focus, must not be {@code null}.
+     */
+    public FilteredProjectDependencyGraph( ProjectDependencyGraph projectDependencyGraph,
+                                           Collection<? extends MavenProject> whiteList )
+    {
+        if ( projectDependencyGraph == null )
+        {
+            throw new IllegalArgumentException( "project dependency graph missing" );
+        }
+
+        this.projectDependencyGraph = projectDependencyGraph;
+
+        this.whiteList = new IdentityHashMap<MavenProject, Object>();
+
+        for ( MavenProject project : whiteList )
+        {
+            this.whiteList.put( project, null );
+        }
+    }
+
+    public List<MavenProject> getSortedProjects()
+    {
+        if ( sortedProjects == null )
+        {
+            sortedProjects = applyFilter( projectDependencyGraph.getSortedProjects() );
+        }
+
+        return new ArrayList<MavenProject>( sortedProjects );
+    }
+
+    public List<MavenProject> getDownstreamProjects( MavenProject project, boolean transitive )
+    {
+        return applyFilter( projectDependencyGraph.getDownstreamProjects( project, transitive ) );
+    }
+
+    public List<MavenProject> getUpstreamProjects( MavenProject project, boolean transitive )
+    {
+        return applyFilter( projectDependencyGraph.getUpstreamProjects( project, transitive ) );
+    }
+
+    private List<MavenProject> applyFilter( Collection<? extends MavenProject> projects )
+    {
+        List<MavenProject> filtered = new ArrayList<MavenProject>( projects.size() );
+
+        for ( MavenProject project : projects )
+        {
+            if ( whiteList.containsKey( project ) )
+            {
+                filtered.add( project );
+            }
+        }
+
+        return filtered;
+    }
+
+    @Override
+    public String toString()
+    {
+        return getSortedProjects().toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven/blob/be3fb200/maven-core/src/main/java/org/apache/maven/graph/GraphBuilder.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/graph/GraphBuilder.java b/maven-core/src/main/java/org/apache/maven/graph/GraphBuilder.java
new file mode 100644
index 0000000..fb7c4f2
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/graph/GraphBuilder.java
@@ -0,0 +1,31 @@
+package org.apache.maven.graph;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.execution.ProjectDependencyGraph;
+import org.apache.maven.model.building.Result;
+
+public interface GraphBuilder
+{
+    String HINT = "graphBuilder";
+
+    Result<? extends ProjectDependencyGraph> build( MavenSession session );
+}

http://git-wip-us.apache.org/repos/asf/maven/blob/be3fb200/maven-core/src/main/java/org/apache/maven/project/DefaultModelBuildingListener.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultModelBuildingListener.java b/maven-core/src/main/java/org/apache/maven/project/DefaultModelBuildingListener.java
index 262cf09..a536562 100644
--- a/maven-core/src/main/java/org/apache/maven/project/DefaultModelBuildingListener.java
+++ b/maven-core/src/main/java/org/apache/maven/project/DefaultModelBuildingListener.java
@@ -37,7 +37,7 @@ import org.apache.maven.plugin.version.PluginVersionResolutionException;
  *
  * @author Benjamin Bentmann
  */
-class DefaultModelBuildingListener
+public class DefaultModelBuildingListener
     extends AbstractModelBuildingListener
 {
 

http://git-wip-us.apache.org/repos/asf/maven/blob/be3fb200/maven-core/src/main/java/org/apache/maven/project/MavenProject.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/project/MavenProject.java b/maven-core/src/main/java/org/apache/maven/project/MavenProject.java
index 641ebda..a14aaa1 100644
--- a/maven-core/src/main/java/org/apache/maven/project/MavenProject.java
+++ b/maven-core/src/main/java/org/apache/maven/project/MavenProject.java
@@ -1171,7 +1171,7 @@ public class MavenProject
         return clone;
     }
 
-    protected void setModel( Model model )
+    public void setModel( Model model )
     {
         this.model = model;
     }

http://git-wip-us.apache.org/repos/asf/maven/blob/be3fb200/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java
----------------------------------------------------------------------
diff --git a/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java b/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java
index c64dd73..77e7c49 100644
--- a/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java
+++ b/maven-core/src/main/java/org/apache/maven/project/ProjectModelResolver.java
@@ -28,6 +28,7 @@ import java.util.Set;
 
 import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
+
 import org.apache.maven.model.Parent;
 import org.apache.maven.model.Repository;
 import org.apache.maven.model.building.FileModelSource;
@@ -55,7 +56,7 @@ import org.eclipse.aether.resolution.VersionRangeResult;
  *
  * @author Benjamin Bentmann
  */
-class ProjectModelResolver
+public class ProjectModelResolver
     implements ModelResolver
 {
 

http://git-wip-us.apache.org/repos/asf/maven/blob/be3fb200/maven-core/src/test/java/org/apache/maven/DefaultProjectDependencyGraphTest.java
----------------------------------------------------------------------
diff --git a/maven-core/src/test/java/org/apache/maven/DefaultProjectDependencyGraphTest.java b/maven-core/src/test/java/org/apache/maven/DefaultProjectDependencyGraphTest.java
deleted file mode 100644
index 668dafb..0000000
--- a/maven-core/src/test/java/org/apache/maven/DefaultProjectDependencyGraphTest.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
- * agreements. See the NOTICE file distributed with this work for additional information regarding
- * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the License. You may obtain a
- * copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.apache.maven;
-
-import junit.framework.TestCase;
-import org.apache.maven.execution.ProjectDependencyGraph;
-import org.apache.maven.model.Dependency;
-import org.apache.maven.project.DuplicateProjectException;
-import org.apache.maven.project.MavenProject;
-import org.codehaus.plexus.util.dag.CycleDetectedException;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * @author Kristian Rosenvold
- */
-public class DefaultProjectDependencyGraphTest
-    extends TestCase
-{
-
-    private final MavenProject aProject = createA();
-
-    private final MavenProject depender1 = createProject( Arrays.asList( toDependency( aProject ) ), "depender1" );
-
-    private final MavenProject depender2 = createProject( Arrays.asList( toDependency( aProject ) ), "depender2" );
-
-    private final MavenProject depender3 = createProject( Arrays.asList( toDependency( aProject ) ), "depender3" );
-
-    private final MavenProject depender4 =
-        createProject( Arrays.asList( toDependency( aProject ), toDependency( depender3 ) ), "depender4" );
-
-    private final MavenProject transitiveOnly =
-        createProject( Arrays.asList( toDependency( depender3 ) ), "depender5" );
-
-    public void testGetSortedProjects()
-        throws DuplicateProjectException, CycleDetectedException
-    {
-        ProjectDependencyGraph graph = new DefaultProjectDependencyGraph( Arrays.asList( depender1, aProject ) );
-        final List<MavenProject> sortedProjects = graph.getSortedProjects();
-        assertEquals( aProject, sortedProjects.get( 0 ) );
-        assertEquals( depender1, sortedProjects.get( 1 ) );
-    }
-
-    public void testVerifyExpectedParentStructure()
-        throws CycleDetectedException, DuplicateProjectException
-    {
-        // This test verifies the baseline structure used in susequent tests. If this fails, the rest will fail.
-        ProjectDependencyGraph graph = threeProjectsDependingOnASingle();
-        final List<MavenProject> sortedProjects = graph.getSortedProjects();
-        assertEquals( aProject, sortedProjects.get( 0 ) );
-        assertEquals( depender1, sortedProjects.get( 1 ) );
-        assertEquals( depender2, sortedProjects.get( 2 ) );
-        assertEquals( depender3, sortedProjects.get( 3 ) );
-    }
-
-    public void testVerifyThatDownsteamProjectsComeInSortedOrder()
-        throws CycleDetectedException, DuplicateProjectException
-    {
-        final List<MavenProject> downstreamProjects =
-            threeProjectsDependingOnASingle().getDownstreamProjects( aProject, true );
-        assertEquals( depender1, downstreamProjects.get( 0 ) );
-        assertEquals( depender2, downstreamProjects.get( 1 ) );
-        assertEquals( depender3, downstreamProjects.get( 2 ) );
-    }
-
-    public void testTransitivesInOrder()
-        throws CycleDetectedException, DuplicateProjectException
-    {
-        final ProjectDependencyGraph graph =
-            new DefaultProjectDependencyGraph( Arrays.asList( depender1, depender4, depender2, depender3, aProject ) );
-
-        final List<MavenProject> downstreamProjects = graph.getDownstreamProjects( aProject, true );
-        assertEquals( depender1, downstreamProjects.get( 0 ) );
-        assertEquals( depender3, downstreamProjects.get( 1 ) );
-        assertEquals( depender4, downstreamProjects.get( 2 ) );
-        assertEquals( depender2, downstreamProjects.get( 3 ) );
-    }
-
-    public void testNonTransitivesInOrder()
-        throws CycleDetectedException, DuplicateProjectException
-    {
-        final ProjectDependencyGraph graph =
-            new DefaultProjectDependencyGraph( Arrays.asList( depender1, depender4, depender2, depender3, aProject ) );
-
-        final List<MavenProject> downstreamProjects = graph.getDownstreamProjects( aProject, false );
-        assertEquals( depender1, downstreamProjects.get( 0 ) );
-        assertEquals( depender3, downstreamProjects.get( 1 ) );
-        assertEquals( depender4, downstreamProjects.get( 2 ) );
-        assertEquals( depender2, downstreamProjects.get( 3 ) );
-    }
-
-    public void testWithTranistiveOnly()
-        throws CycleDetectedException, DuplicateProjectException
-    {
-        final ProjectDependencyGraph graph = new DefaultProjectDependencyGraph(
-            Arrays.asList( depender1, transitiveOnly, depender2, depender3, aProject ) );
-
-        final List<MavenProject> downstreamProjects = graph.getDownstreamProjects( aProject, true );
-        assertEquals( depender1, downstreamProjects.get( 0 ) );
-        assertEquals( depender3, downstreamProjects.get( 1 ) );
-        assertEquals( transitiveOnly, downstreamProjects.get( 2 ) );
-        assertEquals( depender2, downstreamProjects.get( 3 ) );
-    }
-
-    public void testWithMissingTranistiveOnly()
-        throws CycleDetectedException, DuplicateProjectException
-    {
-        final ProjectDependencyGraph graph = new DefaultProjectDependencyGraph(
-            Arrays.asList( depender1, transitiveOnly, depender2, depender3, aProject ) );
-
-        final List<MavenProject> downstreamProjects = graph.getDownstreamProjects( aProject, false );
-        assertEquals( depender1, downstreamProjects.get( 0 ) );
-        assertEquals( depender3, downstreamProjects.get( 1 ) );
-        assertEquals( depender2, downstreamProjects.get( 2 ) );
-    }
-
-    public void testGetUpstreamProjects()
-        throws CycleDetectedException, DuplicateProjectException
-    {
-        ProjectDependencyGraph graph = threeProjectsDependingOnASingle();
-        final List<MavenProject> downstreamProjects = graph.getUpstreamProjects( depender1, true );
-        assertEquals( aProject, downstreamProjects.get( 0 ) );
-    }
-
-    private ProjectDependencyGraph threeProjectsDependingOnASingle()
-        throws CycleDetectedException, DuplicateProjectException
-    {
-        return new DefaultProjectDependencyGraph( Arrays.asList( depender1, depender2, depender3, aProject ) );
-    }
-
-    private static MavenProject createA()
-    {
-        MavenProject result = new MavenProject();
-        result.setGroupId( "org.apache" );
-        result.setArtifactId( "A" );
-        result.setVersion( "1.2" );
-        return result;
-    }
-
-    static Dependency toDependency( MavenProject mavenProject )
-    {
-        final Dependency dependency = new Dependency();
-        dependency.setArtifactId( mavenProject.getArtifactId() );
-        dependency.setGroupId( mavenProject.getGroupId() );
-        dependency.setVersion( mavenProject.getVersion() );
-        return dependency;
-    }
-
-    private static MavenProject createProject( List<Dependency> dependencies, String artifactId )
-    {
-        MavenProject result = new MavenProject();
-        result.setGroupId( "org.apache" );
-        result.setArtifactId( artifactId );
-        result.setVersion( "1.2" );
-        result.setDependencies( dependencies );
-        return result;
-    }
-
-}
\ No newline at end of file