You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@maven.apache.org by GitBox <gi...@apache.org> on 2018/11/27 19:22:13 UTC

[GitHub] rfscholte closed pull request #107: Fixes to various JIRA issues.

rfscholte closed pull request #107:  Fixes to various JIRA issues.
URL: https://github.com/apache/maven/pull/107
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/apache-maven/pom.xml b/apache-maven/pom.xml
index 166a14e97f..d72b2f8f34 100644
--- a/apache-maven/pom.xml
+++ b/apache-maven/pom.xml
@@ -25,7 +25,7 @@ under the License.
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.5.4-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>apache-maven</artifactId>
diff --git a/maven-artifact/pom.xml b/maven-artifact/pom.xml
index ab842fad67..503e0977db 100644
--- a/maven-artifact/pom.xml
+++ b/maven-artifact/pom.xml
@@ -25,7 +25,7 @@ under the License.
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.5.4-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-artifact</artifactId>
diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java b/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java
index 1167e91a53..3fa1907c31 100644
--- a/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java
+++ b/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java
@@ -273,7 +273,7 @@ public void addMetadata( ArtifactMetadata metadata )
             return Collections.emptyList();
         }
 
-        return metadataMap.values();
+        return Collections.unmodifiableCollection( metadataMap.values() );
     }
 
     // ----------------------------------------------------------------------
diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/VersionRange.java b/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/VersionRange.java
index 56343b2f6d..e9196213fb 100644
--- a/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/VersionRange.java
+++ b/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/VersionRange.java
@@ -262,7 +262,7 @@ public VersionRange restrict( VersionRange restriction )
         }
         else
         {
-            restrictions = intersection( r1, r2 );
+            restrictions = Collections.unmodifiableList( intersection( r1, r2 ) );
         }
 
         ArtifactVersion version = null;
diff --git a/maven-builder-support/pom.xml b/maven-builder-support/pom.xml
index ab4fb0804b..5cc3d8dea2 100644
--- a/maven-builder-support/pom.xml
+++ b/maven-builder-support/pom.xml
@@ -25,7 +25,7 @@ under the License.
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.5.4-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-builder-support</artifactId>
diff --git a/maven-compat/pom.xml b/maven-compat/pom.xml
index eaa3abff85..648ef8c3c5 100644
--- a/maven-compat/pom.xml
+++ b/maven-compat/pom.xml
@@ -25,7 +25,7 @@ under the License.
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.5.4-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-compat</artifactId>
diff --git a/maven-compat/src/main/java/org/apache/maven/artifact/repository/DefaultArtifactRepository.java b/maven-compat/src/main/java/org/apache/maven/artifact/repository/DefaultArtifactRepository.java
index f5db5ef634..16b82c5070 100644
--- a/maven-compat/src/main/java/org/apache/maven/artifact/repository/DefaultArtifactRepository.java
+++ b/maven-compat/src/main/java/org/apache/maven/artifact/repository/DefaultArtifactRepository.java
@@ -256,7 +256,7 @@ public void setMirroredRepositories( List<ArtifactRepository> mirroredRepositori
     {
         if ( mirroredRepositories != null )
         {
-            this.mirroredRepositories = mirroredRepositories;
+            this.mirroredRepositories = Collections.unmodifiableList( mirroredRepositories );
         }
         else
         {
diff --git a/maven-compat/src/main/java/org/apache/maven/repository/MetadataResolutionResult.java b/maven-compat/src/main/java/org/apache/maven/repository/MetadataResolutionResult.java
index 70b9c3fdc5..7be1d96950 100644
--- a/maven-compat/src/main/java/org/apache/maven/repository/MetadataResolutionResult.java
+++ b/maven-compat/src/main/java/org/apache/maven/repository/MetadataResolutionResult.java
@@ -118,7 +118,10 @@ public boolean hasMissingArtifacts()
 
     public List<Artifact> getMissingArtifacts()
     {
-        return missingArtifacts == null ? Collections.<Artifact>emptyList() : missingArtifacts;
+        return missingArtifacts == null
+                   ? Collections.<Artifact>emptyList()
+                   : Collections.unmodifiableList( missingArtifacts );
+
     }
 
     public MetadataResolutionResult addMissingArtifact( Artifact artifact )
@@ -148,7 +151,10 @@ public boolean hasExceptions()
 
     public List<Exception> getExceptions()
     {
-        return exceptions == null ? Collections.<Exception>emptyList() : exceptions;
+        return exceptions == null
+                   ? Collections.<Exception>emptyList()
+                   : Collections.unmodifiableList( exceptions );
+
     }
 
     // ------------------------------------------------------------------------
@@ -185,7 +191,10 @@ public OverConstrainedVersionException getVersionRangeViolation( int i )
 
     public List<Exception> getVersionRangeViolations()
     {
-        return versionRangeViolations == null ? Collections.<Exception>emptyList() : versionRangeViolations;
+        return versionRangeViolations == null
+                   ? Collections.<Exception>emptyList()
+                   : Collections.unmodifiableList( versionRangeViolations );
+
     }
 
     // ------------------------------------------------------------------------
@@ -217,8 +226,10 @@ public ArtifactResolutionException getMetadataResolutionException( int i )
 
     public List<ArtifactResolutionException> getMetadataResolutionExceptions()
     {
-        return metadataResolutionExceptions == null ? Collections.<ArtifactResolutionException>emptyList()
-                        : metadataResolutionExceptions;
+        return metadataResolutionExceptions == null
+                   ? Collections.<ArtifactResolutionException>emptyList()
+                   : Collections.unmodifiableList( metadataResolutionExceptions );
+
     }
 
     // ------------------------------------------------------------------------
@@ -246,7 +257,7 @@ public MetadataResolutionResult addError( Exception e )
             return Collections.emptyList();
         }
 
-        return errorArtifactExceptions;
+        return Collections.unmodifiableList( errorArtifactExceptions );
     }
 
     // ------------------------------------------------------------------------
@@ -283,7 +294,7 @@ public CyclicDependencyException getCircularDependencyException( int i )
             return Collections.emptyList();
         }
 
-        return circularDependencyExceptions;
+        return Collections.unmodifiableList( circularDependencyExceptions );
     }
 
     // ------------------------------------------------------------------------
@@ -297,7 +308,7 @@ public CyclicDependencyException getCircularDependencyException( int i )
             return Collections.emptyList();
         }
 
-        return repositories;
+        return Collections.unmodifiableList( repositories );
     }
 
     public MetadataResolutionResult setRepositories( final List<ArtifactRepository> repositories )
diff --git a/maven-compat/src/test/java/org/apache/maven/artifact/AbstractArtifactComponentTestCase.java b/maven-compat/src/test/java/org/apache/maven/artifact/AbstractArtifactComponentTestCase.java
index 0cdea195d7..5d84746f99 100644
--- a/maven-compat/src/test/java/org/apache/maven/artifact/AbstractArtifactComponentTestCase.java
+++ b/maven-compat/src/test/java/org/apache/maven/artifact/AbstractArtifactComponentTestCase.java
@@ -19,6 +19,14 @@
  * under the License.
  */
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.maven.artifact.factory.ArtifactFactory;
 import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
@@ -39,7 +47,7 @@
 import org.eclipse.aether.collection.DependencyTraverser;
 import org.eclipse.aether.internal.impl.SimpleLocalRepositoryManagerFactory;
 import org.eclipse.aether.repository.LocalRepository;
-import org.eclipse.aether.util.graph.manager.ClassicDependencyManager;
+import org.eclipse.aether.util.graph.manager.DefaultDependencyManager;
 import org.eclipse.aether.util.graph.selector.AndDependencySelector;
 import org.eclipse.aether.util.graph.selector.ExclusionDependencySelector;
 import org.eclipse.aether.util.graph.selector.OptionalDependencySelector;
@@ -54,14 +62,6 @@
 import org.eclipse.aether.util.graph.traverser.FatArtifactTraverser;
 import org.eclipse.aether.util.repository.SimpleArtifactDescriptorPolicy;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.List;
-
 /**
  * @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
  */
@@ -349,7 +349,7 @@ protected RepositorySystemSession initRepoSession()
         DependencyTraverser depTraverser = new FatArtifactTraverser();
         session.setDependencyTraverser( depTraverser );
 
-        DependencyManager depManager = new ClassicDependencyManager();
+        DependencyManager depManager = new DefaultDependencyManager();
         session.setDependencyManager( depManager );
 
         DependencySelector depFilter = new AndDependencySelector( new ScopeDependencySelector( "test", "provided" ),
diff --git a/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecyclePluginAnalyzer.java b/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecyclePluginAnalyzer.java
index 672e07b35e..16a0675b52 100644
--- a/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecyclePluginAnalyzer.java
+++ b/maven-compat/src/test/java/org/apache/maven/project/EmptyLifecyclePluginAnalyzer.java
@@ -24,6 +24,8 @@
 import java.util.Set;
 
 import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
 import org.apache.maven.model.Plugin;
 import org.apache.maven.model.PluginExecution;
 
@@ -33,6 +35,7 @@
 public class EmptyLifecyclePluginAnalyzer
     implements LifeCyclePluginAnalyzer
 {
+
     public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging )
     {
         Set<Plugin> plugins;
@@ -57,6 +60,26 @@
         return plugins;
     }
 
+    @Override
+    public Model getLifecycleModel( final Model model )
+    {
+        if ( model == null )
+        {
+            throw new NullPointerException( "model" );
+        }
+
+        final Model lifecycleModel = new Model();
+        lifecycleModel.setBuild( new Build() );
+        lifecycleModel.getBuild().setPluginManagement( model.getBuild() != null
+                                                           ? model.getBuild().getPluginManagement()
+                                                           : null );
+
+        lifecycleModel.getBuild().getPlugins().
+            addAll( this.getPluginsBoundByDefaultToAllLifecycles( model.getPackaging() ) );
+
+        return lifecycleModel;
+    }
+
     private Plugin newPlugin( String artifactId, String... goals )
     {
         Plugin plugin = new Plugin();
diff --git a/maven-compat/src/test/java/org/apache/maven/project/inheritance/t10/ProjectInheritanceTest.java b/maven-compat/src/test/java/org/apache/maven/project/inheritance/t10/ProjectInheritanceTest.java
index c785176224..246f6d8b95 100644
--- a/maven-compat/src/test/java/org/apache/maven/project/inheritance/t10/ProjectInheritanceTest.java
+++ b/maven-compat/src/test/java/org/apache/maven/project/inheritance/t10/ProjectInheritanceTest.java
@@ -87,8 +87,7 @@ public void testDependencyManagementOverridesTransitiveDependencyVersion()
         // transitive dep, overridden b depMgmt
         assertTrue("Incorrect scope for " + b.getDependencyConflictId(), b.getScope().equals("runtime"));
 
-        // direct dep, overrides depMgmt
+        // child depMgmt overrides parent depMgmt
         assertTrue("Incorrect scope for " + c.getDependencyConflictId(), c.getScope().equals("runtime"));
-
     }
 }
\ No newline at end of file
diff --git a/maven-compat/src/test/resources/inheritance-repo/t04/p0/p1/pom.xml b/maven-compat/src/test/resources/inheritance-repo/t04/p0/p1/pom.xml
index c25fc3e738..d7320a7089 100644
--- a/maven-compat/src/test/resources/inheritance-repo/t04/p0/p1/pom.xml
+++ b/maven-compat/src/test/resources/inheritance-repo/t04/p0/p1/pom.xml
@@ -14,6 +14,16 @@
     <url>scm-url</url>
   </scm>
 
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>maven-test</groupId>
+        <artifactId>t04-c</artifactId>
+        <version>1.0</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
   <dependencies>
 
     <dependency>
@@ -24,7 +34,6 @@
     <dependency>
       <groupId>maven-test</groupId>
       <artifactId>t04-c</artifactId>
-      <version>1.0</version>
     </dependency>
 
   </dependencies>
diff --git a/maven-compat/src/test/resources/inheritance-repo/t06/p0/p1/pom.xml b/maven-compat/src/test/resources/inheritance-repo/t06/p0/p1/pom.xml
index 468621901e..2ac95449d3 100644
--- a/maven-compat/src/test/resources/inheritance-repo/t06/p0/p1/pom.xml
+++ b/maven-compat/src/test/resources/inheritance-repo/t06/p0/p1/pom.xml
@@ -24,8 +24,6 @@
         <groupId>maven-test</groupId>
         <artifactId>t06-d</artifactId>
         <version>1.0</version>
-        <scope>test</scope>
-        <optional>false</optional>
       </dependency>
     </dependencies>
   </dependencyManagement>
diff --git a/maven-compat/src/test/resources/inheritance-repo/t06/p0/pom.xml b/maven-compat/src/test/resources/inheritance-repo/t06/p0/pom.xml
index 60c540ca12..6a66cd16c2 100644
--- a/maven-compat/src/test/resources/inheritance-repo/t06/p0/pom.xml
+++ b/maven-compat/src/test/resources/inheritance-repo/t06/p0/pom.xml
@@ -29,8 +29,6 @@
         <groupId>maven-test</groupId>
         <artifactId>t06-d</artifactId>
         <version>1.2</version>
-        <scope>test</scope>
-        <optional>false</optional>
       </dependency>
     </dependencies>
   </dependencyManagement>
diff --git a/maven-compat/src/test/resources/inheritance-repo/t10/p0/p1/pom.xml b/maven-compat/src/test/resources/inheritance-repo/t10/p0/p1/pom.xml
index ed82ae1344..15d7230be0 100644
--- a/maven-compat/src/test/resources/inheritance-repo/t10/p0/p1/pom.xml
+++ b/maven-compat/src/test/resources/inheritance-repo/t10/p0/p1/pom.xml
@@ -14,6 +14,17 @@
     <url>scm-url</url>
   </scm>
 
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>maven-test</groupId>
+        <artifactId>t10-c</artifactId>
+        <version>1.0</version>
+        <scope>runtime</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
   <dependencies>
 
     <dependency>
@@ -24,7 +35,6 @@
     <dependency>
       <groupId>maven-test</groupId>
       <artifactId>t10-c</artifactId>
-      <scope>runtime</scope>
     </dependency>
 
   </dependencies>
diff --git a/maven-core/pom.xml b/maven-core/pom.xml
index 6fd47c5c3a..03c6a237e0 100644
--- a/maven-core/pom.xml
+++ b/maven-core/pom.xml
@@ -25,7 +25,7 @@ under the License.
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.5.4-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-core</artifactId>
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 7f052c139d..548a39c2c1 100644
--- a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
+++ b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
@@ -232,25 +232,30 @@ private MavenExecutionResult doExecute( MavenExecutionRequest request, MavenSess
             return addExceptionToResult( result, e );
         }
 
-        WorkspaceReader reactorWorkspace;
-        try
-        {
-            reactorWorkspace = container.lookup( WorkspaceReader.class, ReactorReader.HINT );
-        }
-        catch ( ComponentLookupException e )
+        // As of Maven 3.4.0, workspace resolution can be disabled. See MNG-5738.
+        if ( !request.isUseLegacyReactorResolution() )
         {
-            return addExceptionToResult( result, e );
-        }
+            WorkspaceReader reactorWorkspace;
+            try
+            {
+                reactorWorkspace = container.lookup( WorkspaceReader.class, ReactorReader.HINT );
+            }
+            catch ( ComponentLookupException e )
+            {
+                return addExceptionToResult( result, e );
+            }
 
-        //
-        // Desired order of precedence for local artifact repositories
-        //
-        // Reactor
-        // Workspace
-        // User Local Repository
-        //
-        repoSession.setWorkspaceReader( ChainedWorkspaceReader.newInstance( reactorWorkspace,
-                                                                            repoSession.getWorkspaceReader() ) );
+            //
+            // Desired order of precedence for local artifact repositories
+            //
+            // Reactor
+            // Workspace
+            // User Local Repository
+            //
+            repoSession.setWorkspaceReader( ChainedWorkspaceReader.newInstance( reactorWorkspace,
+                                                                                repoSession.getWorkspaceReader() ) );
+
+        }
 
         repoSession.setReadOnly();
 
diff --git a/maven-core/src/main/java/org/apache/maven/RepositoryUtils.java b/maven-core/src/main/java/org/apache/maven/RepositoryUtils.java
index c1e21c44be..4723eb1e18 100644
--- a/maven-core/src/main/java/org/apache/maven/RepositoryUtils.java
+++ b/maven-core/src/main/java/org/apache/maven/RepositoryUtils.java
@@ -119,12 +119,16 @@ public static void toArtifacts( Collection<org.apache.maven.artifact.Artifact> a
 
             List<String> nodeTrail = new ArrayList<>( trail.size() + 1 );
             nodeTrail.addAll( trail );
-            nodeTrail.add( artifact.getId() );
 
-            if ( filter == null || filter.accept( node, Collections.<DependencyNode>emptyList() ) )
+            if ( artifact != null )
             {
-                artifact.setDependencyTrail( nodeTrail );
-                artifacts.add( artifact );
+                nodeTrail.add( artifact.getId() );
+
+                if ( filter == null || filter.accept( node, Collections.<DependencyNode>emptyList() ) )
+                {
+                    artifact.setDependencyTrail( nodeTrail );
+                    artifacts.add( artifact );
+                }
             }
 
             toArtifacts( artifacts, node.getChildren(), nodeTrail, filter );
diff --git a/maven-core/src/main/java/org/apache/maven/artifact/repository/MavenArtifactRepository.java b/maven-core/src/main/java/org/apache/maven/artifact/repository/MavenArtifactRepository.java
index d4c64f0bf7..f04007ee6e 100644
--- a/maven-core/src/main/java/org/apache/maven/artifact/repository/MavenArtifactRepository.java
+++ b/maven-core/src/main/java/org/apache/maven/artifact/repository/MavenArtifactRepository.java
@@ -405,7 +405,7 @@ public void setMirroredRepositories( List<ArtifactRepository> mirroredRepositori
     {
         if ( mirroredRepositories != null )
         {
-            this.mirroredRepositories = mirroredRepositories;
+            this.mirroredRepositories = Collections.unmodifiableList( mirroredRepositories );
         }
         else
         {
diff --git a/maven-core/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionResult.java b/maven-core/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionResult.java
index 6de04f3cbd..ffae1d3560 100644
--- a/maven-core/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionResult.java
+++ b/maven-core/src/main/java/org/apache/maven/artifact/resolver/ArtifactResolutionResult.java
@@ -130,7 +130,10 @@ public boolean hasMissingArtifacts()
 
     public List<Artifact> getMissingArtifacts()
     {
-        return missingArtifacts == null ? Collections.<Artifact>emptyList() : missingArtifacts;
+        return missingArtifacts == null
+                   ? Collections.<Artifact>emptyList()
+                   : Collections.unmodifiableList( missingArtifacts );
+
     }
 
     public ArtifactResolutionResult addMissingArtifact( Artifact artifact )
@@ -165,7 +168,10 @@ public boolean hasExceptions()
 
     public List<Exception> getExceptions()
     {
-        return exceptions == null ? Collections.<Exception>emptyList() : exceptions;
+        return exceptions == null
+                   ? Collections.<Exception>emptyList()
+                   : Collections.unmodifiableList( exceptions );
+
     }
 
     // ------------------------------------------------------------------------
@@ -202,7 +208,10 @@ public OverConstrainedVersionException getVersionRangeViolation( int i )
 
     public List<Exception> getVersionRangeViolations()
     {
-        return versionRangeViolations == null ? Collections.<Exception>emptyList() : versionRangeViolations;
+        return versionRangeViolations == null
+                   ? Collections.<Exception>emptyList()
+                   : Collections.unmodifiableList( versionRangeViolations );
+
     }
 
     // ------------------------------------------------------------------------
@@ -234,8 +243,10 @@ public ArtifactResolutionException getMetadataResolutionException( int i )
 
     public List<ArtifactResolutionException> getMetadataResolutionExceptions()
     {
-        return metadataResolutionExceptions == null ? Collections.<ArtifactResolutionException>emptyList()
-                        : metadataResolutionExceptions;
+        return metadataResolutionExceptions == null
+                   ? Collections.<ArtifactResolutionException>emptyList()
+                   : Collections.unmodifiableList( metadataResolutionExceptions );
+
     }
 
     // ------------------------------------------------------------------------
@@ -267,7 +278,7 @@ public ArtifactResolutionResult addErrorArtifactException( ArtifactResolutionExc
             return Collections.emptyList();
         }
 
-        return errorArtifactExceptions;
+        return Collections.unmodifiableList( errorArtifactExceptions );
     }
 
     // ------------------------------------------------------------------------
@@ -304,7 +315,7 @@ public CyclicDependencyException getCircularDependencyException( int i )
             return Collections.emptyList();
         }
 
-        return circularDependencyExceptions;
+        return Collections.unmodifiableList( circularDependencyExceptions );
     }
 
     // ------------------------------------------------------------------------
@@ -318,7 +329,7 @@ public CyclicDependencyException getCircularDependencyException( int i )
             return Collections.emptyList();
         }
 
-        return repositories;
+        return Collections.unmodifiableList( repositories );
     }
 
     public ArtifactResolutionResult setRepositories( final List<ArtifactRepository> repositories )
diff --git a/maven-core/src/main/java/org/apache/maven/artifact/resolver/ResolutionNode.java b/maven-core/src/main/java/org/apache/maven/artifact/resolver/ResolutionNode.java
index a156871de0..8e47d2e0b4 100644
--- a/maven-core/src/main/java/org/apache/maven/artifact/resolver/ResolutionNode.java
+++ b/maven-core/src/main/java/org/apache/maven/artifact/resolver/ResolutionNode.java
@@ -102,6 +102,7 @@ public void addDependencies( Set<Artifact> artifacts, List<ArtifactRepository> r
 
                 children.add( new ResolutionNode( a, remoteRepositories, this ) );
             }
+            children = Collections.unmodifiableList( children );
         }
         else
         {
diff --git a/maven-core/src/main/java/org/apache/maven/bridge/MavenRepositorySystem.java b/maven-core/src/main/java/org/apache/maven/bridge/MavenRepositorySystem.java
index 84ad93c923..72f57a01fb 100644
--- a/maven-core/src/main/java/org/apache/maven/bridge/MavenRepositorySystem.java
+++ b/maven-core/src/main/java/org/apache/maven/bridge/MavenRepositorySystem.java
@@ -574,8 +574,8 @@ public ArtifactRepository createDefaultRemoteRepository( MavenExecutionRequest r
         throws Exception
     {
         return createRepository( RepositorySystem.DEFAULT_REMOTE_REPO_URL, RepositorySystem.DEFAULT_REMOTE_REPO_ID,
-                                 true, ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY, false,
-                                 ArtifactRepositoryPolicy.UPDATE_POLICY_DAILY,
+                                 true, ArtifactRepositoryPolicy.UPDATE_POLICY_NEVER, false,
+                                 ArtifactRepositoryPolicy.UPDATE_POLICY_NEVER,
                                  ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN );
     }
     
diff --git a/maven-core/src/main/java/org/apache/maven/exception/ExceptionSummary.java b/maven-core/src/main/java/org/apache/maven/exception/ExceptionSummary.java
index dcc376a4b9..6615af61ce 100644
--- a/maven-core/src/main/java/org/apache/maven/exception/ExceptionSummary.java
+++ b/maven-core/src/main/java/org/apache/maven/exception/ExceptionSummary.java
@@ -53,7 +53,10 @@ public ExceptionSummary( Throwable exception, String message, String reference,
         this.exception = exception;
         this.message = ( message != null ) ? message : "";
         this.reference = ( reference != null ) ? reference : "";
-        this.children = ( children != null ) ? children : Collections.<ExceptionSummary>emptyList();
+        this.children = ( children != null )
+                            ? Collections.unmodifiableList( children )
+                            : Collections.<ExceptionSummary>emptyList();
+
     }
 
     public Throwable getException()
diff --git a/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java b/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java
index fe558cd338..291686a0b1 100644
--- a/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java
+++ b/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java
@@ -163,6 +163,8 @@
 
     private Map<String, Object> data;
 
+    private boolean useLegacyReactorResolution = false;
+
     public DefaultMavenExecutionRequest()
     {
     }
@@ -207,6 +209,7 @@ public static MavenExecutionRequest copy( MavenExecutionRequest original )
         copy.setNoSnapshotUpdates( original.isNoSnapshotUpdates() );
         copy.setExecutionListener( original.getExecutionListener() );
         copy.setUseLegacyLocalRepository( original.isUseLegacyLocalRepository() );
+        copy.setUseLegacyReactorResolution( original.isUseLegacyReactorResolution() );
         copy.setBuilderId( original.getBuilderId() );
         return copy;
     }
@@ -1219,6 +1222,17 @@ public MavenExecutionRequest setUseLegacyLocalRepository( boolean useLegacyLocal
     }
 
     @Override
+    public boolean isUseLegacyReactorResolution()
+    {
+        return this.useLegacyReactorResolution;
+    }
+
+    public MavenExecutionRequest setUseLegacyReactorResolution( boolean value )
+    {
+        this.useLegacyReactorResolution = value;
+        return this;
+    }
+
     public MavenExecutionRequest setBuilderId( String builderId )
     {
         this.builderId = builderId;
diff --git a/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionResult.java b/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionResult.java
index 87d8676627..112a064923 100644
--- a/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionResult.java
+++ b/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionResult.java
@@ -64,8 +64,10 @@ public MavenExecutionResult setTopologicallySortedProjects( List<MavenProject> t
 
     public List<MavenProject> getTopologicallySortedProjects()
     {
-        return null == topologicallySortedProjects ? Collections.<MavenProject>emptyList()
-                        : topologicallySortedProjects;
+        return null == topologicallySortedProjects
+                   ? Collections.<MavenProject>emptyList()
+                   : Collections.unmodifiableList( topologicallySortedProjects );
+
     }
 
     public DependencyResolutionResult getDependencyResolutionResult()
diff --git a/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java b/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java
index d006a434c5..3c8bda1786 100644
--- a/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java
+++ b/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java
@@ -442,4 +442,15 @@
      * @since 3.3.0
      */
     Map<String, Object> getData();
+
+    /**
+     * @since 3.4.0
+     */
+    boolean isUseLegacyReactorResolution();
+
+    /**
+     * @since 3.4.0
+     */
+    MavenExecutionRequest setUseLegacyReactorResolution( boolean value );
+
 }
diff --git a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java
index 248a3b6dd1..69fa723ba9 100644
--- a/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java
+++ b/maven-core/src/main/java/org/apache/maven/internal/aether/DefaultRepositorySystemSessionFactory.java
@@ -93,6 +93,7 @@
     @Inject
     MavenRepositorySystem mavenRepositorySystem;
 
+    @SuppressWarnings( "checkstyle:methodlength" )
     public DefaultRepositorySystemSession newRepositorySession( MavenExecutionRequest request )
     {
         DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
@@ -152,7 +153,12 @@ else if ( request.isUpdateSnapshots() )
             session.setLocalRepositoryManager( repoSystem.newLocalRepositoryManager( session, localRepo ) );
         }
 
-        if ( request.getWorkspaceReader() != null )
+        // As of Maven 3.4.0, workspace resolution can be disabled. See MNG-5738.
+        if ( request.isUseLegacyReactorResolution() )
+        {
+            session.setWorkspaceReader( null );
+        }
+        else if ( request.getWorkspaceReader() != null )
         {
             session.setWorkspaceReader( request.getWorkspaceReader() );
         }
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java b/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java
index dae18948ac..d7174b22f6 100644
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java
@@ -19,6 +19,11 @@
  * under the License.
  */
 
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.lifecycle.internal.LifecycleExecutionPlanCalculator;
 import org.apache.maven.lifecycle.internal.LifecycleStarter;
@@ -42,11 +47,6 @@
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.component.annotations.Requirement;
 
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * A facade that provides lifecycle services to components outside maven core.
  *
@@ -88,19 +88,13 @@ public void execute( MavenSession session )
     @Requirement
     private MojoDescriptorCreator mojoDescriptorCreator;
 
-    // These methods deal with construction intact Plugin object that look like they come from a standard
-    // <plugin/> block in a Maven POM. We have to do some wiggling to pull the sources of information
-    // together and this really shows the problem of constructing a sensible default configuration but
-    // it's all encapsulated here so it appears normalized to the POM builder.
-
-    // We are going to take the project packaging and find all plugin in the default lifecycle and create
-    // fully populated Plugin objects, including executions with goals and default configuration taken
-    // from the plugin.xml inside a plugin.
-    //
-    // TODO This whole method could probably removed by injecting lifeCyclePluginAnalyzer straight into client site.
-    // TODO But for some reason the whole plexus appcontext refuses to start when I try this.
-
+    /**
+     * @deprecated As of Maven 3.6.0, please use
+     * {@link LifeCyclePluginAnalyzer#getLifecycleModel(org.apache.maven.model.Model)}.
+     */
+    @Deprecated
     public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging )
+        throws LifecycleMappingNotFoundException
     {
         return lifeCyclePluginAnalyzer.getPluginsBoundByDefaultToAllLifecycles( packaging );
     }
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java b/maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java
index ed07c1d5e7..d2b3895150 100644
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java
@@ -20,6 +20,8 @@
  */
 
 import java.util.Set;
+
+import org.apache.maven.model.Model;
 import org.apache.maven.model.Plugin;
 
 /**
@@ -28,5 +30,31 @@
  */
 public interface LifeCyclePluginAnalyzer
 {
-    Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging );
+
+    /**
+     * @deprecated As of Maven 3.6.0, replaced by method {@link #getLifecycleModel(org.apache.maven.model.Model)}.
+     */
+    @Deprecated
+    Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging )
+        throws LifecycleMappingNotFoundException;
+
+    /**
+     * Gets the lifecycle {@code Model} for a given {@code Model}.
+     * <p>
+     * The lifecycle model for a given model is the list of default build plugins plus lifecycle plugin execution
+     * management.
+     * </p>
+     *
+     * @param model The {@code Model} to get the lifecycle {@code Model} for.
+     *
+     * @return The lifecycle {@code Model} for {@code model}.
+     *
+     * @throws NullPointerException if {@code model} is {@code null}.
+     * @throws LifecycleMappingNotFoundException if {@code model} declares an unsupported packaging.
+     *
+     * @since 3.6.0
+     */
+    Model getLifecycleModel( Model model )
+        throws LifecycleMappingNotFoundException;
+
 }
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java
index 04c602cfe2..a3d639fc47 100644
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutor.java
@@ -19,6 +19,9 @@
  * under the License.
  */
 
+import java.util.List;
+import java.util.Set;
+
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.model.Plugin;
 import org.apache.maven.plugin.InvalidPluginDescriptorException;
@@ -32,13 +35,10 @@
 import org.apache.maven.plugin.version.PluginVersionResolutionException;
 import org.apache.maven.project.MavenProject;
 
-import java.util.List;
-import java.util.Set;
-
 /**
  * A facade that provides lifecycle services to components outside Maven core.
  *
- * @author Jason van  Zyl
+ * @author Jason van Zyl
  */
 public interface LifecycleExecutor
 {
@@ -47,21 +47,13 @@
     @Deprecated
     String ROLE = LifecycleExecutor.class.getName();
 
-    // For a given project packaging find all the plugins that are bound to any registered
-    // lifecycles. The project builder needs to now what default plugin information needs to be
-    // merged into POM being built. Once the POM builder has this plugin information, versions can be assigned
-    // by the POM builder because they will have to be defined in plugin management. Once this is setComplete then it
-    // can be passed back so that the default configuration information can be populated.
-    //
-    // We need to know the specific version so that we can lookup the right version of the plugin descriptor
-    // which tells us what the default configuration is.
-    //
-
     /**
-     * @return The plugins bound to the lifecycles of the specified packaging or {@code null} if the packaging is
-     *         unknown.
+     * @deprecated As of Maven 3.6.0, please use
+     * {@link LifeCyclePluginAnalyzer#getLifecycleModel(org.apache.maven.model.Model)}.
      */
-    Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging );
+    @Deprecated
+    Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging )
+        throws LifecycleMappingNotFoundException;
 
     MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks )
         throws PluginNotFoundException, PluginResolutionException, PluginDescriptorParsingException,
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleMappingNotFoundException.java b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleMappingNotFoundException.java
new file mode 100644
index 0000000000..8bed701726
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleMappingNotFoundException.java
@@ -0,0 +1,45 @@
+package org.apache.maven.lifecycle;
+
+/*
+ * 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.
+ */
+
+/**
+ * Signals a failure to locate a lifecycle mapping.
+ *
+ * @author Christian Schulte
+ *
+ * @since 3.6.0
+ */
+public final class LifecycleMappingNotFoundException extends Exception
+{
+
+    private String packaging;
+
+    public LifecycleMappingNotFoundException( final String packaging )
+    {
+        super( String.format( "No lifecycle mapping found for packaging '%s'.", packaging ) );
+        this.packaging = packaging;
+    }
+
+    public String getPackaging()
+    {
+        return this.packaging;
+    }
+
+}
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecyclePluginAnalyzer.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecyclePluginAnalyzer.java
index 14653b7d25..b3eb4ce8a8 100644
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecyclePluginAnalyzer.java
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/DefaultLifecyclePluginAnalyzer.java
@@ -19,32 +19,36 @@
  * under the License.
  */
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import org.apache.maven.lifecycle.DefaultLifecycles;
 import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer;
 import org.apache.maven.lifecycle.Lifecycle;
+import org.apache.maven.lifecycle.LifecycleMappingNotFoundException;
 import org.apache.maven.lifecycle.mapping.LifecycleMapping;
 import org.apache.maven.lifecycle.mapping.LifecycleMojo;
 import org.apache.maven.lifecycle.mapping.LifecyclePhase;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
 import org.apache.maven.model.Plugin;
 import org.apache.maven.model.PluginExecution;
+import org.apache.maven.model.PluginManagement;
 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.xml.Xpp3Dom;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * <strong>NOTE:</strong> This class is not part of any public api and can be changed or deleted without prior notice.
- * 
+ *
  * @since 3.0
  * @author Benjamin Bentmann
  * @author Jason van Zyl
@@ -69,64 +73,117 @@ public DefaultLifecyclePluginAnalyzer()
     {
     }
 
+    // -----------------------------------------------------------------------------------------------------------------
+    // Comment regarding these methods moved here from LifecycleExecuter:
+    // -----------------------------------------------------------------------------------------------------------------
+    // For a given project packaging find all the plugins that are bound to any registered
+    // lifecycles. The project builder needs to now what default plugin information needs to be
+    // merged into POM being built. Once the POM builder has this plugin information, versions can be assigned
+    // by the POM builder because they will have to be defined in plugin management. Once this is setComplete then it
+    // can be passed back so that the default configuration information can be populated.
+    //
+    // We need to know the specific version so that we can lookup the right version of the plugin descriptor
+    // which tells us what the default configuration is.
+    // -----------------------------------------------------------------------------------------------------------------
+    // Comment regarding these methods moved here from DefaultLifecycleExecutor:
+    // -----------------------------------------------------------------------------------------------------------------
     // These methods deal with construction intact Plugin object that look like they come from a standard
     // <plugin/> block in a Maven POM. We have to do some wiggling to pull the sources of information
     // together and this really shows the problem of constructing a sensible default configuration but
     // it's all encapsulated here so it appears normalized to the POM builder.
-
     // We are going to take the project packaging and find all plugins in the default lifecycle and create
     // fully populated Plugin objects, including executions with goals and default configuration taken
     // from the plugin.xml inside a plugin.
-    //
-
+    @Override
+    @Deprecated
     public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging )
+        throws LifecycleMappingNotFoundException
+    {
+        if ( packaging == null )
+        {
+            throw new NullPointerException( "packaging" );
+        }
+
+        final Model model = new Model();
+        model.setPackaging( packaging );
+
+        final Set<Plugin> plugins = new HashSet<>( this.getLifecycleModel( model ).getBuild().getPlugins() );
+        return Collections.unmodifiableSet( plugins );
+    }
+
+    @Override
+    public Model getLifecycleModel( final Model model )
+        throws LifecycleMappingNotFoundException
     {
+        if ( model == null )
+        {
+            throw new NullPointerException( "model" );
+        }
+
+        final PluginManagement pluginManagement =
+            model.getBuild() != null && model.getBuild().getPluginManagement() != null
+                ? model.getBuild().getPluginManagement().clone()
+                : null;
+
+        final Model lifecycleModel = new Model();
+        lifecycleModel.setBuild( new Build() );
+        lifecycleModel.getBuild().setPluginManagement( pluginManagement != null
+                                                           ? pluginManagement.clone()
+                                                           : new PluginManagement() );
+
+        for ( final Plugin managedPlugin : lifecycleModel.getBuild().getPluginManagement().getPlugins() )
+        {
+            managedPlugin.getExecutions().clear();
+        }
+
         if ( logger.isDebugEnabled() )
         {
-            logger.debug( "Looking up lifecycle mappings for packaging " + packaging + " from "
-                + Thread.currentThread().getContextClassLoader() );
+            logger.debug( "Looking up lifecycle mappings for packaging " + model.getPackaging() + " from "
+                              + Thread.currentThread().getContextClassLoader() );
+
         }
 
-        LifecycleMapping lifecycleMappingForPackaging = lifecycleMappings.get( packaging );
+        final LifecycleMapping lifecycleMappingForPackaging = this.lifecycleMappings.get( model.getPackaging() );
 
         if ( lifecycleMappingForPackaging == null )
         {
-            return null;
+            throw new LifecycleMappingNotFoundException( model.getPackaging() );
         }
 
-        Map<Plugin, Plugin> plugins = new LinkedHashMap<>();
+        final Map<Plugin, Plugin> plugins = new LinkedHashMap<>();
 
         for ( Lifecycle lifecycle : getOrderedLifecycles() )
         {
-            org.apache.maven.lifecycle.mapping.Lifecycle lifecycleConfiguration =
+            final org.apache.maven.lifecycle.mapping.Lifecycle lifecycleConfiguration =
                 lifecycleMappingForPackaging.getLifecycles().get( lifecycle.getId() );
 
-            Map<String, LifecyclePhase> phaseToGoalMapping = null;
-
-            if ( lifecycleConfiguration != null )
-            {
-                phaseToGoalMapping = lifecycleConfiguration.getLifecyclePhases();
-            }
-            else if ( lifecycle.getDefaultLifecyclePhases() != null )
-            {
-                phaseToGoalMapping = lifecycle.getDefaultLifecyclePhases();
-            }
+            final Map<String, LifecyclePhase> phaseToGoalMapping =
+                lifecycleConfiguration != null
+                    ? lifecycleConfiguration.getLifecyclePhases()
+                    : lifecycle.getDefaultLifecyclePhases() != null
+                          ? lifecycle.getDefaultLifecyclePhases()
+                          : null;
 
             if ( phaseToGoalMapping != null )
             {
-                for ( Map.Entry<String, LifecyclePhase> goalsForLifecyclePhase : phaseToGoalMapping.entrySet() )
+                for ( final Map.Entry<String, LifecyclePhase> goalsForLifecyclePhase : phaseToGoalMapping.entrySet() )
                 {
-                    String phase = goalsForLifecyclePhase.getKey();
-                    LifecyclePhase goals = goalsForLifecyclePhase.getValue();
+                    final String phase = goalsForLifecyclePhase.getKey();
+                    final LifecyclePhase goals = goalsForLifecyclePhase.getValue();
+
                     if ( goals != null )
                     {
-                        parseLifecyclePhaseDefinitions( plugins, phase, goals );
+                        parseLifecyclePhaseDefinitions( plugins, phase, goals, lifecycle, lifecycleModel,
+                                                        pluginManagement );
+
                     }
                 }
             }
         }
 
-        return plugins.keySet();
+        lifecycleModel.getBuild().getPlugins().addAll( plugins.keySet() );
+
+        return lifecycleModel;
     }
 
     private List<Lifecycle> getOrderedLifecycles()
@@ -136,42 +193,45 @@ else if ( lifecycle.getDefaultLifecyclePhases() != null )
         List<Lifecycle> lifecycles = new ArrayList<>( defaultLifeCycles.getLifeCycles() );
 
         Collections.sort( lifecycles, new Comparator<Lifecycle>()
-        {
+                      {
 
-            public int compare( Lifecycle l1, Lifecycle l2 )
-            {
-                return l1.getId().compareTo( l2.getId() );
-            }
+                          @Override
+                          public int compare( Lifecycle l1, Lifecycle l2 )
+                          {
+                              return l1.getId().compareTo( l2.getId() );
+                          }
 
-        } );
+                      } );
 
         return lifecycles;
     }
 
-    private void parseLifecyclePhaseDefinitions( Map<Plugin, Plugin> plugins, String phase, LifecyclePhase goals )
+    private void parseLifecyclePhaseDefinitions( Map<Plugin, Plugin> plugins, String phase, LifecyclePhase goals,
+                                                 final Lifecycle lifecycle, final Model lifecycleModel,
+                                                 final PluginManagement pluginManagement )
     {
         List<LifecycleMojo> mojos = goals.getMojos();
+
         if ( mojos != null )
         {
-            
             for ( int i = 0; i < mojos.size(); i++ )
             {
                 LifecycleMojo mojo = mojos.get( i );
-                
+
                 GoalSpec gs = parseGoalSpec( mojo.getGoal() );
-    
+
                 if ( gs == null )
                 {
                     logger.warn( "Ignored invalid goal specification '" + mojo.getGoal()
-                            + "' from lifecycle mapping for phase " + phase );
+                                     + "' from lifecycle mapping for phase '" + phase + "'" );
                     continue;
                 }
-    
+
                 Plugin plugin = new Plugin();
                 plugin.setGroupId( gs.groupId );
                 plugin.setArtifactId( gs.artifactId );
                 plugin.setVersion( gs.version );
-    
+
                 Plugin existing = plugins.get( plugin );
                 if ( existing != null )
                 {
@@ -185,7 +245,7 @@ private void parseLifecyclePhaseDefinitions( Map<Plugin, Plugin> plugins, String
                 {
                     plugins.put( plugin, plugin );
                 }
-    
+
                 PluginExecution execution = new PluginExecution();
                 execution.setId( getExecutionId( plugin, gs.goal ) );
                 execution.setPhase( phase );
@@ -200,6 +260,38 @@ private void parseLifecyclePhaseDefinitions( Map<Plugin, Plugin> plugins, String
 
                 plugin.setDependencies( mojo.getDependencies() );
                 plugin.getExecutions().add( execution );
+
+                if ( pluginManagement != null )
+                {
+                    final Plugin managedPlugin = this.getManagedPlugin( pluginManagement, plugin );
+
+                    if ( managedPlugin != null )
+                    {
+                        final List<PluginExecution> defaultExecutions =
+                            new ArrayList<>( managedPlugin.getExecutions().size() );
+
+                        for ( final PluginExecution pluginExecution : managedPlugin.getExecutions() )
+                        {
+                            // What if the plugin's default phase (== null) is not from the lifecyle?
+                            if ( pluginExecution.getPhase() == null
+                                     || lifecycle.getPhases().contains( pluginExecution.getPhase() ) )
+                            {
+                                defaultExecutions.add( pluginExecution );
+                            }
+                        }
+
+                        final Plugin defaultManagedPlugin =
+                            this.getManagedPlugin( lifecycleModel.getBuild().getPluginManagement(),
+                                                   managedPlugin );
+
+                        for ( final PluginExecution pluginExecution : defaultExecutions )
+                        {
+                            defaultManagedPlugin.addExecution( pluginExecution );
+                        }
+
+                        managedPlugin.getExecutions().removeAll( defaultExecutions );
+                    }
+                }
             }
         }
     }
@@ -253,6 +345,28 @@ private String getExecutionId( Plugin plugin, String goal )
         return id;
     }
 
+    private Plugin getManagedPlugin( final PluginManagement pluginManagement, final Plugin plugin )
+    {
+        Plugin managedPlugin = null;
+        final String key = plugin.getKey();
+
+        if ( pluginManagement != null )
+        {
+            for ( int i = 0, s0 = pluginManagement.getPlugins().size(); i < s0; i++ )
+            {
+                final Plugin current = pluginManagement.getPlugins().get( i );
+
+                if ( current.getKey().equals( key ) )
+                {
+                    managedPlugin = current;
+                    break;
+                }
+            }
+        }
+
+        return managedPlugin;
+    }
+
     static class GoalSpec
     {
 
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java
index 766aed1469..b78f54dc42 100644
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/MojoExecutor.java
@@ -105,32 +105,34 @@ private void collectDependencyRequirements( Set<String> scopesToResolve, Set<Str
 
     private Collection<String> toScopes( String classpath )
     {
+        Collection<String> scopes = Collections.emptyList();
+
         if ( StringUtils.isNotEmpty( classpath ) )
         {
             if ( Artifact.SCOPE_COMPILE.equals( classpath ) )
             {
-                return Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED );
+                scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED );
             }
             else if ( Artifact.SCOPE_RUNTIME.equals( classpath ) )
             {
-                return Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_RUNTIME );
+                scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_RUNTIME );
             }
             else if ( Artifact.SCOPE_COMPILE_PLUS_RUNTIME.equals( classpath ) )
             {
-                return Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED,
-                                      Artifact.SCOPE_RUNTIME );
+                scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED,
+                                        Artifact.SCOPE_RUNTIME );
             }
             else if ( Artifact.SCOPE_RUNTIME_PLUS_SYSTEM.equals( classpath ) )
             {
-                return Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_RUNTIME );
+                scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_RUNTIME );
             }
             else if ( Artifact.SCOPE_TEST.equals( classpath ) )
             {
-                return Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED,
-                                      Artifact.SCOPE_RUNTIME, Artifact.SCOPE_TEST );
+                scopes = Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED,
+                                        Artifact.SCOPE_RUNTIME, Artifact.SCOPE_TEST );
             }
         }
-        return Collections.emptyList();
+        return Collections.unmodifiableCollection( scopes );
     }
 
     public void execute( MavenSession session, List<MojoExecution> mojoExecutions, ProjectIndex projectIndex )
diff --git a/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java b/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java
index 90cf8da7e5..0b2ce9013d 100644
--- a/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java
+++ b/maven-core/src/main/java/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.java
@@ -20,13 +20,13 @@
  */
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer;
+import org.apache.maven.lifecycle.LifecycleMappingNotFoundException;
 import org.apache.maven.model.Build;
 import org.apache.maven.model.Model;
 import org.apache.maven.model.Plugin;
@@ -34,9 +34,9 @@
 import org.apache.maven.model.PluginExecution;
 import org.apache.maven.model.PluginManagement;
 import org.apache.maven.model.building.ModelBuildingRequest;
-import org.apache.maven.model.building.ModelProblemCollector;
 import org.apache.maven.model.building.ModelProblem.Severity;
 import org.apache.maven.model.building.ModelProblem.Version;
+import org.apache.maven.model.building.ModelProblemCollector;
 import org.apache.maven.model.building.ModelProblemCollectorRequest;
 import org.apache.maven.model.merge.MavenModelMerger;
 import org.codehaus.plexus.component.annotations.Component;
@@ -55,27 +55,33 @@
     private LifecycleBindingsMerger merger = new LifecycleBindingsMerger();
 
     @Requirement
-    private LifeCyclePluginAnalyzer lifecycle;
+    private LifeCyclePluginAnalyzer lifecyclePluginAnalyzer;
 
+    @Override
     public void injectLifecycleBindings( Model model, ModelBuildingRequest request, ModelProblemCollector problems )
     {
-        String packaging = model.getPackaging();
+        try
+        {
+            final Model lifecycleModel = this.lifecyclePluginAnalyzer.getLifecycleModel( model );
 
-        Collection<Plugin> defaultPlugins = lifecycle.getPluginsBoundByDefaultToAllLifecycles( packaging );
+            if ( model.getBuild() == null )
+            {
+                model.setBuild( new Build() );
+            }
 
-        if ( defaultPlugins == null )
-        {
-            problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
-                    .setMessage( "Unknown packaging: " + packaging )
-                    .setLocation( model.getLocation( "packaging" ) ) );
+            final PluginManagement pluginManagement = model.getBuild().getPluginManagement();
+
+            model.getBuild().setPluginManagement( lifecycleModel.getBuild().getPluginManagement() );
+
+            merger.merge( model, lifecycleModel );
+
+            model.getBuild().setPluginManagement( pluginManagement );
         }
-        else if ( !defaultPlugins.isEmpty() )
+        catch ( final LifecycleMappingNotFoundException e )
         {
-            Model lifecycleModel = new Model();
-            lifecycleModel.setBuild( new Build() );
-            lifecycleModel.getBuild().getPlugins().addAll( defaultPlugins );
+            problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).
+                setException( e ).setLocation( model.getLocation( "packaging" ) ) );
 
-            merger.merge( model, lifecycleModel );
         }
     }
 
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java
index 34b3b17bf6..54fa5c0def 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java
@@ -460,7 +460,7 @@ private void discoverPluginComponents( final ClassRealm pluginRealm, Plugin plug
                 it.remove();
             }
         }
-        return artifacts;
+        return Collections.unmodifiableList( artifacts );
     }
 
     private Map<String, ClassLoader> calcImports( MavenProject project, ClassLoader parent, List<String> imports )
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java
index b79b15f264..9bfacc94f4 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultPluginDependenciesResolver.java
@@ -19,17 +19,20 @@
  * under the License.
  */
 
+import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.maven.RepositoryUtils;
+import org.apache.maven.artifact.versioning.ComparableVersion;
 import org.apache.maven.model.Dependency;
 import org.apache.maven.model.Plugin;
 import org.apache.maven.plugin.PluginResolutionException;
 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.eclipse.aether.DefaultRepositorySystemSession;
 import org.eclipse.aether.RepositorySystem;
 import org.eclipse.aether.RepositorySystemSession;
@@ -37,6 +40,7 @@
 import org.eclipse.aether.artifact.Artifact;
 import org.eclipse.aether.artifact.DefaultArtifact;
 import org.eclipse.aether.collection.CollectRequest;
+import org.eclipse.aether.collection.DependencyCollectionContext;
 import org.eclipse.aether.collection.DependencyCollectionException;
 import org.eclipse.aether.collection.DependencyGraphTransformer;
 import org.eclipse.aether.collection.DependencySelector;
@@ -54,7 +58,12 @@
 import org.eclipse.aether.util.artifact.JavaScopes;
 import org.eclipse.aether.util.filter.AndDependencyFilter;
 import org.eclipse.aether.util.filter.ScopeDependencyFilter;
+import org.eclipse.aether.util.graph.manager.ClassicDependencyManager;
+import org.eclipse.aether.util.graph.manager.DefaultDependencyManager;
+import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
 import org.eclipse.aether.util.graph.selector.AndDependencySelector;
+import org.eclipse.aether.util.graph.selector.ExclusionDependencySelector;
+import org.eclipse.aether.util.graph.selector.OptionalDependencySelector;
 import org.eclipse.aether.util.graph.transformer.ChainedDependencyGraphTransformer;
 import org.eclipse.aether.util.repository.SimpleArtifactDescriptorPolicy;
 
@@ -73,6 +82,10 @@
 
     private static final String REPOSITORY_CONTEXT = "plugin";
 
+    private static final String DEFAULT_PREREQUISITES = "2";
+
+    private static final ComparableVersion DEFAULT_RESULTION_PREREQUISITES = new ComparableVersion( "3" );
+
     @Requirement
     private Logger logger;
 
@@ -85,50 +98,21 @@ private Artifact toArtifact( Plugin plugin, RepositorySystemSession session )
                                     session.getArtifactTypeRegistry().get( "maven-plugin" ) );
     }
 
+    @Override
     public Artifact resolve( Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session )
         throws PluginResolutionException
     {
-        RequestTrace trace = RequestTrace.newChild( null, plugin );
-
-        Artifact pluginArtifact = toArtifact( plugin, session );
-
         try
         {
-            DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession( session );
-            pluginSession.setArtifactDescriptorPolicy( new SimpleArtifactDescriptorPolicy( true, false ) );
-
-            ArtifactDescriptorRequest request =
-                new ArtifactDescriptorRequest( pluginArtifact, repositories, REPOSITORY_CONTEXT );
-            request.setTrace( trace );
-            ArtifactDescriptorResult result = repoSystem.readArtifactDescriptor( pluginSession, request );
-
-            pluginArtifact = result.getArtifact();
-
-            String requiredMavenVersion = (String) result.getProperties().get( "prerequisites.maven" );
-            if ( requiredMavenVersion != null )
-            {
-                Map<String, String> props = new LinkedHashMap<>( pluginArtifact.getProperties() );
-                props.put( "requiredMavenVersion", requiredMavenVersion );
-                pluginArtifact = pluginArtifact.setProperties( props );
-            }
+            final Artifact pluginArtifact = this.createPluginArtifact( plugin, session, repositories );
+            final ArtifactRequest request = new ArtifactRequest( pluginArtifact, repositories, REPOSITORY_CONTEXT );
+            request.setTrace( RequestTrace.newChild( null, plugin ) );
+            return this.repoSystem.resolveArtifact( session, request ).getArtifact();
         }
-        catch ( ArtifactDescriptorException e )
+        catch ( ArtifactDescriptorException | ArtifactResolutionException e )
         {
             throw new PluginResolutionException( plugin, e );
         }
-
-        try
-        {
-            ArtifactRequest request = new ArtifactRequest( pluginArtifact, repositories, REPOSITORY_CONTEXT );
-            request.setTrace( trace );
-            pluginArtifact = repoSystem.resolveArtifact( session, request ).getArtifact();
-        }
-        catch ( ArtifactResolutionException e )
-        {
-            throw new PluginResolutionException( plugin, e );
-        }
-
-        return pluginArtifact;
     }
 
     /**
@@ -150,56 +134,182 @@ public DependencyNode resolve( Plugin plugin, Artifact pluginArtifact, Dependenc
                                 session );
     }
 
-    private DependencyNode resolveInternal( Plugin plugin, Artifact pluginArtifact, DependencyFilter dependencyFilter,
-                                            DependencyGraphTransformer transformer,
-                                            List<RemoteRepository> repositories, RepositorySystemSession session )
+    @SuppressWarnings( "checkstyle:methodlength" )
+    private DependencyNode resolveInternal( final Plugin plugin, final Artifact artifact,
+                                            final DependencyFilter dependencyFilter,
+                                            final DependencyGraphTransformer transformer,
+                                            final List<RemoteRepository> repositories,
+                                            final RepositorySystemSession session )
         throws PluginResolutionException
     {
-        RequestTrace trace = RequestTrace.newChild( null, plugin );
-
-        if ( pluginArtifact == null )
+        // This dependency selector matches the resolver's implementation before MRESOLVER-8 got fixed. It is
+        // used for plugin's with prerequisites < 3.6 to mimic incorrect but backwards compatible behaviour.
+        class ClassicScopeDependencySelector implements DependencySelector
         {
-            pluginArtifact = toArtifact( plugin, session );
+
+            private final boolean transitive;
+
+            ClassicScopeDependencySelector()
+            {
+                this( false );
+            }
+
+            private ClassicScopeDependencySelector( final boolean transitive )
+            {
+                super();
+                this.transitive = transitive;
+            }
+
+            @Override
+            public boolean selectDependency( final org.eclipse.aether.graph.Dependency dependency )
+            {
+                return !this.transitive
+                           || !( "test".equals( dependency.getScope() )
+                                 || "provided".equals( dependency.getScope() ) );
+
+            }
+
+            @Override
+            public DependencySelector deriveChildSelector( final DependencyCollectionContext context )
+            {
+                ClassicScopeDependencySelector child = this;
+
+                if ( context.getDependency() != null && !child.transitive )
+                {
+                    child = new ClassicScopeDependencySelector( true );
+                }
+                if ( context.getDependency() == null && child.transitive )
+                {
+                    child = new ClassicScopeDependencySelector( false );
+                }
+
+                return child;
+            }
+
+            @Override
+            public boolean equals( Object obj )
+            {
+                boolean equal = obj instanceof ClassicScopeDependencySelector;
+
+                if ( equal )
+                {
+                    final ClassicScopeDependencySelector that = (ClassicScopeDependencySelector) obj;
+                    equal = this.transitive == that.transitive;
+                }
+
+                return equal;
+            }
+
+            @Override
+            public int hashCode()
+            {
+                int hash = 17;
+                hash = hash * 31 + ( ( (Boolean) this.transitive ).hashCode() );
+                return hash;
+            }
+
         }
 
-        DependencyFilter collectionFilter = new ScopeDependencyFilter( "provided", "test" );
-        DependencyFilter resolutionFilter = AndDependencyFilter.newInstance( collectionFilter, dependencyFilter );
+        final RepositorySystemSession verboseSession;
+        if ( this.logger.isDebugEnabled()
+                 && session.getConfigProperties().get( DependencyManagerUtils.CONFIG_PROP_VERBOSE ) == null )
+        {
+            final DefaultRepositorySystemSession defaultSession = new DefaultRepositorySystemSession( session );
+            defaultSession.setConfigProperty( DependencyManagerUtils.CONFIG_PROP_VERBOSE, Boolean.TRUE );
+            verboseSession = defaultSession;
+        }
+        else
+        {
+            verboseSession = session;
+        }
 
-        DependencyNode node;
+        final RequestTrace trace = RequestTrace.newChild( null, plugin );
+        final DependencyFilter collectionFilter = new ScopeDependencyFilter( "provided", "test" );
+        final DependencyFilter resolutionFilter = AndDependencyFilter.newInstance( collectionFilter, dependencyFilter );
 
         try
         {
-            DependencySelector selector =
-                AndDependencySelector.newInstance( session.getDependencySelector(), new WagonExcluder() );
+            final Artifact pluginArtifact = artifact != null
+                                                ? this.createPluginArtifact( artifact, verboseSession, repositories )
+                                                : this.createPluginArtifact( plugin, verboseSession, repositories );
 
-            transformer =
-                ChainedDependencyGraphTransformer.newInstance( session.getDependencyGraphTransformer(), transformer );
+            final ComparableVersion prerequisites =
+                new ComparableVersion( pluginArtifact.getProperty( "requiredMavenVersion", DEFAULT_PREREQUISITES ) );
 
-            DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession( session );
-            pluginSession.setDependencySelector( selector );
-            pluginSession.setDependencyGraphTransformer( transformer );
+            final boolean classicResolution = prerequisites.compareTo( DEFAULT_RESULTION_PREREQUISITES ) < 0;
+
+            if ( this.logger.isDebugEnabled() )
+            {
+                if ( classicResolution )
+                {
+                    this.logger.debug( String.format(
+                        "Constructing classic plugin classpath '%s' for prerequisites '%s'.",
+                        pluginArtifact, prerequisites ) );
+
+                }
+                else
+                {
+                    this.logger.debug( String.format(
+                        "Constructing default plugin classpath '%s' for prerequisites '%s'.",
+                        pluginArtifact, prerequisites ) );
+
+                }
+            }
+
+            final DependencySelector pluginDependencySelector =
+                classicResolution
+                    ? new AndDependencySelector( new ClassicScopeDependencySelector(), // incorrect - see MRESOLVER-8
+                                                 new OptionalDependencySelector(),
+                                                 new ExclusionDependencySelector(),
+                                                 new WagonExcluder() )
+                    : AndDependencySelector.newInstance( verboseSession.getDependencySelector(), new WagonExcluder() );
+
+            final DependencyGraphTransformer pluginDependencyGraphTransformer =
+                ChainedDependencyGraphTransformer.newInstance( verboseSession.getDependencyGraphTransformer(),
+                                                               transformer );
+
+            DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession( verboseSession );
+            pluginSession.setDependencySelector( pluginDependencySelector );
+            pluginSession.setDependencyGraphTransformer( pluginDependencyGraphTransformer );
+            pluginSession.setDependencyManager( classicResolution
+                                                    ? new ClassicDependencyManager()
+                                                    : new DefaultDependencyManager() );
 
             CollectRequest request = new CollectRequest();
             request.setRequestContext( REPOSITORY_CONTEXT );
             request.setRepositories( repositories );
-            request.setRoot( new org.eclipse.aether.graph.Dependency( pluginArtifact, null ) );
+
             for ( Dependency dependency : plugin.getDependencies() )
             {
                 org.eclipse.aether.graph.Dependency pluginDep =
-                    RepositoryUtils.toDependency( dependency, session.getArtifactTypeRegistry() );
+                    RepositoryUtils.toDependency( dependency, verboseSession.getArtifactTypeRegistry() );
+
                 if ( !JavaScopes.SYSTEM.equals( pluginDep.getScope() ) )
                 {
                     pluginDep = pluginDep.setScope( JavaScopes.RUNTIME );
                 }
-                request.addDependency( pluginDep );
+
+                final Object sourceHint = dependency.getLocation( "" );
+                request.addDependency( pluginDep.setSourceHint( sourceHint != null
+                                                                    ? sourceHint.toString()
+                                                                    : dependency.toString() ) );
+
+                request.addManagedDependency( pluginDep.setSourceHint( sourceHint != null
+                                                                           ? sourceHint.toString()
+                                                                           : dependency.toString() ) );
+
             }
 
+            final Object sourceHint = plugin.getLocation( "" );
+            request.setRoot( new org.eclipse.aether.graph.Dependency( pluginArtifact, null ).
+                setSourceHint( sourceHint != null ? sourceHint.toString() : plugin.toString() ) );
+
             DependencyRequest depRequest = new DependencyRequest( request, resolutionFilter );
             depRequest.setTrace( trace );
 
             request.setTrace( RequestTrace.newChild( trace, depRequest ) );
 
-            node = repoSystem.collectDependencies( pluginSession, request ).getRoot();
+            final DependencyNode node = repoSystem.collectDependencies( pluginSession, request ).getRoot();
 
             if ( logger.isDebugEnabled() )
             {
@@ -207,9 +317,10 @@ private DependencyNode resolveInternal( Plugin plugin, Artifact pluginArtifact,
             }
 
             depRequest.setRoot( node );
-            repoSystem.resolveDependencies( session, depRequest );
+            repoSystem.resolveDependencies( verboseSession, depRequest );
+            return node;
         }
-        catch ( DependencyCollectionException e )
+        catch ( ArtifactDescriptorException | DependencyCollectionException e )
         {
             throw new PluginResolutionException( plugin, e );
         }
@@ -217,16 +328,58 @@ private DependencyNode resolveInternal( Plugin plugin, Artifact pluginArtifact,
         {
             throw new PluginResolutionException( plugin, e.getCause() );
         }
+    }
+
+    private Artifact createPluginArtifact( final Plugin plugin,
+                                           final RepositorySystemSession session,
+                                           final List<RemoteRepository> repositories )
+        throws ArtifactDescriptorException
+    {
+        return this.createPluginArtifact( toArtifact( plugin, session ), session, repositories );
+    }
+
+    private Artifact createPluginArtifact( final Artifact artifact,
+                                           final RepositorySystemSession session,
+                                           final List<RemoteRepository> repositories )
+        throws ArtifactDescriptorException
+    {
+        Artifact pluginArtifact = artifact;
+        final DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession( session );
+        pluginSession.setArtifactDescriptorPolicy( new SimpleArtifactDescriptorPolicy( true, false ) );
+
+        final ArtifactDescriptorRequest request =
+            new ArtifactDescriptorRequest( pluginArtifact, repositories, REPOSITORY_CONTEXT );
+
+        request.setTrace( RequestTrace.newChild( null, artifact ) );
+
+        final ArtifactDescriptorResult result = this.repoSystem.readArtifactDescriptor( pluginSession, request );
+
+        pluginArtifact = result.getArtifact();
+
+        final String requiredMavenVersion = (String) result.getProperties().get( "prerequisites.maven" );
+
+        if ( requiredMavenVersion != null )
+        {
+            final Map<String, String> props = new LinkedHashMap<>( pluginArtifact.getProperties() );
+            props.put( "requiredMavenVersion", requiredMavenVersion );
+            pluginArtifact = pluginArtifact.setProperties( props );
+        }
 
-        return node;
+        return pluginArtifact;
     }
 
+    // Keep this class in sync with org.apache.maven.project.DefaultProjectDependenciesResolver.GraphLogger
     class GraphLogger
         implements DependencyVisitor
     {
 
         private String indent = "";
 
+        GraphLogger()
+        {
+            super();
+        }
+
         public boolean visitEnter( DependencyNode node )
         {
             StringBuilder buffer = new StringBuilder( 128 );
@@ -234,10 +387,121 @@ public boolean visitEnter( DependencyNode node )
             org.eclipse.aether.graph.Dependency dep = node.getDependency();
             if ( dep != null )
             {
-                Artifact art = dep.getArtifact();
+                org.eclipse.aether.artifact.Artifact art = dep.getArtifact();
 
                 buffer.append( art );
-                buffer.append( ':' ).append( dep.getScope() );
+                buffer.append( ':' ).append( dep.getScope() ).append( ":optional(" ).
+                    append( dep.getOptional() == null
+                                ? "default"
+                                : dep.isOptional()
+                                      ? "true"
+                                      : "false" ).append( ')' );
+
+                if ( !dep.getExclusions().isEmpty() )
+                {
+                    buffer.append( ":exclusions(" ).append( dep.getExclusions() ).append( ')' );
+                }
+
+                if ( !dep.getArtifact().getProperties().isEmpty() )
+                {
+                    buffer.append( ":properties(" ).append( dep.getArtifact().getProperties() ).append( ')' );
+                }
+
+                if ( ( node.getManagedBits() & DependencyNode.MANAGED_SCOPE ) == DependencyNode.MANAGED_SCOPE )
+                {
+                    final String premanagedScope = DependencyManagerUtils.getPremanagedScope( node );
+                    if ( premanagedScope != null && !premanagedScope.equals( dep.getScope() ) )
+                    {
+                        buffer.append( " (scope managed from " );
+                        buffer.append( StringUtils.defaultString( premanagedScope, "default" ) );
+
+                        final String sourceHint = DependencyManagerUtils.getScopeManagementSourceHint( node );
+                        if ( sourceHint != null )
+                        {
+                            buffer.append( " by " ).append( sourceHint ).append( ' ' );
+                        }
+
+                        buffer.append( ')' );
+                    }
+                }
+
+                if ( ( node.getManagedBits() & DependencyNode.MANAGED_VERSION ) == DependencyNode.MANAGED_VERSION )
+                {
+                    final String premanagedVersion = DependencyManagerUtils.getPremanagedVersion( node );
+                    if ( premanagedVersion != null && !premanagedVersion.equals( dep.getArtifact().getVersion() ) )
+                    {
+                        buffer.append( " (version managed from " );
+                        buffer.append( StringUtils.defaultString( premanagedVersion, "default" ) );
+
+                        final String sourceHint = DependencyManagerUtils.getVersionManagementSourceHint( node );
+                        if ( sourceHint != null )
+                        {
+                            buffer.append( " by " ).append( sourceHint ).append( ' ' );
+                        }
+
+                        buffer.append( ')' );
+                    }
+                }
+
+                if ( ( node.getManagedBits() & DependencyNode.MANAGED_OPTIONAL ) == DependencyNode.MANAGED_OPTIONAL )
+                {
+                    final Boolean premanagedOptional = DependencyManagerUtils.getPremanagedOptional( node );
+                    if ( premanagedOptional != null && !premanagedOptional.equals( dep.getOptional() ) )
+                    {
+                        buffer.append( " (optionality managed from " );
+                        buffer.append( StringUtils.defaultString( premanagedOptional, "default" ) );
+
+                        final String sourceHint = DependencyManagerUtils.getOptionalityManagementSourceHint( node );
+                        if ( sourceHint != null )
+                        {
+                            buffer.append( " by " ).append( sourceHint ).append( ' ' );
+                        }
+
+                        buffer.append( ')' );
+                    }
+                }
+
+                if ( ( node.getManagedBits() & DependencyNode.MANAGED_EXCLUSIONS )
+                         == DependencyNode.MANAGED_EXCLUSIONS )
+                {
+                    final Collection<org.eclipse.aether.graph.Exclusion> premanagedExclusions =
+                        DependencyManagerUtils.getPremanagedExclusions( node );
+
+                    if ( premanagedExclusions != null && !premanagedExclusions.equals( dep.getExclusions() ) )
+                    {
+                        buffer.append( " (exclusions managed from " );
+                        buffer.append( StringUtils.defaultString( premanagedExclusions, "default" ) );
+
+                        final String sourceHint = DependencyManagerUtils.getExclusionsManagementSourceHint( node );
+                        if ( sourceHint != null )
+                        {
+                            buffer.append( " by " ).append( sourceHint ).append( ' ' );
+                        }
+
+                        buffer.append( ')' );
+                    }
+                }
+
+                if ( ( node.getManagedBits() & DependencyNode.MANAGED_PROPERTIES )
+                         == DependencyNode.MANAGED_PROPERTIES )
+                {
+                    final Map<String, String> premanagedProperties =
+                        DependencyManagerUtils.getPremanagedProperties( node );
+
+                    if ( premanagedProperties != null && !premanagedProperties.equals( art.getProperties() ) )
+                    {
+                        buffer.append( " (properties managed from " );
+                        buffer.append( StringUtils.defaultString( premanagedProperties, "default" ) );
+
+                        final String sourceHint = DependencyManagerUtils.getPropertiesManagementSourceHint( node );
+                        if ( sourceHint != null )
+                        {
+                            buffer.append( " by " ).append( sourceHint ).append( ' ' );
+                        }
+
+                        buffer.append( ')' );
+                    }
+                }
             }
 
             logger.debug( buffer.toString() );
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusUtilsInjector.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusUtilsInjector.java
index 16a0b63c08..eb36957912 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusUtilsInjector.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/PlexusUtilsInjector.java
@@ -64,24 +64,32 @@ public DependencyNode transformGraph( DependencyNode node, DependencyGraphTransf
 
     private DependencyNode findPlexusUtils( DependencyNode node )
     {
-        Artifact artifact = node.getDependency().getArtifact();
+        DependencyNode plexusUtils = null;
 
-        if ( AID.equals( artifact.getArtifactId() ) && GID.equals( artifact.getGroupId() )
-            && EXT.equals( artifact.getExtension() ) && "".equals( artifact.getClassifier() ) )
+        find:
         {
-            return node;
-        }
+            if ( AID.equals( node.getArtifact().getArtifactId() )
+                     && GID.equals( node.getArtifact().getGroupId() )
+                     && EXT.equals( node.getArtifact().getExtension() )
+                     && "".equals( node.getArtifact().getClassifier() ) )
+            {
+                plexusUtils = node;
+                break find;
+            }
 
-        for ( DependencyNode child : node.getChildren() )
-        {
-            DependencyNode result = findPlexusUtils( child );
-            if ( result != null )
+            for ( DependencyNode child : node.getChildren() )
             {
-                return result;
+                DependencyNode result = findPlexusUtils( child );
+
+                if ( result != null )
+                {
+                    plexusUtils = result;
+                    break find;
+                }
             }
         }
 
-        return null;
+        return plexusUtils;
     }
 
 }
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/WagonExcluder.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/WagonExcluder.java
index d374cab9a5..e003ede979 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/WagonExcluder.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/WagonExcluder.java
@@ -51,19 +51,19 @@ private WagonExcluder( boolean coreArtifact )
 
     public boolean selectDependency( Dependency dependency )
     {
-        return !coreArtifact || !isWagonProvider( dependency.getArtifact() );
+        return !( coreArtifact && isWagonProvider( dependency.getArtifact() ) );
     }
 
     public DependencySelector deriveChildSelector( DependencyCollectionContext context )
     {
-        if ( coreArtifact || !isLegacyCoreArtifact( context.getDependency().getArtifact() ) )
-        {
-            return this;
-        }
-        else
+        WagonExcluder child = this;
+
+        if ( isLegacyCoreArtifact( context.getArtifact() ) && !this.coreArtifact )
         {
-            return new WagonExcluder( true );
+            child = new WagonExcluder( true );
         }
+
+        return child;
     }
 
     private boolean isLegacyCoreArtifact( Artifact artifact )
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/prefix/DefaultPluginPrefixRequest.java b/maven-core/src/main/java/org/apache/maven/plugin/prefix/DefaultPluginPrefixRequest.java
index 7ab86cfd16..01194c866d 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/prefix/DefaultPluginPrefixRequest.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/prefix/DefaultPluginPrefixRequest.java
@@ -100,7 +100,7 @@ public DefaultPluginPrefixRequest setPluginGroups( List<String> pluginGroups )
     {
         if ( pluginGroups != null )
         {
-            this.pluginGroups = pluginGroups;
+            this.pluginGroups = Collections.unmodifiableList( pluginGroups );
         }
         else
         {
@@ -131,7 +131,7 @@ public DefaultPluginPrefixRequest setRepositories( List<RemoteRepository> reposi
     {
         if ( repositories != null )
         {
-            this.repositories = repositories;
+            this.repositories = Collections.unmodifiableList( repositories );
         }
         else
         {
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/version/DefaultPluginVersionRequest.java b/maven-core/src/main/java/org/apache/maven/plugin/version/DefaultPluginVersionRequest.java
index 9907066b9d..57f4250c63 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/version/DefaultPluginVersionRequest.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/version/DefaultPluginVersionRequest.java
@@ -140,7 +140,7 @@ public DefaultPluginVersionRequest setRepositories( List<RemoteRepository> repos
     {
         if ( repositories != null )
         {
-            this.repositories = repositories;
+            this.repositories = Collections.unmodifiableList( repositories );
         }
         else
         {
diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionResult.java b/maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionResult.java
index dbdf25261d..509e8b48d9 100644
--- a/maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionResult.java
+++ b/maven-core/src/main/java/org/apache/maven/project/DefaultDependencyResolutionResult.java
@@ -98,7 +98,10 @@ public void setCollectionErrors( List<Exception> exceptions )
     public List<Exception> getResolutionErrors( Dependency dependency )
     {
         List<Exception> errors = resolutionErrors.get( dependency );
-        return ( errors != null ) ? errors : Collections.<Exception>emptyList();
+        return ( errors != null )
+                   ? Collections.unmodifiableList( errors )
+                   : Collections.<Exception>emptyList();
+
     }
 
     public void setResolutionErrors( Dependency dependency, List<Exception> errors )
diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
index 279399add8..9515591064 100644
--- a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
+++ b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
@@ -809,6 +809,7 @@ private void initProject( MavenProject project, Map<String, MavenProject> projec
                         map.put( d.getManagementKey(), artifact );
                     }
                 }
+                map = Collections.unmodifiableMap( map );
             }
             else
             {
diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingRequest.java b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingRequest.java
index 0451a306fc..c7f031202f 100644
--- a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingRequest.java
+++ b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuildingRequest.java
@@ -83,22 +83,25 @@ public DefaultProjectBuildingRequest()
         pluginArtifactRepositories = new ArrayList<>();
     }
 
+    @SuppressWarnings( "deprecation" )
     public DefaultProjectBuildingRequest( ProjectBuildingRequest request )
     {
         this();
-        setProcessPlugins( request.isProcessPlugins() );
-        setProfiles( request.getProfiles() );
         setActiveProfileIds( request.getActiveProfileIds() );
+        setBuildStartTime( request.getBuildStartTime() );
         setInactiveProfileIds( request.getInactiveProfileIds() );
-        setSystemProperties( request.getSystemProperties() );
-        setUserProperties( request.getUserProperties() );
-        setRemoteRepositories( request.getRemoteRepositories() );
-        setPluginArtifactRepositories( request.getPluginArtifactRepositories() );
-        setRepositorySession( request.getRepositorySession() );
         setLocalRepository( request.getLocalRepository() );
-        setBuildStartTime( request.getBuildStartTime() );
+        setPluginArtifactRepositories( request.getPluginArtifactRepositories() );
+        setProcessPlugins( request.isProcessPlugins() );
+        setProfiles( request.getProfiles() );
         setProject( request.getProject() );
+        setRemoteRepositories( request.getRemoteRepositories() );
+        setRepositoryMerging( request.getRepositoryMerging() );
+        setRepositorySession( request.getRepositorySession() );
         setResolveDependencies( request.isResolveDependencies() );
+        setResolveVersionRanges( request.isResolveVersionRanges() );
+        setSystemProperties( request.getSystemProperties() );
+        setUserProperties( request.getUserProperties() );
         setValidationLevel( request.getValidationLevel() );
     }
 
diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectDependenciesResolver.java b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectDependenciesResolver.java
index 4bb9609fc2..0649ea16a8 100644
--- a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectDependenciesResolver.java
+++ b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectDependenciesResolver.java
@@ -19,6 +19,7 @@
  * under the License.
  */
 
+import java.io.File;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
@@ -29,6 +30,7 @@
 import org.apache.maven.model.Dependency;
 import org.apache.maven.model.DependencyManagement;
 import org.apache.maven.model.Exclusion;
+import org.apache.maven.model.Model;
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.component.annotations.Requirement;
 import org.codehaus.plexus.logging.Logger;
@@ -80,7 +82,7 @@ public DependencyResolutionResult resolve( DependencyResolutionRequest request )
         ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry();
 
         if ( logger.isDebugEnabled()
-            && session.getConfigProperties().get( DependencyManagerUtils.CONFIG_PROP_VERBOSE ) == null )
+                 && session.getConfigProperties().get( DependencyManagerUtils.CONFIG_PROP_VERBOSE ) == null )
         {
             DefaultRepositorySystemSession verbose = new DefaultRepositorySystemSession( session );
             verbose.setConfigProperty( DependencyManagerUtils.CONFIG_PROP_VERBOSE, Boolean.TRUE );
@@ -106,12 +108,14 @@ public DependencyResolutionResult resolve( DependencyResolutionRequest request )
             for ( Dependency dependency : project.getDependencies() )
             {
                 if ( StringUtils.isEmpty( dependency.getGroupId() ) || StringUtils.isEmpty( dependency.getArtifactId() )
-                    || StringUtils.isEmpty( dependency.getVersion() ) )
+                         || StringUtils.isEmpty( dependency.getVersion() ) )
                 {
                     // guard against case where best-effort resolution for invalid models is requested
                     continue;
                 }
-                collect.addDependency( RepositoryUtils.toDependency( dependency, stereotypes ) );
+                collect.addDependency( RepositoryUtils.toDependency( dependency, stereotypes ).
+                    setSourceHint( toSourceHint( project.getModel() ) ) );
+
             }
         }
         else
@@ -130,7 +134,7 @@ public DependencyResolutionResult resolve( DependencyResolutionRequest request )
                 }
                 String key =
                     ArtifactIdUtils.toVersionlessId( dependency.getGroupId(), dependency.getArtifactId(),
-                                                    dependency.getType(), classifier );
+                                                     dependency.getType(), classifier );
                 dependencies.put( key, dependency );
             }
             for ( Artifact artifact : project.getDependencyArtifacts() )
@@ -146,7 +150,7 @@ public DependencyResolutionResult resolve( DependencyResolutionRequest request )
                     art = art.setFile( null ).setVersion( art.getBaseVersion() );
                     dep = dep.setArtifact( art );
                 }
-                collect.addDependency( dep );
+                collect.addDependency( dep.setSourceHint( toSourceHint( project.getModel() ) ) );
             }
         }
 
@@ -155,7 +159,9 @@ public DependencyResolutionResult resolve( DependencyResolutionRequest request )
         {
             for ( Dependency dependency : depMgmt.getDependencies() )
             {
-                collect.addManagedDependency( RepositoryUtils.toDependency( dependency, stereotypes ) );
+                collect.addManagedDependency( RepositoryUtils.toDependency( dependency, stereotypes ).
+                    setSourceHint( toSourceHint( project.getModel() ) ) );
+
             }
         }
 
@@ -175,7 +181,7 @@ public DependencyResolutionResult resolve( DependencyResolutionRequest request )
             result.setCollectionErrors( e.getResult().getExceptions() );
 
             throw new DependencyResolutionException( result, "Could not resolve dependencies for project "
-                + project.getId() + ": " + e.getMessage(), e );
+                                                                 + project.getId() + ": " + e.getMessage(), e );
         }
 
         depRequest.setRoot( node );
@@ -187,7 +193,7 @@ public DependencyResolutionResult resolve( DependencyResolutionRequest request )
                 if ( !child.getRelocations().isEmpty() )
                 {
                     logger.warn( "The artifact " + child.getRelocations().get( 0 ) + " has been relocated to "
-                        + child.getDependency().getArtifact() );
+                                     + child.getDependency().getArtifact() );
                 }
             }
         }
@@ -206,7 +212,7 @@ public DependencyResolutionResult resolve( DependencyResolutionRequest request )
             process( result, e.getResult().getArtifactResults() );
 
             throw new DependencyResolutionException( result, "Could not resolve dependencies for project "
-                + project.getId() + ": " + e.getMessage(), e );
+                                                                 + project.getId() + ": " + e.getMessage(), e );
         }
 
         return result;
@@ -228,6 +234,67 @@ private void process( DefaultDependencyResolutionResult result, Collection<Artif
         }
     }
 
+    private static String toSourceHint( final Model model )
+    {
+        String sourceHint = null;
+
+        if ( model != null )
+        {
+            final StringBuilder sourceHintBuilder = new StringBuilder( 128 );
+
+            sourceHintBuilder.append( toId( model ) );
+
+            File pomFile = model.getPomFile();
+            if ( pomFile != null )
+            {
+                sourceHintBuilder.append( " @ " ).append( pomFile );
+            }
+
+            sourceHint = sourceHintBuilder.toString();
+        }
+
+        return sourceHint;
+    }
+
+    private static String toId( final Model model )
+    {
+        String id = null;
+
+        if ( model != null )
+        {
+            String groupId = model.getGroupId();
+            if ( groupId == null && model.getParent() != null )
+            {
+                groupId = model.getParent().getGroupId();
+            }
+
+            String artifactId = model.getArtifactId();
+
+            String version = model.getVersion();
+            if ( version == null && model.getParent() != null )
+            {
+                version = model.getParent().getVersion();
+            }
+
+            id = toId( groupId, artifactId, version );
+        }
+
+        return id;
+    }
+
+    private static String toId( final String groupId, final String artifactId, final String version )
+    {
+        final StringBuilder idBuilder = new StringBuilder( 128 );
+
+        idBuilder.append( ( groupId != null && groupId.length() > 0 ) ? groupId : "[unknown-group-id]" );
+        idBuilder.append( ':' );
+        idBuilder.append( ( artifactId != null && artifactId.length() > 0 ) ? artifactId : "[unknown-artifact-id]" );
+        idBuilder.append( ':' );
+        idBuilder.append( ( version != null && version.length() > 0 ) ? version : "[unknown-version]" );
+
+        return idBuilder.toString();
+    }
+
     class GraphLogger
         implements DependencyVisitor
     {
@@ -251,54 +318,117 @@ public boolean visitEnter( DependencyNode node )
                 org.eclipse.aether.artifact.Artifact art = dep.getArtifact();
 
                 buffer.append( art );
-                buffer.append( ':' ).append( dep.getScope() );
+                buffer.append( ':' ).append( dep.getScope() ).append( ":optional(" ).
+                    append( dep.getOptional() == null
+                                ? "default"
+                                : dep.isOptional()
+                                      ? "true"
+                                      : "false" ).append( ')' );
+
+                if ( !dep.getExclusions().isEmpty() )
+                {
+                    buffer.append( ":exclusions(" ).append( dep.getExclusions() ).append( ')' );
+                }
+
+                if ( !dep.getArtifact().getProperties().isEmpty() )
+                {
+                    buffer.append( ":properties(" ).append( dep.getArtifact().getProperties() ).append( ')' );
+                }
 
-                // TODO We currently cannot tell which <dependencyManagement> section contained the management
-                //      information. When resolver 1.1 provides this information, these log messages should be updated
-                //      to contain it.
                 if ( ( node.getManagedBits() & DependencyNode.MANAGED_SCOPE ) == DependencyNode.MANAGED_SCOPE )
                 {
                     final String premanagedScope = DependencyManagerUtils.getPremanagedScope( node );
-                    buffer.append( " (scope managed from " );
-                    buffer.append( StringUtils.defaultString( premanagedScope, "default" ) );
-                    buffer.append( ')' );
+                    if ( premanagedScope != null && !premanagedScope.equals( dep.getScope() ) )
+                    {
+                        buffer.append( " (scope managed from " );
+                        buffer.append( StringUtils.defaultString( premanagedScope, "default" ) );
+
+                        final String sourceHint = DependencyManagerUtils.getScopeManagementSourceHint( node );
+                        if ( sourceHint != null )
+                        {
+                            buffer.append( " by " ).append( sourceHint ).append( ' ' );
+                        }
+
+                        buffer.append( ')' );
+                    }
                 }
 
                 if ( ( node.getManagedBits() & DependencyNode.MANAGED_VERSION ) == DependencyNode.MANAGED_VERSION )
                 {
                     final String premanagedVersion = DependencyManagerUtils.getPremanagedVersion( node );
-                    buffer.append( " (version managed from " );
-                    buffer.append( StringUtils.defaultString( premanagedVersion, "default" ) );
-                    buffer.append( ')' );
+                    if ( premanagedVersion != null && !premanagedVersion.equals( dep.getArtifact().getVersion() ) )
+                    {
+                        buffer.append( " (version managed from " );
+                        buffer.append( StringUtils.defaultString( premanagedVersion, "default" ) );
+
+                        final String sourceHint = DependencyManagerUtils.getVersionManagementSourceHint( node );
+                        if ( sourceHint != null )
+                        {
+                            buffer.append( " by " ).append( sourceHint ).append( ' ' );
+                        }
+
+                        buffer.append( ')' );
+                    }
                 }
 
                 if ( ( node.getManagedBits() & DependencyNode.MANAGED_OPTIONAL ) == DependencyNode.MANAGED_OPTIONAL )
                 {
                     final Boolean premanagedOptional = DependencyManagerUtils.getPremanagedOptional( node );
-                    buffer.append( " (optionality managed from " );
-                    buffer.append( StringUtils.defaultString( premanagedOptional, "default" ) );
-                    buffer.append( ')' );
+                    if ( premanagedOptional != null && !premanagedOptional.equals( dep.getOptional() ) )
+                    {
+                        buffer.append( " (optionality managed from " );
+                        buffer.append( StringUtils.defaultString( premanagedOptional, "default" ) );
+
+                        final String sourceHint = DependencyManagerUtils.getOptionalityManagementSourceHint( node );
+                        if ( sourceHint != null )
+                        {
+                            buffer.append( " by " ).append( sourceHint ).append( ' ' );
+                        }
+
+                        buffer.append( ')' );
+                    }
                 }
 
                 if ( ( node.getManagedBits() & DependencyNode.MANAGED_EXCLUSIONS )
-                        == DependencyNode.MANAGED_EXCLUSIONS )
+                         == DependencyNode.MANAGED_EXCLUSIONS )
                 {
-                    // TODO As of resolver 1.1, use DependencyManagerUtils.getPremanagedExclusions( node ).
-                    //      The resolver 1.0.x releases do not record premanaged state of exclusions.
-                    buffer.append( " (exclusions managed)" );
+                    final Collection<org.eclipse.aether.graph.Exclusion> premanagedExclusions =
+                        DependencyManagerUtils.getPremanagedExclusions( node );
+
+                    if ( premanagedExclusions != null && !premanagedExclusions.equals( dep.getExclusions() ) )
+                    {
+                        buffer.append( " (exclusions managed from " );
+                        buffer.append( StringUtils.defaultString( premanagedExclusions, "default" ) );
+
+                        final String sourceHint = DependencyManagerUtils.getExclusionsManagementSourceHint( node );
+                        if ( sourceHint != null )
+                        {
+                            buffer.append( " by " ).append( sourceHint ).append( ' ' );
+                        }
+
+                        buffer.append( ')' );
+                    }
                 }
 
                 if ( ( node.getManagedBits() & DependencyNode.MANAGED_PROPERTIES )
-                        == DependencyNode.MANAGED_PROPERTIES )
+                         == DependencyNode.MANAGED_PROPERTIES )
                 {
-                    // TODO As of resolver 1.1, use DependencyManagerUtils.getPremanagedProperties( node ).
-                    //      The resolver 1.0.x releases do not record premanaged state of properties.
-                    buffer.append( " (properties managed)" );
-                }
+                    final Map<String, String> premanagedProperties =
+                        DependencyManagerUtils.getPremanagedProperties( node );
 
-                if ( dep.isOptional() )
-                {
-                    buffer.append( " (optional)" );
+                    if ( premanagedProperties != null && !premanagedProperties.equals( art.getProperties() ) )
+                    {
+                        buffer.append( " (properties managed from " );
+                        buffer.append( StringUtils.defaultString( premanagedProperties, "default" ) );
+
+                        final String sourceHint = DependencyManagerUtils.getPropertiesManagementSourceHint( node );
+                        if ( sourceHint != null )
+                        {
+                            buffer.append( " by " ).append( sourceHint ).append( ' ' );
+                        }
+
+                        buffer.append( ')' );
+                    }
                 }
             }
             else
diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectRealmCache.java b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectRealmCache.java
index a14e624af8..15681b6c39 100644
--- a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectRealmCache.java
+++ b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectRealmCache.java
@@ -51,7 +51,9 @@
 
         public CacheKey( List<? extends ClassRealm> extensionRealms )
         {
-            this.extensionRealms = ( extensionRealms != null ) ? extensionRealms : Collections.<ClassRealm>emptyList();
+            this.extensionRealms = ( extensionRealms != null )
+                                       ? Collections.unmodifiableList( extensionRealms )
+                                       : Collections.<ClassRealm>emptyList();
 
             this.hashCode = this.extensionRealms.hashCode();
         }
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 dff5f3fdcf..fd7ab40ddc 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
@@ -778,7 +778,7 @@ public Artifact getParentArtifact()
         {
             return Collections.emptyList();
         }
-        return getModel().getBuild().getPlugins();
+        return Collections.unmodifiableList( getModel().getBuild().getPlugins() );
     }
 
     public List<String> getModules()
@@ -1079,7 +1079,7 @@ public int hashCode()
         }
         else
         {
-            return build.getExtensions();
+            return Collections.unmodifiableList( build.getExtensions() );
         }
     }
 
@@ -1604,7 +1604,7 @@ public void addScriptSourceRoot( String path )
         {
             // TODO let the scope handler deal with this
             if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_PROVIDED.equals( a.getScope() )
-                || Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
+                     || Artifact.SCOPE_SYSTEM.equals( a.getScope() ) )
             {
                 Dependency dependency = new Dependency();
 
@@ -1618,7 +1618,7 @@ public void addScriptSourceRoot( String path )
                 list.add( dependency );
             }
         }
-        return list;
+        return Collections.unmodifiableList( list );
     }
 
     @Deprecated
@@ -1662,7 +1662,7 @@ public void addScriptSourceRoot( String path )
 
             list.add( dependency );
         }
-        return list;
+        return Collections.unmodifiableList( list );
     }
 
     @Deprecated // used by the Maven ITs
@@ -1677,7 +1677,7 @@ public void addScriptSourceRoot( String path )
 
         List<Dependency> list = new ArrayList<>( artifacts.size() );
 
-        for ( Artifact a : getArtifacts()  )
+        for ( Artifact a : getArtifacts() )
         {
             // TODO let the scope handler deal with this
             if ( Artifact.SCOPE_COMPILE.equals( a.getScope() ) || Artifact.SCOPE_RUNTIME.equals( a.getScope() ) )
@@ -1694,7 +1694,7 @@ public void addScriptSourceRoot( String path )
                 list.add( dependency );
             }
         }
-        return list;
+        return Collections.unmodifiableList( list );
     }
 
     @Deprecated
@@ -1790,7 +1790,7 @@ public void addScriptSourceRoot( String path )
                 list.add( dependency );
             }
         }
-        return list;
+        return Collections.unmodifiableList( list );
     }
 
     @Deprecated
@@ -1862,8 +1862,7 @@ public void setExtensionArtifacts( Set<Artifact> extensionArtifacts )
         {
             return Collections.emptyList();
         }
-        return getModel().getReporting().getPlugins();
-
+        return Collections.unmodifiableList( getModel().getReporting().getPlugins() );
     }
 
     @Deprecated
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 2b3108a47f..21d4820c4f 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
@@ -77,6 +77,8 @@
 
     private final Set<String> repositoryIds;
 
+    private final Set<String> externalRepositoryIds;
+
     private final ReactorModelPool modelPool;
 
     private final ProjectBuildingRequest.RepositoryMerging repositoryMerging;
@@ -98,7 +100,13 @@ public ProjectModelResolver( RepositorySystemSession session, RequestTrace trace
         this.repositories.addAll( externalRepositories );
         this.repositoryMerging = repositoryMerging;
         this.repositoryIds = new HashSet<>();
+        this.externalRepositoryIds = new HashSet<>();
         this.modelPool = modelPool;
+        for ( final RemoteRepository repository : repositories )
+        {
+            this.repositoryIds.add( repository.getId() );
+            this.externalRepositoryIds.add( repository.getId() );
+        }
     }
 
     private ProjectModelResolver( ProjectModelResolver original )
@@ -112,6 +120,7 @@ private ProjectModelResolver( ProjectModelResolver original )
         this.repositories = new ArrayList<>( original.repositories );
         this.repositoryMerging = original.repositoryMerging;
         this.repositoryIds = new HashSet<>( original.repositoryIds );
+        this.externalRepositoryIds = new HashSet<>( original.externalRepositoryIds );
         this.modelPool = original.modelPool;
     }
 
@@ -127,7 +136,8 @@ public void addRepository( final Repository repository, boolean replace )
     {
         if ( !repositoryIds.add( repository.getId() ) )
         {
-            if ( !replace )
+            if ( !replace || ( ProjectBuildingRequest.RepositoryMerging.REQUEST_DOMINANT.equals( repositoryMerging )
+                               && this.externalRepositoryIds.contains( repository.getId() ) ) )
             {
                 return;
             }
diff --git a/maven-core/src/main/java/org/apache/maven/project/artifact/ProjectArtifact.java b/maven-core/src/main/java/org/apache/maven/project/artifact/ProjectArtifact.java
index 8556a6af64..46e56dc470 100644
--- a/maven-core/src/main/java/org/apache/maven/project/artifact/ProjectArtifact.java
+++ b/maven-core/src/main/java/org/apache/maven/project/artifact/ProjectArtifact.java
@@ -58,8 +58,11 @@ public MavenProject getProject()
 
     public List<Dependency> getManagedDependencies()
     {
-        DependencyManagement depMgmt = project.getDependencyManagement();
-        return ( depMgmt != null ) ? depMgmt.getDependencies() : Collections.<Dependency>emptyList();
+        DependencyManagement depMngt = project.getDependencyManagement();
+        return ( depMngt != null )
+                   ? Collections.unmodifiableList( depMngt.getDependencies() )
+                   : Collections.<Dependency>emptyList();
+
     }
 
     static class PomArtifactHandler
diff --git a/maven-core/src/main/java/org/apache/maven/settings/SettingsUtils.java b/maven-core/src/main/java/org/apache/maven/settings/SettingsUtils.java
index 8da696e8ac..16ccdb65f0 100644
--- a/maven-core/src/main/java/org/apache/maven/settings/SettingsUtils.java
+++ b/maven-core/src/main/java/org/apache/maven/settings/SettingsUtils.java
@@ -139,7 +139,7 @@ public static Profile convertToSettingsProfile( org.apache.maven.model.Profile m
 
         profile.setId( settingsProfile.getId() );
 
-        profile.setSource( "settings.xml" );
+        profile.setSource( org.apache.maven.model.Profile.SOURCE_SETTINGS );
 
         Activation settingsActivation = settingsProfile.getActivation();
 
diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/EmptyLifecyclePluginAnalyzer.java b/maven-core/src/test/java/org/apache/maven/lifecycle/EmptyLifecyclePluginAnalyzer.java
index a812c26900..b48a909e42 100644
--- a/maven-core/src/test/java/org/apache/maven/lifecycle/EmptyLifecyclePluginAnalyzer.java
+++ b/maven-core/src/test/java/org/apache/maven/lifecycle/EmptyLifecyclePluginAnalyzer.java
@@ -23,6 +23,8 @@
 import java.util.LinkedHashSet;
 import java.util.Set;
 
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
 import org.apache.maven.model.Plugin;
 import org.apache.maven.model.PluginExecution;
 
@@ -32,6 +34,7 @@
 public class EmptyLifecyclePluginAnalyzer
     implements LifeCyclePluginAnalyzer
 {
+
     public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging )
     {
         Set<Plugin> plugins;
@@ -56,6 +59,26 @@
         return plugins;
     }
 
+    @Override
+    public Model getLifecycleModel( final Model model )
+    {
+        if ( model == null )
+        {
+            throw new NullPointerException( "model" );
+        }
+
+        final Model lifecycleModel = new Model();
+        lifecycleModel.setBuild( new Build() );
+        lifecycleModel.getBuild().setPluginManagement( model.getBuild() != null
+                                                           ? model.getBuild().getPluginManagement()
+                                                           : null );
+
+        lifecycleModel.getBuild().getPlugins().
+            addAll( this.getPluginsBoundByDefaultToAllLifecycles( model.getPackaging() ) );
+
+        return lifecycleModel;
+    }
+
     private Plugin newPlugin( String artifactId, String... goals )
     {
         Plugin plugin = new Plugin();
diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifeCyclePluginAnalyzerStub.java b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifeCyclePluginAnalyzerStub.java
index b067e244a9..7bd23e6279 100644
--- a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifeCyclePluginAnalyzerStub.java
+++ b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifeCyclePluginAnalyzerStub.java
@@ -12,23 +12,25 @@
  * or implied. See the License for the specific language governing permissions and limitations under
  * the License.
  */
-
 package org.apache.maven.lifecycle.internal.stub;
 
-import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer;
-import org.apache.maven.model.Plugin;
-import org.apache.maven.model.PluginExecution;
-
 import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.Set;
 
+import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+
 /**
  * @author Kristian Rosenvold
  */
 public class LifeCyclePluginAnalyzerStub
     implements LifeCyclePluginAnalyzer
 {
+
     public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging )
     {
         Set<Plugin> plugins;
@@ -53,6 +55,26 @@
         return plugins;
     }
 
+    @Override
+    public Model getLifecycleModel( final Model model )
+    {
+        if ( model == null )
+        {
+            throw new NullPointerException( "model" );
+        }
+
+        final Model lifecycleModel = new Model();
+        lifecycleModel.setBuild( new Build() );
+        lifecycleModel.getBuild().setPluginManagement( model.getBuild() != null
+                                                           ? model.getBuild().getPluginManagement()
+                                                           : null );
+
+        lifecycleModel.getBuild().getPlugins().
+            addAll( this.getPluginsBoundByDefaultToAllLifecycles( model.getPackaging() ) );
+
+        return lifecycleModel;
+    }
+
     private Plugin newPlugin( String artifactId, String... goals )
     {
         Plugin plugin = new Plugin();
diff --git a/maven-embedder/pom.xml b/maven-embedder/pom.xml
index 2994f04f5c..80d8ddb05f 100644
--- a/maven-embedder/pom.xml
+++ b/maven-embedder/pom.xml
@@ -25,7 +25,7 @@ under the License.
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.5.4-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-embedder</artifactId>
diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java b/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java
index a9038bff26..1261b098fa 100644
--- a/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java
+++ b/maven-embedder/src/main/java/org/apache/maven/cli/CLIManager.java
@@ -99,6 +99,8 @@
 
     public static final String LEGACY_LOCAL_REPOSITORY = "llr";
 
+    public static final String LEGACY_REACTOR_RESOLUTION = "lrr";
+
     public static final String BUILDER = "b";
 
     protected Options options;
@@ -140,6 +142,7 @@ public CLIManager()
         options.addOption( OptionBuilder.withLongOpt( "threads" ).hasArg().withDescription( "Thread count, for instance 2.0C where C is core multiplied" ).create( THREADS ) );
         options.addOption( OptionBuilder.withLongOpt( "legacy-local-repository" ).withDescription( "Use Maven 2 Legacy Local Repository behaviour, ie no use of _remote.repositories. Can also be activated by using -Dmaven.legacyLocalRepo=true" ).create( LEGACY_LOCAL_REPOSITORY ) );
         options.addOption( OptionBuilder.withLongOpt( "builder" ).hasArg().withDescription( "The id of the build strategy to use" ).create( BUILDER ) );
+        options.addOption( OptionBuilder.withLongOpt( "legacy-reactor-resolution" ).withDescription( "Use Maven 2 legacy reactor resolution behaviour, ie disable workspace resolution. Can also be activated by using -Dmaven.legacyReactorResolution=true" ).create( LEGACY_REACTOR_RESOLUTION ) );
 
         // Adding this back in for compatibility with the verifier that hard codes this option.
         options.addOption( OptionBuilder.withLongOpt( "no-plugin-registry" ).withDescription( "Ineffective, only kept for backward compatibility" ).create( "npr" ) );
diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
index ca8e040732..f24129484c 100644
--- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
+++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
@@ -19,6 +19,29 @@
  * under the License.
  */
 
+import java.io.BufferedInputStream;
+import java.io.Console;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import com.google.inject.AbstractModule;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Option;
@@ -27,6 +50,8 @@
 import org.apache.maven.BuildAbort;
 import org.apache.maven.InternalErrorException;
 import org.apache.maven.Maven;
+import org.apache.maven.artifact.InvalidRepositoryException;
+import org.apache.maven.bridge.MavenRepositorySystem;
 import org.apache.maven.building.FileSource;
 import org.apache.maven.building.Problem;
 import org.apache.maven.building.Source;
@@ -58,7 +83,15 @@
 import org.apache.maven.extension.internal.CoreExports;
 import org.apache.maven.extension.internal.CoreExtensionEntry;
 import org.apache.maven.lifecycle.LifecycleExecutionException;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.Repository;
+import org.apache.maven.model.building.DefaultModelProblem;
+import org.apache.maven.model.building.ModelProblem;
+import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.building.ModelProblemCollectorRequest;
 import org.apache.maven.model.building.ModelProcessor;
+import org.apache.maven.model.profile.DefaultProfileActivationContext;
+import org.apache.maven.model.profile.ProfileSelector;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.properties.internal.EnvironmentUtils;
 import org.apache.maven.properties.internal.SystemProperties;
@@ -90,29 +123,6 @@
 import org.sonatype.plexus.components.sec.dispatcher.SecUtil;
 import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity;
 
-import java.io.BufferedInputStream;
-import java.io.Console;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Properties;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
 import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
 
 // TODO push all common bits back to plexus cli and prepare for transition to Guice. We don't need 50 ways to make CLIs
@@ -165,6 +175,8 @@
 
     private Map<String, ConfigurationProcessor> configurationProcessors;
 
+    private ProfileSelector profileSelector;
+
     public MavenCli()
     {
         this( null );
@@ -285,6 +297,8 @@ public int doMain( CliRequest cliRequest )
             populateRequest( cliRequest );
             encryption( cliRequest );
             repository( cliRequest );
+            resolution( cliRequest );
+            profiles( cliRequest );
             return execute( cliRequest );
         }
         catch ( ExitException e )
@@ -684,6 +698,8 @@ protected void configure()
 
         dispatcher = (DefaultSecDispatcher) container.lookup( SecDispatcher.class, "maven" );
 
+        profileSelector = container.lookup( ProfileSelector.class );
+
         return container;
     }
 
@@ -748,9 +764,15 @@ protected void configure()
 
                 request = executionRequestPopulator.populateDefaults( request );
 
+                profileSelector = container.lookup( ProfileSelector.class );
+
+                profiles( request );
+
                 BootstrapCoreExtensionManager resolver = container.lookup( BootstrapCoreExtensionManager.class );
 
-                return resolver.loadCoreExtensions( request, providedArtifacts, extensions );
+                return Collections.unmodifiableList( resolver.loadCoreExtensions( request, providedArtifacts,
+                                                                                  extensions ) );
+
             }
             finally
             {
@@ -937,13 +959,114 @@ else if ( cliRequest.commandLine.hasOption( CLIManager.ENCRYPT_PASSWORD ) )
     private void repository( CliRequest cliRequest )
         throws Exception
     {
-        if ( cliRequest.commandLine.hasOption( CLIManager.LEGACY_LOCAL_REPOSITORY ) || Boolean.getBoolean(
-            "maven.legacyLocalRepo" ) )
+        if ( cliRequest.commandLine.hasOption( CLIManager.LEGACY_LOCAL_REPOSITORY )
+                 || Boolean.getBoolean( "maven.legacyLocalRepo" ) )
         {
             cliRequest.request.setUseLegacyLocalRepository( true );
         }
     }
 
+    private void resolution( CliRequest cliRequest )
+        throws Exception
+    {
+        if ( cliRequest.commandLine.hasOption( CLIManager.LEGACY_REACTOR_RESOLUTION )
+                 || Boolean.getBoolean( "maven.legacyReactorResolution" ) )
+        {
+            cliRequest.request.setUseLegacyReactorResolution( true );
+        }
+    }
+
+    private void profiles( final CliRequest request )
+    {
+        this.profiles( request.getRequest() );
+    }
+
+    private void profiles( final MavenExecutionRequest request )
+    {
+        // Adds repositories from profiles.
+        final DefaultProfileActivationContext profileActivationContext = new DefaultProfileActivationContext();
+        profileActivationContext.setActiveProfileIds( request.getActiveProfiles() );
+        profileActivationContext.setInactiveProfileIds( request.getInactiveProfiles() );
+        profileActivationContext.setSystemProperties( request.getSystemProperties() );
+        profileActivationContext.setUserProperties( request.getUserProperties() );
+        profileActivationContext.setProjectDirectory( request.getPom() != null
+                                                          ? request.getPom().getParentFile()
+                                                          : null );
+
+        final List<ModelProblem> modelProblems = new ArrayList<>();
+        final List<Profile> activeProfiles =
+            this.profileSelector.getActiveProfiles( request.getProfiles(), profileActivationContext,
+                                                    new ModelProblemCollector()
+                                                    {
+
+                                                        @Override
+                                                        public void add( final ModelProblemCollectorRequest req )
+                                                        {
+                                                            modelProblems.add( new DefaultModelProblem(
+                                                                    req.getMessage(), req.getSeverity(),
+                                                                    req.getVersion(), Profile.SOURCE_SETTINGS, -1, -1,
+                                                                    null, req.getException() ) );
+
+                                                        }
+
+                                                    } );
+
+        if ( !modelProblems.isEmpty() )
+        {
+            slf4jLogger.warn( "" );
+            slf4jLogger.warn( "Some problems were encountered while processing profiles" );
+
+            for ( final ModelProblem problem : modelProblems )
+            {
+                slf4jLogger.warn( problem.getMessage(), problem.getException() );
+            }
+
+            slf4jLogger.warn( "" );
+        }
+
+        if ( !activeProfiles.isEmpty() )
+        {
+            for ( final Profile profile : activeProfiles )
+            {
+                final List<Repository> remoteRepositories = profile.getRepositories();
+
+                for ( final Repository remoteRepository : remoteRepositories )
+                {
+                    try
+                    {
+                        request.addRemoteRepository(
+                            MavenRepositorySystem.buildArtifactRepository( remoteRepository ) );
+
+                    }
+                    catch ( final InvalidRepositoryException e )
+                    {
+                        slf4jLogger.warn( String.format( "Failure adding repository '%s' from profile '%s'.",
+                                                         remoteRepository.getId(), profile.getId() ), e );
+
+                    }
+                }
+
+                final List<Repository> pluginRepositories = profile.getPluginRepositories();
+
+                for ( final Repository pluginRepository : pluginRepositories )
+                {
+                    try
+                    {
+                        request.addPluginArtifactRepository(
+                            MavenRepositorySystem.buildArtifactRepository( pluginRepository ) );
+
+                    }
+                    catch ( InvalidRepositoryException e )
+                    {
+                        slf4jLogger.warn( String.format( "Failure adding plugin repository '%s' from profile '%s'.",
+                                                         pluginRepository.getId(), profile.getId() ), e );
+
+                    }
+                }
+            }
+        }
+    }
+
     private int execute( CliRequest cliRequest )
         throws MavenExecutionRequestPopulationException
     {
diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/configuration/SettingsXmlConfigurationProcessor.java b/maven-embedder/src/main/java/org/apache/maven/cli/configuration/SettingsXmlConfigurationProcessor.java
index 2536a22ced..9b21a3be60 100644
--- a/maven-embedder/src/main/java/org/apache/maven/cli/configuration/SettingsXmlConfigurationProcessor.java
+++ b/maven-embedder/src/main/java/org/apache/maven/cli/configuration/SettingsXmlConfigurationProcessor.java
@@ -21,11 +21,8 @@
 
 import java.io.File;
 import java.io.FileNotFoundException;
-import java.util.List;
 
 import org.apache.commons.cli.CommandLine;
-import org.apache.maven.artifact.InvalidRepositoryException;
-import org.apache.maven.bridge.MavenRepositorySystem;
 import org.apache.maven.building.Source;
 import org.apache.maven.cli.CLIManager;
 import org.apache.maven.cli.CliRequest;
@@ -33,7 +30,6 @@
 import org.apache.maven.execution.MavenExecutionRequestPopulationException;
 import org.apache.maven.settings.Mirror;
 import org.apache.maven.settings.Proxy;
-import org.apache.maven.settings.Repository;
 import org.apache.maven.settings.Server;
 import org.apache.maven.settings.Settings;
 import org.apache.maven.settings.SettingsUtils;
@@ -42,7 +38,6 @@
 import org.apache.maven.settings.building.SettingsBuildingRequest;
 import org.apache.maven.settings.building.SettingsBuildingResult;
 import org.apache.maven.settings.building.SettingsProblem;
-import org.apache.maven.settings.crypto.SettingsDecrypter;
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.component.annotations.Requirement;
 import org.slf4j.Logger;
@@ -54,6 +49,7 @@
 public class SettingsXmlConfigurationProcessor
     implements ConfigurationProcessor
 {
+
     public static final String HINT = "settings";
 
     public static final String USER_HOME = System.getProperty( "user.home" );
@@ -71,9 +67,6 @@
     @Requirement
     private SettingsBuilder settingsBuilder;
 
-    @Requirement
-    private SettingsDecrypter settingsDecrypter;
-
     @Override
     public void process( CliRequest cliRequest )
         throws Exception
@@ -91,8 +84,9 @@ public void process( CliRequest cliRequest )
 
             if ( !userSettingsFile.isFile() )
             {
-                throw new FileNotFoundException( "The specified user settings file does not exist: "
-                    + userSettingsFile );
+                throw new FileNotFoundException( String.format( "The specified user settings file does not exist: %s",
+                                                                userSettingsFile ) );
+
             }
         }
         else
@@ -109,8 +103,9 @@ public void process( CliRequest cliRequest )
 
             if ( !globalSettingsFile.isFile() )
             {
-                throw new FileNotFoundException( "The specified global settings file does not exist: "
-                    + globalSettingsFile );
+                throw new FileNotFoundException( String.format( "The specified global settings file does not exist: %s",
+                                                                globalSettingsFile ) );
+
             }
         }
         else
@@ -132,10 +127,13 @@ public void process( CliRequest cliRequest )
             request.getEventSpyDispatcher().onEvent( settingsRequest );
         }
 
-        logger.debug( "Reading global settings from "
-            + getLocation( settingsRequest.getGlobalSettingsSource(), settingsRequest.getGlobalSettingsFile() ) );
-        logger.debug( "Reading user settings from "
-            + getLocation( settingsRequest.getUserSettingsSource(), settingsRequest.getUserSettingsFile() ) );
+        logger.debug( String.format( "Reading global settings from %s",
+                                     getLocation( settingsRequest.getGlobalSettingsSource(),
+                                                  settingsRequest.getGlobalSettingsFile() ) ) );
+
+        logger.debug( String.format( "Reading user settings from %s",
+                                     getLocation( settingsRequest.getUserSettingsSource(),
+                                                  settingsRequest.getUserSettingsFile() ) ) );
 
         SettingsBuildingResult settingsResult = settingsBuilder.build( settingsRequest );
 
@@ -221,43 +219,13 @@ private MavenExecutionRequest populateFromSettings( MavenExecutionRequest reques
             request.addMirror( mirror );
         }
 
-        request.setActiveProfiles( settings.getActiveProfiles() );
+        request.addActiveProfiles( settings.getActiveProfiles() );
 
         for ( org.apache.maven.settings.Profile rawProfile : settings.getProfiles() )
         {
             request.addProfile( SettingsUtils.convertFromSettingsProfile( rawProfile ) );
-
-            if ( settings.getActiveProfiles().contains( rawProfile.getId() ) )
-            {
-                List<Repository> remoteRepositories = rawProfile.getRepositories();
-                for ( Repository remoteRepository : remoteRepositories )
-                {
-                    try
-                    {
-                        request.addRemoteRepository( 
-                            MavenRepositorySystem.buildArtifactRepository( remoteRepository ) );
-                    }
-                    catch ( InvalidRepositoryException e )
-                    {
-                        // do nothing for now
-                    }
-                }
-                
-                List<Repository> pluginRepositories = rawProfile.getPluginRepositories();
-                for ( Repository pluginRepository : pluginRepositories )
-                {
-                    try
-                    {
-                        request.addPluginArtifactRepository( 
-                            MavenRepositorySystem.buildArtifactRepository( pluginRepository ) );
-                    }
-                    catch ( InvalidRepositoryException e )
-                    {
-                        // do nothing for now
-                    }
-                }                
-            }
         }
+
         return request;
     }
 
@@ -290,4 +258,5 @@ else if ( file.getPath().startsWith( File.separator ) )
             return new File( workingDirectory, file.getPath() ).getAbsoluteFile();
         }
     }
+
 }
diff --git a/maven-model-builder/pom.xml b/maven-model-builder/pom.xml
index a009b5cfb8..dd60146275 100644
--- a/maven-model-builder/pom.xml
+++ b/maven-model-builder/pom.xml
@@ -25,7 +25,7 @@ under the License.
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.5.4-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-model-builder</artifactId>
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
index 44ee334c30..b6acf06f95 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilder.java
@@ -19,6 +19,17 @@
  * under the License.
  */
 
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
 
 import org.apache.commons.lang3.Validate;
 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
@@ -28,6 +39,7 @@
 import org.apache.maven.model.Build;
 import org.apache.maven.model.Dependency;
 import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.Exclusion;
 import org.apache.maven.model.InputLocation;
 import org.apache.maven.model.InputSource;
 import org.apache.maven.model.Model;
@@ -65,17 +77,6 @@
 import org.codehaus.plexus.interpolation.MapBasedValueSource;
 import org.codehaus.plexus.interpolation.StringSearchInterpolator;
 
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
 import static org.apache.maven.model.building.Result.error;
 import static org.apache.maven.model.building.Result.newResult;
 
@@ -86,6 +87,7 @@
 public class DefaultModelBuilder
     implements ModelBuilder
 {
+
     @Requirement
     private ModelProcessor modelProcessor;
 
@@ -253,8 +255,8 @@ public ModelBuildingResult build( ModelBuildingRequest request )
         DefaultProfileActivationContext profileActivationContext = getProfileActivationContext( request );
 
         problems.setSource( "(external profiles)" );
-        List<Profile> activeExternalProfiles = profileSelector.getActiveProfiles( request.getProfiles(),
-                                                                                  profileActivationContext, problems );
+        List<Profile> activeExternalProfiles =
+            profileSelector.getActiveProfiles( request.getProfiles(), profileActivationContext, problems );
 
         result.setActiveExternalProfiles( activeExternalProfiles );
 
@@ -301,8 +303,9 @@ public ModelBuildingResult build( ModelBuildingRequest request )
 
             profileActivationContext.setProjectProperties( tmpModel.getProperties() );
 
-            List<Profile> activePomProfiles = profileSelector.getActiveProfiles( rawModel.getProfiles(),
-                                                                                 profileActivationContext, problems );
+            List<Profile> activePomProfiles =
+                profileSelector.getActiveProfiles( rawModel.getProfiles(), profileActivationContext, problems );
+
             currentData.setActiveProfiles( activePomProfiles );
 
             Map<String, Activation> interpolatedActivations = getProfileActivations( rawModel, false );
@@ -337,13 +340,13 @@ public ModelBuildingResult build( ModelBuildingRequest request )
             }
             else if ( currentData == resultData )
             { // First iteration - add initial id after version resolution.
-                currentData.setGroupId( currentData.getRawModel().getGroupId() == null ? parentData.getGroupId()
-                                                                                      : currentData.getRawModel()
-                                                                                          .getGroupId() );
+                currentData.setGroupId( currentData.getRawModel().getGroupId() == null
+                                            ? parentData.getGroupId()
+                                            : currentData.getRawModel().getGroupId() );
 
-                currentData.setVersion( currentData.getRawModel().getVersion() == null ? parentData.getVersion()
-                                                                                      : currentData.getRawModel()
-                                                                                          .getVersion() );
+                currentData.setVersion( currentData.getRawModel().getVersion() == null
+                                            ? parentData.getVersion()
+                                            : currentData.getRawModel().getVersion() );
 
                 currentData.setArtifactId( currentData.getRawModel().getArtifactId() );
                 parentIds.add( currentData.getId() );
@@ -362,8 +365,9 @@ else if ( !parentIds.add( parentData.getId() ) )
                 }
                 message += parentData.getId();
 
-                problems.add( new ModelProblemCollectorRequest( ModelProblem.Severity.FATAL, ModelProblem.Version.BASE )
-                    .setMessage( message ) );
+                problems.add( new ModelProblemCollectorRequest( ModelProblem.Severity.FATAL,
+                                                                ModelProblem.Version.BASE ).
+                    setMessage( message ) );
 
                 throw problems.newModelBuildingException();
             }
@@ -376,24 +380,34 @@ else if ( !parentIds.add( parentData.getId() ) )
         problems.setSource( inputModel );
         checkPluginVersions( lineage, request, problems );
 
-        // inheritance assembly
-        assembleInheritance( lineage, request, problems );
+        // [MNG-4052] import scope dependencies prefer to download pom rather than find it in the current project
+        // [MNG-5971] Imported dependencies should be available to inheritance processing
+        //
+        // This first phase of model building is used for building models holding just enough information to map
+        // groupId:artifactId:version to pom files and to provide modules to build. For this, inheritance and
+        // interpolation needs to be performed. A temporary model is built in phase 1 applying inheritance and
+        // interpolation to fill in those values but is not returned. The rest of the model building takes place in
+        // phase 2.
+        final DefaultModelProblemCollector intermediateProblems = new DefaultModelProblemCollector( result );
+        final List<Model> intermediateLineage = new ArrayList<>( lineage.size() );
+        for ( final ModelData modelData : lineage )
+        {
+            intermediateLineage.add( modelData.getModel().clone() );
+        }
+        assembleInheritance( intermediateLineage, request, intermediateProblems );
+
+        Model intermediateModel = intermediateLineage.get( 0 );
+        intermediateModel = interpolateModel( intermediateModel, request, intermediateProblems );
 
         Model resultModel = resultData.getModel();
 
+        resultModel.setGroupId( intermediateModel.getGroupId() );
+        resultModel.setArtifactId( intermediateModel.getArtifactId() );
+        resultModel.setVersion( intermediateModel.getVersion() );
+
         problems.setSource( resultModel );
         problems.setRootModel( resultModel );
 
-        // model interpolation
-        resultModel = interpolateModel( resultModel, request, problems );
-        resultData.setModel( resultModel );
-
-        // url normalization
-        modelUrlNormalizer.normalize( resultModel, request );
-
-        // Now the fully interpolated model is available: reconfigure the resolver
-        configureResolver( request.getModelResolver(), resultModel, problems, true );
-
         resultData.setGroupId( resultModel.getGroupId() );
         resultData.setArtifactId( resultModel.getArtifactId() );
         resultData.setVersion( resultModel.getVersion() );
@@ -407,6 +421,7 @@ else if ( !parentIds.add( parentData.getId() ) )
             result.addModelId( modelId );
             result.setActivePomProfiles( modelId, currentData.getActiveProfiles() );
             result.setRawModel( modelId, currentData.getRawModel() );
+            result.setEffectiveModel( modelId, currentData.getModel() );
         }
 
         if ( !request.isTwoPhaseBuilding() )
@@ -420,21 +435,41 @@ else if ( !parentIds.add( parentData.getId() ) )
     @Override
     public ModelBuildingResult build( ModelBuildingRequest request, ModelBuildingResult result )
         throws ModelBuildingException
-    {
-        return build( request, result, new LinkedHashSet<String>() );
-    }
-
-    private ModelBuildingResult build( ModelBuildingRequest request, ModelBuildingResult result,
-                                       Collection<String> imports )
-        throws ModelBuildingException
     {
         // phase 2
         Model resultModel = result.getEffectiveModel();
 
+        // Reset to on-disk values to not suppress any warnings from phase 1.
+        resultModel.setGroupId( result.getRawModel().getGroupId() );
+        resultModel.setArtifactId( result.getRawModel().getArtifactId() );
+        resultModel.setVersion( result.getRawModel().getVersion() );
+
         DefaultModelProblemCollector problems = new DefaultModelProblemCollector( result );
         problems.setSource( resultModel );
         problems.setRootModel( resultModel );
 
+        final List<Model> lineage = new ArrayList<>( result.getModelIds().size() );
+
+        for ( final String modelId : result.getModelIds() )
+        {
+            lineage.add( result.getEffectiveModel( modelId ) );
+        }
+
+        // [MNG-5971] Imported dependencies should be available to inheritance processing
+        processImports( lineage, "include", "pom", request, problems );
+        problems.setSource( resultModel );
+
+        // inheritance assembly
+        assembleInheritance( lineage, request, problems );
+
+        resultModel = interpolateModel( resultModel, request, problems );
+
+        // url normalization
+        modelUrlNormalizer.normalize( resultModel, request );
+
+        // Now the fully interpolated model is available: reconfigure the resolver
+        configureResolver( request.getModelResolver(), resultModel, problems, true );
+
         // model path translation
         modelPathTranslator.alignToBaseDirectory( resultModel, resultModel.getProjectDirectory(), request );
 
@@ -454,8 +489,7 @@ private ModelBuildingResult build( ModelBuildingRequest request, ModelBuildingRe
             lifecycleBindingsInjector.injectLifecycleBindings( resultModel, request, problems );
         }
 
-        // dependency management import
-        importDependencyManagement( resultModel, request, problems, imports );
+        this.importDependencyManagement( resultModel, "import", request, problems, new HashSet<String>() );
 
         // dependency management injection
         dependencyManagementInjector.injectManagement( resultModel, request, problems );
@@ -488,10 +522,13 @@ private ModelBuildingResult build( ModelBuildingRequest request, ModelBuildingRe
     @Override
     public Result<? extends Model> buildRawModel( File pomFile, int validationLevel, boolean locationTracking )
     {
-        final ModelBuildingRequest request = new DefaultModelBuildingRequest().setValidationLevel( validationLevel )
-            .setLocationTracking( locationTracking );
+        final ModelBuildingRequest request = new DefaultModelBuildingRequest().
+            setValidationLevel( validationLevel ).
+            setLocationTracking( locationTracking );
+
         final DefaultModelProblemCollector collector =
             new DefaultModelProblemCollector( new DefaultModelBuildingResult() );
+
         try
         {
             return newResult( readModel( null, pomFile, request, collector ), collector.getProblems() );
@@ -556,15 +593,17 @@ private Model readModel( ModelSource modelSource, File pomFile, ModelBuildingReq
 
                 if ( pomFile != null )
                 {
-                    problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.V20 )
-                        .setMessage( "Malformed POM " + modelSource.getLocation() + ": " + e.getMessage() )
-                        .setException( e ) );
+                    problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.V20 ).
+                        setMessage( "Malformed POM " + modelSource.getLocation() + ": " + e.getMessage() ).
+                        setException( e ) );
+
                 }
                 else
                 {
-                    problems.add( new ModelProblemCollectorRequest( Severity.WARNING, Version.V20 )
-                        .setMessage( "Malformed POM " + modelSource.getLocation() + ": " + e.getMessage() )
-                        .setException( e ) );
+                    problems.add( new ModelProblemCollectorRequest( Severity.WARNING, Version.V20 ).
+                        setMessage( "Malformed POM " + modelSource.getLocation() + ": " + e.getMessage() ).
+                        setException( e ) );
+
                 }
             }
 
@@ -576,14 +615,16 @@ private Model readModel( ModelSource modelSource, File pomFile, ModelBuildingReq
         }
         catch ( ModelParseException e )
         {
-            problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.BASE )
-                .setMessage( "Non-parseable POM " + modelSource.getLocation() + ": " + e.getMessage() )
-                .setException( e ) );
+            problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.BASE ).
+                setMessage( "Non-parseable POM " + modelSource.getLocation() + ": " + e.getMessage() ).
+                setException( e ) );
+
             throw problems.newModelBuildingException();
         }
         catch ( IOException e )
         {
             String msg = e.getMessage();
+
             if ( msg == null || msg.length() <= 0 )
             {
                 // NOTE: There's java.nio.charset.MalformedInputException and sun.io.MalformedInputException
@@ -596,14 +637,18 @@ private Model readModel( ModelSource modelSource, File pomFile, ModelBuildingReq
                     msg = e.getClass().getSimpleName();
                 }
             }
-            problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.BASE )
-                .setMessage( "Non-readable POM " + modelSource.getLocation() + ": " + msg ).setException( e ) );
+
+            problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.BASE ).
+                setMessage( "Non-readable POM " + modelSource.getLocation() + ": " + msg ).
+                setException( e ) );
+
             throw problems.newModelBuildingException();
         }
 
         model.setPomFile( pomFile );
 
         problems.setSource( model );
+
         modelValidator.validateRawModel( model, request, problems );
 
         if ( hasFatalErrors( problems ) )
@@ -652,9 +697,11 @@ private void configureResolver( ModelResolver modelResolver, Model model, Defaul
             }
             catch ( InvalidRepositoryException e )
             {
-                problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
-                    .setMessage( "Invalid repository " + repository.getId() + ": " + e.getMessage() )
-                    .setLocation( repository.getLocation( "" ) ).setException( e ) );
+                problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).
+                    setMessage( "Invalid repository " + repository.getId() + ": " + e.getMessage() ).
+                    setLocation( repository.getLocation( "" ) ).
+                    setException( e ) );
+
             }
         }
     }
@@ -706,21 +753,150 @@ private void checkPluginVersions( List<ModelData> lineage, ModelBuildingRequest
             if ( versions.get( key ) == null && managedVersions.get( key ) == null )
             {
                 InputLocation location = plugins.get( key ).getLocation( "" );
-                problems
-                    .add( new ModelProblemCollectorRequest( Severity.WARNING, Version.V20 )
-                        .setMessage( "'build.plugins.plugin.version' for " + key + " is missing." )
-                        .setLocation( location ) );
+                problems.add( new ModelProblemCollectorRequest( Severity.WARNING, Version.V20 ).
+                    setMessage( "'build.plugins.plugin.version' for " + key + " is missing." ).
+                    setLocation( location ) );
+
             }
         }
     }
 
-    private void assembleInheritance( List<ModelData> lineage, ModelBuildingRequest request,
+    private void processImports( final List<Model> lineage, final String scope, final String packaging,
+                                 final ModelBuildingRequest request, final DefaultModelProblemCollector problems )
+    {
+        // [MNG-5971] Imported dependencies should be available to inheritance processing
+        // It's not possible to support all ${project.xyz} properties in dependency management import declarations
+        // because import processing is performed before the final inheritance processing is performed. So the set of
+        // ${project.xyz} properties supported in dependency management import declarations is limited.
+
+        final List<Model> intermediateLineage = new ArrayList<>( lineage.size() );
+
+        for ( int i = 0, s0 = lineage.size(); i < s0; i++ )
+        {
+            intermediateLineage.add( lineage.get( i ).clone() );
+        }
+
+        for ( int i = intermediateLineage.size() - 2; i >= 0; i-- )
+        {
+            final Model parent = intermediateLineage.get( i + 1 );
+            final Model child = intermediateLineage.get( i );
+
+            if ( child.getGroupId() == null )
+            {
+                // Support ${project.groupId} in dependency management import declarations.
+                child.setGroupId( parent.getGroupId() );
+            }
+            if ( child.getVersion() == null )
+            {
+                // Support ${project.version} in dependency management import declarations.
+                child.setVersion( parent.getVersion() );
+            }
+
+            final Properties properties = new Properties();
+            properties.putAll( parent.getProperties() );
+            properties.putAll( child.getProperties() );
+            child.setProperties( properties );
+
+            final List<Repository> repositories = new ArrayList<>();
+            repositories.addAll( child.getRepositories() );
+
+            for ( final Repository parentRepository : parent.getRepositories() )
+            {
+                if ( !repositories.contains( parentRepository ) )
+                {
+                    repositories.add( parentRepository );
+                }
+            }
+
+            child.setRepositories( repositories );
+        }
+
+        final Properties effectiveProperties = intermediateLineage.get( 0 ).getProperties();
+
+        final DefaultModelProblemCollector intermediateProblems =
+            new DefaultModelProblemCollector( new DefaultModelBuildingResult() );
+
+        // Interpolates the intermediate model.
+        // MNG-6079: Uses the effective properties of the result model to support property overriding.
+        for ( int i = 0, s0 = intermediateLineage.size(); i < s0; i++ )
+        {
+            final Model model = intermediateLineage.get( i );
+            model.setProperties( effectiveProperties );
+            intermediateProblems.setSource( model );
+            this.interpolateModel( model, request, intermediateProblems );
+        }
+
+        // Exchanges 'include' scope dependencies in the original lineage with possibly interpolated values.
+        for ( int i = 0, s0 = lineage.size(); i < s0; i++ )
+        {
+            final Model model = lineage.get( i );
+
+            if ( model.getDependencyManagement() != null )
+            {
+                for ( int j = 0, s1 = model.getDependencyManagement().getDependencies().size(); j < s1; j++ )
+                {
+                    final Dependency dependency = model.getDependencyManagement().getDependencies().get( j );
+
+                    if ( scope.equals( dependency.getScope() ) && packaging.equals( dependency.getType() ) )
+                    {
+                        final Dependency interpolated =
+                            intermediateLineage.get( i ).getDependencyManagement().getDependencies().get( j );
+
+                        model.getDependencyManagement().getDependencies().set( j, interpolated );
+                    }
+                }
+            }
+        }
+
+        // [MNG-4488] [regression] Parent POMs resolved from repository are validated in strict mode
+        ModelBuildingRequest lenientRequest = request;
+        if ( request.getValidationLevel() > ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 )
+        {
+            lenientRequest = new FilterModelBuildingRequest( request )
+            {
+
+                @Override
+                public int getValidationLevel()
+                {
+                    return ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0;
+                }
+
+            };
+        }
+
+        // Sets up the resolver to use the effective repositories to support repository overriding.
+        if ( lenientRequest.getModelResolver() != null )
+        {
+            for ( Repository repository : intermediateLineage.get( 0 ).getRepositories() )
+            {
+                try
+                {
+                    lenientRequest.getModelResolver().addRepository( repository, true );
+                }
+                catch ( InvalidRepositoryException e )
+                {
+                    problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+                        .setMessage( "Invalid repository " + repository.getId() + ": " + e.getMessage() )
+                        .setLocation( repository.getLocation( "" ) ).setException( e ) );
+
+                }
+            }
+        }
+
+        // Imports dependencies into the original model using the effective repositories.
+        for ( int i = 0, s0 = lineage.size(); i < s0; i++ )
+        {
+            this.importDependencyManagement( lineage.get( i ), scope, lenientRequest, problems, new HashSet<String>() );
+        }
+    }
+
+    private void assembleInheritance( List<Model> lineage, ModelBuildingRequest request,
                                       ModelProblemCollector problems )
     {
         for ( int i = lineage.size() - 2; i >= 0; i-- )
         {
-            Model parent = lineage.get( i + 1 ).getModel();
-            Model child = lineage.get( i ).getModel();
+            Model parent = lineage.get( i + 1 );
+            Model child = lineage.get( i );
             inheritanceAssembler.assembleModelInheritance( child, parent, request, problems );
         }
     }
@@ -858,10 +1034,11 @@ private ModelData readParent( Model childModel, ModelSource childSource, ModelBu
 
             if ( !"pom".equals( parentModel.getPackaging() ) )
             {
-                problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
-                    .setMessage( "Invalid packaging for parent POM " + ModelProblemUtils.toSourceHint( parentModel )
-                                     + ", must be \"pom\" but is \"" + parentModel.getPackaging() + "\"" )
-                    .setLocation( parentModel.getLocation( "packaging" ) ) );
+                problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).
+                    setMessage( "Invalid packaging for parent POM " + ModelProblemUtils.toSourceHint( parentModel )
+                                    + ", must be \"pom\" but is \"" + parentModel.getPackaging() + "\"" ).
+                    setLocation( parentModel.getLocation( "packaging" ) ) );
+
             }
         }
         else
@@ -903,11 +1080,15 @@ private ModelData readParentLocally( Model childModel, ModelSource childSource,
             {
                 candidateModel =
                     resolver.resolveRawModel( parent.getGroupId(), parent.getArtifactId(), parent.getVersion() );
+
             }
             catch ( UnresolvableModelException e )
             {
-                problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.BASE ) //
-                .setMessage( e.getMessage().toString() ).setLocation( parent.getLocation( "" ) ).setException( e ) );
+                problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.BASE ).
+                    setMessage( e.getMessage().toString() ).
+                    setLocation( parent.getLocation( "" ) ).
+                    setException( e ) );
+
                 throw problems.newModelBuildingException();
             }
             if ( candidateModel == null )
@@ -922,7 +1103,6 @@ private ModelData readParentLocally( Model childModel, ModelSource childSource,
         // have a model that is suitable, yet more checks are done here and the one for the version is problematic
         // before because with parents as ranges it will never work in this scenario.
         //
-
         String groupId = candidateModel.getGroupId();
         if ( groupId == null && candidateModel.getParent() != null )
         {
@@ -936,7 +1116,7 @@ private ModelData readParentLocally( Model childModel, ModelSource childSource,
         }
 
         if ( groupId == null || !groupId.equals( parent.getGroupId() ) || artifactId == null
-            || !artifactId.equals( parent.getArtifactId() ) )
+                 || !artifactId.equals( parent.getArtifactId() ) )
         {
             StringBuilder buffer = new StringBuilder( 256 );
             buffer.append( "'parent.relativePath'" );
@@ -949,8 +1129,10 @@ private ModelData readParentLocally( Model childModel, ModelSource childSource,
             buffer.append( parent.getArtifactId() ).append( ", please verify your project structure" );
 
             problems.setSource( childModel );
-            problems.add( new ModelProblemCollectorRequest( Severity.WARNING, Version.BASE )
-                .setMessage( buffer.toString() ).setLocation( parent.getLocation( "" ) ) );
+            problems.add( new ModelProblemCollectorRequest( Severity.WARNING, Version.BASE ).
+                setMessage( buffer.toString() ).
+                setLocation( parent.getLocation( "" ) ) );
+
             return null;
         }
         if ( version != null && parent.getVersion() != null && !version.equals( parent.getVersion() ) )
@@ -1006,7 +1188,6 @@ private ModelData readParentLocally( Model childModel, ModelSource childSource,
         /*
          * if ( version == null || !version.equals( parent.getVersion() ) ) { return null; }
          */
-
         ModelData parentData = new ModelData( candidateSource, candidateModel, groupId, artifactId, version );
 
         return parentData;
@@ -1044,7 +1225,8 @@ private ModelData readParentExternally( Model childModel, ModelBuildingRequest r
         ModelResolver modelResolver = request.getModelResolver();
 
         Validate.notNull( modelResolver, "request.modelResolver cannot be null (parent POM %s and POM %s)",
-            ModelProblemUtils.toId( groupId, artifactId, version ), ModelProblemUtils.toSourceHint( childModel ) );
+                          ModelProblemUtils.toId( groupId, artifactId, version ),
+                          ModelProblemUtils.toSourceHint( childModel ) );
 
         ModelSource modelSource;
         try
@@ -1077,8 +1259,11 @@ private ModelData readParentExternally( Model childModel, ModelBuildingRequest r
                 }
             }
 
-            problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.BASE )
-                .setMessage( buffer.toString() ).setLocation( parent.getLocation( "" ) ).setException( e ) );
+            problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.BASE ).
+                setMessage( buffer.toString() ).
+                setLocation( parent.getLocation( "" ) ).
+                setException( e ) );
+
             throw problems.newModelBuildingException();
         }
 
@@ -1087,11 +1272,13 @@ private ModelData readParentExternally( Model childModel, ModelBuildingRequest r
         {
             lenientRequest = new FilterModelBuildingRequest( request )
             {
+
                 @Override
                 public int getValidationLevel()
                 {
                     return ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0;
                 }
+
             };
         }
 
@@ -1102,8 +1289,9 @@ public int getValidationLevel()
             if ( childModel.getVersion() == null )
             {
                 // Message below is checked for in the MNG-2199 core IT.
-                problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.V31 )
-                    .setMessage( "Version must be a constant" ).setLocation( childModel.getLocation( "" ) ) );
+                problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.V31 ).
+                    setMessage( "Version must be a constant" ).
+                    setLocation( childModel.getLocation( "" ) ) );
 
             }
             else
@@ -1111,9 +1299,9 @@ public int getValidationLevel()
                 if ( childModel.getVersion().contains( "${" ) )
                 {
                     // Message below is checked for in the MNG-2199 core IT.
-                    problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.V31 )
-                        .setMessage( "Version must be a constant" )
-                        .setLocation( childModel.getLocation( "version" ) ) );
+                    problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.V31 ).
+                        setMessage( "Version must be a constant" ).
+                        setLocation( childModel.getLocation( "version" ) ) );
 
                 }
             }
@@ -1133,7 +1321,7 @@ private Model getSuperModel()
     }
 
     @SuppressWarnings( "checkstyle:methodlength" )
-    private void importDependencyManagement( Model model, ModelBuildingRequest request,
+    private void importDependencyManagement( Model model, String scope, ModelBuildingRequest request,
                                              DefaultModelProblemCollector problems, Collection<String> importIds )
     {
         DependencyManagement depMgmt = model.getDependencyManagement();
@@ -1143,22 +1331,19 @@ private void importDependencyManagement( Model model, ModelBuildingRequest reque
             return;
         }
 
+        problems.setSource( model );
+
         String importing = model.getGroupId() + ':' + model.getArtifactId() + ':' + model.getVersion();
 
         importIds.add( importing );
 
-        final WorkspaceModelResolver workspaceResolver = request.getWorkspaceModelResolver();
-        final ModelResolver modelResolver = request.getModelResolver();
-
-        ModelBuildingRequest importRequest = null;
-
         List<DependencyManagement> importMgmts = null;
 
         for ( Iterator<Dependency> it = depMgmt.getDependencies().iterator(); it.hasNext(); )
         {
             Dependency dependency = it.next();
 
-            if ( !"pom".equals( dependency.getType() ) || !"import".equals( dependency.getScope() ) )
+            if ( !"pom".equals( dependency.getType() ) || !scope.equals( dependency.getScope() ) )
             {
                 continue;
             }
@@ -1171,26 +1356,28 @@ private void importDependencyManagement( Model model, ModelBuildingRequest reque
 
             if ( groupId == null || groupId.length() <= 0 )
             {
-                problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
-                    .setMessage( "'dependencyManagement.dependencies.dependency.groupId' for "
-                                     + dependency.getManagementKey() + " is missing." )
-                    .setLocation( dependency.getLocation( "" ) ) );
+                problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).
+                    setMessage( "'dependencyManagement.dependencies.dependency.groupId' for "
+                                    + dependency.getManagementKey() + " is missing." ).
+                    setLocation( dependency.getLocation( "" ) ) );
                 continue;
             }
             if ( artifactId == null || artifactId.length() <= 0 )
             {
-                problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
-                    .setMessage( "'dependencyManagement.dependencies.dependency.artifactId' for "
-                                     + dependency.getManagementKey() + " is missing." )
-                    .setLocation( dependency.getLocation( "" ) ) );
+                problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).
+                    setMessage( "'dependencyManagement.dependencies.dependency.artifactId' for "
+                                    + dependency.getManagementKey() + " is missing." ).
+                    setLocation( dependency.getLocation( "" ) ) );
+
                 continue;
             }
             if ( version == null || version.length() <= 0 )
             {
-                problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
-                    .setMessage( "'dependencyManagement.dependencies.dependency.version' for "
-                                     + dependency.getManagementKey() + " is missing." )
-                    .setLocation( dependency.getLocation( "" ) ) );
+                problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).
+                    setMessage( "'dependencyManagement.dependencies.dependency.version' for "
+                                    + dependency.getManagementKey() + " is missing." ).
+                    setLocation( dependency.getLocation( "" ) ) );
+
                 continue;
             }
 
@@ -1198,14 +1385,13 @@ private void importDependencyManagement( Model model, ModelBuildingRequest reque
 
             if ( importIds.contains( imported ) )
             {
-                String message = "The dependencies of type=pom and with scope=import form a cycle: ";
+                String message = "The dependencies of type=pom and scope=" + scope + " form a cycle: ";
                 for ( String modelId : importIds )
                 {
                     message += modelId + " -> ";
                 }
                 message += imported;
                 problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).setMessage( message ) );
-
                 continue;
             }
 
@@ -1214,104 +1400,220 @@ private void importDependencyManagement( Model model, ModelBuildingRequest reque
 
             if ( importMgmt == null )
             {
-                if ( workspaceResolver == null && modelResolver == null )
+                if ( request.getWorkspaceModelResolver() == null && request.getModelResolver() == null )
                 {
                     throw new NullPointerException( String.format(
                         "request.workspaceModelResolver and request.modelResolver cannot be null"
-                        + " (parent POM %s and POM %s)",
+                            + " (parent POM %s and POM %s)",
                         ModelProblemUtils.toId( groupId, artifactId, version ),
                         ModelProblemUtils.toSourceHint( model ) ) );
+
                 }
 
                 Model importModel = null;
-                if ( workspaceResolver != null )
+                if ( request.getWorkspaceModelResolver() != null )
                 {
                     try
                     {
-                        importModel = workspaceResolver.resolveEffectiveModel( groupId, artifactId, version );
+                        importModel =
+                            request.getWorkspaceModelResolver().resolveEffectiveModel( groupId, artifactId, version );
+
                     }
                     catch ( UnresolvableModelException e )
                     {
-                        problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.BASE )
-                            .setMessage( e.getMessage().toString() ).setException( e ) );
+                        problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.BASE ).
+                            setMessage( e.getMessage() ).
+                            setException( e ) );
+
                         continue;
                     }
                 }
 
-                // no workspace resolver or workspace resolver returned null (i.e. model not in workspace)
                 if ( importModel == null )
                 {
-                    final ModelSource importSource;
-                    try
+                    // no workspace resolver or workspace resolver returned null (i.e. model not in workspace)
+                    importModel = this.buildImportModelFromRepository( request, dependency, importIds, problems );
+
+                    if ( importModel == null )
                     {
-                        importSource = modelResolver.resolveModel( groupId, artifactId, version );
+                        continue;
                     }
-                    catch ( UnresolvableModelException e )
+                }
+
+                importMgmt = importModel.getDependencyManagement() == null
+                                 ? new DependencyManagement()
+                                 : importModel.getDependencyManagement();
+
+                // [MNG-5600] Dependency management import should support exclusions.
+                if ( !dependency.getExclusions().isEmpty() )
+                {
+                    for ( final Exclusion exclusion : dependency.getExclusions() )
                     {
-                        StringBuilder buffer = new StringBuilder( 256 );
-                        buffer.append( "Non-resolvable import POM" );
-                        if ( !containsCoordinates( e.getMessage(), groupId, artifactId, version ) )
+                        if ( exclusion.getGroupId() != null && exclusion.getArtifactId() != null )
                         {
-                            buffer.append( ' ' ).append( ModelProblemUtils.toId( groupId, artifactId, version ) );
+                            for ( final Iterator<Dependency> dependencies = importMgmt.getDependencies().iterator();
+                                  dependencies.hasNext(); )
+                            {
+                                final Dependency candidate = dependencies.next();
+
+                                if ( ( exclusion.getGroupId().equals( "*" )
+                                       || exclusion.getGroupId().equals( candidate.getGroupId() ) )
+                                         && ( exclusion.getArtifactId().equals( "*" )
+                                              || exclusion.getArtifactId().equals( candidate.getArtifactId() ) ) )
+                                {
+                                    // Dependency excluded from import.
+                                    dependencies.remove();
+                                }
+                            }
                         }
-                        buffer.append( ": " ).append( e.getMessage() );
-
-                        problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
-                            .setMessage( buffer.toString() ).setLocation( dependency.getLocation( "" ) )
-                            .setException( e ) );
-                        continue;
                     }
 
-                    if ( importRequest == null )
+                    for ( final Dependency includedDependency : importMgmt.getDependencies() )
                     {
-                        importRequest = new DefaultModelBuildingRequest();
-                        importRequest.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
-                        importRequest.setModelCache( request.getModelCache() );
-                        importRequest.setSystemProperties( request.getSystemProperties() );
-                        importRequest.setUserProperties( request.getUserProperties() );
-                        importRequest.setLocationTracking( request.isLocationTracking() );
+                        includedDependency.getExclusions().addAll( dependency.getExclusions() );
                     }
+                }
+                else
+                {
+                    // Only dependency managements without exclusion processing applied can be cached.
+                    putCache( request.getModelCache(), groupId, artifactId, version, ModelCacheTag.IMPORT, importMgmt );
+                }
+            }
 
-                    importRequest.setModelSource( importSource );
-                    importRequest.setModelResolver( modelResolver.newCopy() );
+            if ( importMgmts == null )
+            {
+                importMgmts = new ArrayList<>();
+            }
 
-                    final ModelBuildingResult importResult;
-                    try
-                    {
-                        importResult = build( importRequest );
-                    }
-                    catch ( ModelBuildingException e )
-                    {
-                        problems.addAll( e.getProblems() );
-                        continue;
-                    }
+            importMgmts.add( importMgmt );
+        }
 
-                    problems.addAll( importResult.getProblems() );
+        importIds.remove( importing );
 
-                    importModel = importResult.getEffectiveModel();
-                }
+        dependencyManagementImporter.importManagement( model, importMgmts, request, problems );
+    }
+
+    private Model buildImportModelFromRepository( final ModelBuildingRequest targetModelBuildingRequest,
+                                                  final Dependency dependency, final Collection<String> importIds,
+                                                  final DefaultModelProblemCollector problems )
+    {
+        try
+        {
+            final String imported =
+                String.format( "%s:%s:%s", dependency.getGroupId(), dependency.getArtifactId(),
+                               dependency.getVersion() );
+
+            final Dependency resolvedDependency = dependency.clone();
+            final ModelSource importSource =
+                targetModelBuildingRequest.getModelResolver().resolveModel( resolvedDependency );
 
-                importMgmt = importModel.getDependencyManagement();
+            final String resolvedId =
+                String.format( "%s:%s:%s", resolvedDependency.getGroupId(), resolvedDependency.getArtifactId(),
+                               resolvedDependency.getVersion() );
 
-                if ( importMgmt == null )
+            if ( !imported.equals( resolvedId ) && importIds.contains( resolvedId ) )
+            {
+                // A version range has been resolved to a cycle.
+                String message = "The dependencies of type=pom and scope=" + dependency.getScope() + " form a cycle: ";
+                for ( String modelId : importIds )
+                {
+                    message += modelId + " -> ";
+                }
+                message += resolvedId;
+                problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).setMessage( message ) );
+            }
+            else
+            {
+                final ModelBuildingRequest importRequest = new DefaultModelBuildingRequest();
+                importRequest.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
+                importRequest.setModelCache( targetModelBuildingRequest.getModelCache() );
+                importRequest.setSystemProperties( targetModelBuildingRequest.getSystemProperties() );
+                importRequest.setUserProperties( targetModelBuildingRequest.getUserProperties() );
+                importRequest.setLocationTracking( targetModelBuildingRequest.isLocationTracking() );
+                importRequest.setModelSource( importSource );
+                importRequest.setModelResolver( targetModelBuildingRequest.getModelResolver().newCopy() );
+
+                final ModelBuildingResult importResult = build( importRequest );
+                problems.addAll( importResult.getProblems() );
+
+                Model importModel = importResult.getEffectiveModel();
+
+                if ( importModel.getDistributionManagement() != null
+                         && importModel.getDistributionManagement().getRelocation() != null )
                 {
-                    importMgmt = new DependencyManagement();
+                    final Dependency relocated = dependency.clone();
+                    relocated.setGroupId( importModel.getDistributionManagement().getRelocation().getGroupId() );
+                    relocated.setArtifactId( importModel.getDistributionManagement().getRelocation().getArtifactId() );
+                    relocated.setVersion( importModel.getDistributionManagement().getRelocation().getVersion() );
+
+                    // Message below is checked for in the MNG-5527 core IT.
+                    String message = String.format(
+                        "The dependency of type='%s' and scope='%s' has been relocated to '%s:%s:%s'",
+                        dependency.getType(), dependency.getScope(), relocated.getGroupId(),
+                        relocated.getArtifactId(), relocated.getVersion() );
+
+                    if ( importModel.getDistributionManagement().getRelocation().getMessage() != null )
+                    {
+                        message += ". " + importModel.getDistributionManagement().getRelocation().getMessage();
+                    }
+
+                    problems.add( new ModelProblemCollectorRequest( Severity.WARNING, Version.BASE ).
+                        setMessage( message ).
+                        setLocation( importModel.getDistributionManagement().getRelocation().getLocation( "" ) ) );
+
+                    importModel = this.buildImportModelFromRepository(
+                        targetModelBuildingRequest, relocated, importIds, problems );
+
                 }
 
-                putCache( request.getModelCache(), groupId, artifactId, version, ModelCacheTag.IMPORT, importMgmt );
+                return importModel;
             }
+        }
+        catch ( final UnresolvableModelException e )
+        {
+            final StringBuilder buffer = new StringBuilder( 256 );
+            buffer.append( "Non-resolvable " ).append( dependency.getScope() ).append( " POM" );
 
-            if ( importMgmts == null )
+            if ( !containsCoordinates( e.getMessage(), dependency.getGroupId(), dependency.getArtifactId(),
+                                       dependency.getVersion() ) )
             {
-                importMgmts = new ArrayList<>();
+                buffer.append( ' ' ).append( ModelProblemUtils.toId(
+                    dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() ) );
+
             }
 
-            importMgmts.add( importMgmt );
+            buffer.append( ": " ).append( e.getMessage() );
+
+            problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).
+                setMessage( buffer.toString() ).
+                setLocation( dependency.getLocation( "" ) ).
+                setException( e ) );
+
         }
+        catch ( final ModelBuildingException e )
+        {
+            final StringBuilder buffer = new StringBuilder( 256 );
+            buffer.append( "Failure building " ).append( dependency.getScope() ).append( " POM" );
 
-        importIds.remove( importing );
+            if ( !containsCoordinates( e.getMessage(), dependency.getGroupId(), dependency.getArtifactId(),
+                                       dependency.getVersion() ) )
+            {
+                buffer.append( ' ' ).append( ModelProblemUtils.toId(
+                    dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() ) );
 
-        dependencyManagementImporter.importManagement( model, importMgmts, request, problems );
+            }
+
+            buffer.append( ": " ).append( e.getMessage() );
+
+            problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).
+                setMessage( buffer.toString() ).
+                setLocation( dependency.getLocation( "" ) ).
+                setException( e ) );
+
+            problems.addAll( e.getProblems() );
+        }
+
+        return null;
     }
 
     private <T> void putCache( ModelCache modelCache, String groupId, String artifactId, String version,
@@ -1353,9 +1655,11 @@ private void fireEvent( Model model, ModelBuildingRequest request, ModelProblemC
 
     private boolean containsCoordinates( String message, String groupId, String artifactId, String version )
     {
-        return message != null && ( groupId == null || message.contains( groupId ) )
-            && ( artifactId == null || message.contains( artifactId ) )
-            && ( version == null || message.contains( version ) );
+        return message != null
+                   && ( groupId == null || message.contains( groupId ) )
+                   && ( artifactId == null || message.contains( artifactId ) )
+                   && ( version == null || message.contains( version ) );
+
     }
 
     protected boolean hasModelErrors( ModelProblemCollectorExt problems )
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingResult.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingResult.java
index 7c14063468..9f72fc7037 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingResult.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuildingResult.java
@@ -39,11 +39,13 @@
 
     private Model effectiveModel;
 
-    private List<String> modelIds;
+    private final List<String> modelIds;
 
-    private Map<String, Model> rawModels;
+    private final Map<String, Model> rawModels;
 
-    private Map<String, List<Profile>> activePomProfiles;
+    private final Map<String, Model> effectiveModels;
+
+    private final Map<String, List<Profile>> activePomProfiles;
 
     private List<Profile> activeExternalProfiles;
 
@@ -56,6 +58,7 @@
         activePomProfiles = new HashMap<>();
         activeExternalProfiles = new ArrayList<>();
         problems = new ArrayList<>();
+        effectiveModels = new HashMap<>();
     }
 
     @Override
@@ -109,6 +112,23 @@ public DefaultModelBuildingResult setRawModel( String modelId, Model rawModel )
         return this;
     }
 
+    @Override
+    public Model getEffectiveModel( final String modelId )
+    {
+        return this.effectiveModels.get( modelId );
+    }
+
+    public DefaultModelBuildingResult setEffectiveModel( final String modelId, final Model model )
+    {
+        // Intentionally notNull because Super POM may not contain a modelId
+        Validate.notNull( modelId, "modelId must not be null" );
+        Validate.notNull( model, "model must not be null" );
+
+        this.effectiveModels.put( modelId, model );
+
+        return this;
+    }
+
     @Override
     public List<Profile> getActivePomProfiles( String modelId )
     {
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingException.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingException.java
index 434cb591a2..b5274382be 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingException.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingException.java
@@ -136,7 +136,7 @@ public String getModelId()
         {
             return Collections.emptyList();
         }
-        return result.getProblems();
+        return Collections.unmodifiableList( result.getProblems() );
     }
 
     private static String toMessage( ModelBuildingResult result )
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java
index 44b12958ee..b21a670aa4 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingResult.java
@@ -68,6 +68,18 @@
      */
     Model getRawModel( String modelId );
 
+    /**
+     * Gets the effective model for a given identifier. The model identifier should be from the collection obtained by
+     * {@link #getModelIds()}. As a special case, an empty string can be used as the identifier for the super POM.
+     *
+     * @param modelId The identifier of the desired effective model, must not be {@code null}.
+     *
+     * @return The effective model or {@code null} if the specified model id does not refer to a known model.
+     *
+     * @since 3.6
+     */
+    Model getEffectiveModel( String modelId );
+
     /**
      * Gets the profiles from the specified model that were active during model building. The model identifier should be
      * from the collection obtained by {@link #getModelIds()}. As a special case, an empty string can be used as the
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependencyManagementImporter.java b/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependencyManagementImporter.java
index cce7d7f867..b8caaa790a 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependencyManagementImporter.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/composition/DefaultDependencyManagementImporter.java
@@ -20,15 +20,20 @@
  */
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-
 import org.apache.maven.model.Dependency;
 import org.apache.maven.model.DependencyManagement;
+import org.apache.maven.model.Exclusion;
+import org.apache.maven.model.InputLocation;
+import org.apache.maven.model.InputSource;
 import org.apache.maven.model.Model;
 import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.model.building.ModelProblem;
 import org.apache.maven.model.building.ModelProblemCollector;
+import org.apache.maven.model.building.ModelProblemCollectorRequest;
 import org.codehaus.plexus.component.annotations.Component;
 
 /**
@@ -42,41 +47,215 @@
 {
 
     @Override
-    public void importManagement( Model target, List<? extends DependencyManagement> sources,
-                                  ModelBuildingRequest request, ModelProblemCollector problems )
+    public void importManagement( final Model target, final List<? extends DependencyManagement> sources,
+                                  final ModelBuildingRequest request, final ModelProblemCollector problems )
     {
         if ( sources != null && !sources.isEmpty() )
         {
-            Map<String, Dependency> dependencies = new LinkedHashMap<>();
+            final Map<String, Dependency> targetDependencies = new LinkedHashMap<>();
+            final DependencyManagement targetDependencyManagement = target.getDependencyManagement() != null
+                                                                        ? target.getDependencyManagement()
+                                                                        : new DependencyManagement();
+
+            target.setDependencyManagement( targetDependencyManagement );
+
+            for ( final Dependency targetDependency : targetDependencyManagement.getDependencies() )
+            {
+                targetDependencies.put( targetDependency.getManagementKey(), targetDependency );
+            }
 
-            DependencyManagement depMgmt = target.getDependencyManagement();
+            final Map<String, List<Dependency>> sourceDependencies = new LinkedHashMap<>();
 
-            if ( depMgmt != null )
+            for ( final DependencyManagement source : sources )
             {
-                for ( Dependency dependency : depMgmt.getDependencies() )
+                for ( final Dependency sourceDependency : source.getDependencies() )
                 {
-                    dependencies.put( dependency.getManagementKey(), dependency );
+                    if ( !targetDependencies.containsKey( sourceDependency.getManagementKey() ) )
+                    {
+                        List<Dependency> conflictCanditates =
+                            sourceDependencies.get( sourceDependency.getManagementKey() );
+
+                        if ( conflictCanditates == null )
+                        {
+                            conflictCanditates = new ArrayList<>( source.getDependencies().size() );
+                            sourceDependencies.put( sourceDependency.getManagementKey(), conflictCanditates );
+                        }
+
+                        conflictCanditates.add( sourceDependency );
+                    }
                 }
             }
-            else
+
+            for ( final List<Dependency> conflictCanditates : sourceDependencies.values() )
             {
-                depMgmt = new DependencyManagement();
-                target.setDependencyManagement( depMgmt );
+                final List<Dependency> conflictingDependencies = removeRedundantDependencies( conflictCanditates );
+
+                // First declaration wins. This is what makes the conflict resolution indeterministic because this
+                // solely relies on the order of declaration. There is no such thing as the "first" declaration.
+                targetDependencyManagement.getDependencies().add( conflictingDependencies.get( 0 ) );
+
+                // As of Maven 3.6, we print a warning about such conflicting imports using validation level Maven 3.1.
+                if ( conflictingDependencies.size() > 1 )
+                {
+                    final StringBuilder conflictsBuilder = new StringBuilder( conflictingDependencies.size() * 128 );
+
+                    for ( final Dependency dependency : conflictingDependencies )
+                    {
+                        final InputLocation location = dependency.getLocation( "" );
+
+                        if ( location != null )
+                        {
+                            final InputSource inputSource = location.getSource();
+
+                            if ( inputSource != null )
+                            {
+                                conflictsBuilder.append( ", '" ).append( inputSource.getModelId() ).append( '\'' );
+                            }
+                        }
+                    }
+
+                    problems.add( new ModelProblemCollectorRequest(
+                        effectiveSeverity( request.getValidationLevel(),
+                                           ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_3_1 ),
+                        ModelProblem.Version.V20 ).
+                        setMessage( String.format(
+                            "Dependency '%1$s' has conflicting dependency management in model '%2$s'%3$s%4$s. "
+                                + "To resolve the conflicts, declare the dependency management for dependency '%1$s' "
+                                + "directly in the dependency management of model '%2$s' to override what gets "
+                                + "imported. If the Maven version in use supports it, add exclusions for the "
+                                + "conflicting dependencies or use the include scope feature to rearrange the "
+                                + "causing dependencies in the inheritance hierarchy applying standard override logic "
+                                + "based on artifact coordinates. Without resolving the conflicts, your build relies "
+                                + "on indeterministic behaviour.",
+                            conflictingDependencies.get( 0 ).getManagementKey(), target.getId(),
+                            target.getPomFile() != null
+                                ? " @ '" + target.getPomFile().getAbsolutePath() + "' "
+                                : " ", conflictsBuilder.length() > 0
+                                           ? "(" + conflictsBuilder.substring( 2 ) + ")"
+                                           : "" ) ) );
+
+                }
             }
+        }
+    }
+
+    private static List<Dependency> removeRedundantDependencies( final List<Dependency> candidateDependencies )
+    {
+        final List<Dependency> resultDependencies = new ArrayList<>( candidateDependencies.size() );
 
-            for ( DependencyManagement source : sources )
+        while ( !candidateDependencies.isEmpty() )
+        {
+            final Dependency resultDependency = candidateDependencies.remove( 0 );
+            resultDependencies.add( resultDependency );
+
+            // Removes redundant dependencies.
+            for ( final Iterator<Dependency> it = candidateDependencies.iterator(); it.hasNext(); )
             {
-                for ( Dependency dependency : source.getDependencies() )
+                final Dependency candidateDependency = it.next();
+                boolean redundant = true;
+
+                redundancy_check:
                 {
-                    String key = dependency.getManagementKey();
-                    if ( !dependencies.containsKey( key ) )
+                    if ( !( resultDependency.getOptional() != null
+                            ? resultDependency.getOptional().equals( candidateDependency.getOptional() )
+                            : candidateDependency.getOptional() == null ) )
+                    {
+                        redundant = false;
+                        break redundancy_check;
+                    }
+
+                    if ( !( effectiveScope( resultDependency ).equals( effectiveScope( candidateDependency ) ) ) )
+                    {
+                        redundant = false;
+                        break redundancy_check;
+                    }
+
+                    if ( !( resultDependency.getSystemPath() != null
+                            ? resultDependency.getSystemPath().equals( candidateDependency.getSystemPath() )
+                            : candidateDependency.getSystemPath() == null ) )
                     {
-                        dependencies.put( key, dependency );
+                        redundant = false;
+                        break redundancy_check;
                     }
+
+                    if ( !( resultDependency.getVersion() != null
+                            ? resultDependency.getVersion().equals( candidateDependency.getVersion() )
+                            : candidateDependency.getVersion() == null ) )
+                    {
+                        redundant = false;
+                        break redundancy_check;
+                    }
+
+                    for ( int i = 0, s0 = resultDependency.getExclusions().size(); i < s0; i++ )
+                    {
+                        final Exclusion resultExclusion = resultDependency.getExclusions().get( i );
+
+                        if ( !containsExclusion( candidateDependency.getExclusions(), resultExclusion ) )
+                        {
+                            redundant = false;
+                            break redundancy_check;
+                        }
+                    }
+
+                    for ( int i = 0, s0 = candidateDependency.getExclusions().size(); i < s0; i++ )
+                    {
+                        final Exclusion candidateExclusion = candidateDependency.getExclusions().get( i );
+
+                        if ( !containsExclusion( resultDependency.getExclusions(), candidateExclusion ) )
+                        {
+                            redundant = false;
+                            break redundancy_check;
+                        }
+                    }
+                }
+
+                if ( redundant )
+                {
+                    it.remove();
                 }
             }
+        }
+
+        return resultDependencies;
+    }
+
+    private static boolean containsExclusion( final List<Exclusion> exclusions, final Exclusion exclusion )
+    {
+        for ( int i = 0, s0 = exclusions.size(); i < s0; i++ )
+        {
+            final Exclusion current = exclusions.get( i );
+
+            if ( ( exclusion.getArtifactId() != null
+                   ? exclusion.getArtifactId().equals( current.getArtifactId() )
+                   : current.getArtifactId() == null )
+                     && ( exclusion.getGroupId() != null
+                          ? exclusion.getGroupId().equals( current.getGroupId() )
+                          : current.getGroupId() == null ) )
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
 
-            depMgmt.setDependencies( new ArrayList<>( dependencies.values() ) );
+    private static String effectiveScope( final Dependency dependency )
+    {
+        return dependency.getScope() == null
+                   ? "compile"
+                   : dependency.getScope();
+
+    }
+
+    private static ModelProblem.Severity effectiveSeverity( final int validationLevel, final int errorThreshold )
+    {
+        if ( validationLevel < errorThreshold )
+        {
+            return ModelProblem.Severity.WARNING;
+        }
+        else
+        {
+            return ModelProblem.Severity.ERROR;
         }
     }
 
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultDependencyManagementInjector.java b/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultDependencyManagementInjector.java
index 45474078b2..510c4cc89d 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultDependencyManagementInjector.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/management/DefaultDependencyManagementInjector.java
@@ -85,13 +85,6 @@ public void mergeManagedDependencies( Model model )
             }
         }
 
-        @Override
-        protected void mergeDependency_Optional( Dependency target, Dependency source, boolean sourceDominant,
-                                                 Map<Object, Object> context )
-        {
-            // optional flag is not managed
-        }
-
         @Override
         protected void mergeDependency_Exclusions( Dependency target, Dependency source, boolean sourceDominant,
                                                    Map<Object, Object> context )
diff --git a/maven-model-builder/src/main/resources/org/apache/maven/model/pom-4.0.0.xml b/maven-model-builder/src/main/resources/org/apache/maven/model/pom-4.0.0.xml
index 8c26f71991..aa3a295a01 100644
--- a/maven-model-builder/src/main/resources/org/apache/maven/model/pom-4.0.0.xml
+++ b/maven-model-builder/src/main/resources/org/apache/maven/model/pom-4.0.0.xml
@@ -32,6 +32,9 @@ under the License.
       <snapshots>
         <enabled>false</enabled>
       </snapshots>
+      <releases>
+        <updatePolicy>never</updatePolicy>
+      </releases>
     </repository>
   </repositories>
 
diff --git a/maven-model-builder/src/site/apt/index.apt b/maven-model-builder/src/site/apt/index.apt
index a14b4e3369..9b6c8418bf 100644
--- a/maven-model-builder/src/site/apt/index.apt
+++ b/maven-model-builder/src/site/apt/index.apt
@@ -57,6 +57,12 @@ Maven Model Builder
 
    ** parent resolution until {{{./super-pom.html}super-pom}}
 
+   []
+
+ * phase 2, with optional plugin processing
+
+   ** dependency management include processing (for dependencies of type <<<pom>>> and scope <<<include>>> in the <<<\<dependencyManagement\>>>> section)
+
    ** inheritance assembly (see {{{./index.html#Inheritance_Assembly}below}})
 
    ** model interpolation (see {{{./index.html#Model_Interpolation}below}})
@@ -65,10 +71,6 @@ Maven Model Builder
    with its <<<DefaultUrlNormalizer>>> implementation
    ({{{./xref/org/apache/maven/model/path/DefaultUrlNormalizer.html}source}})
 
-   []
-
- * phase 2, with optional plugin processing
-
    ** model path translation: <<<ModelPathTranslator>>> ({{{./apidocs/org/apache/maven/model/path/ModelPathTranslator.html}javadoc}}),
    with its <<<DefaultModelPathTranslator>>> implementation
    ({{{./xref/org/apache/maven/model/path/DefaultModelPathTranslator.html}source}})
@@ -81,7 +83,7 @@ Maven Model Builder
    with its <<<DefaultLifecycleBindingsInjector>>> implementation
    ({{{./xref/org/apache/maven/model/plugin/DefaultLifecycleBindingsInjector.html}source}})
 
-   ** dependency management import (for dependencies of type <<<pom>>> in the <<<\<dependencyManagement\>>>> section)
+   ** dependency management import processing (for dependencies of type <<<pom>>> and scope <<<import>>> in the <<<\<dependencyManagement\>>>> section)
 
    ** dependency management injection: <<<DependencyManagementInjector>>> ({{{./apidocs/org/apache/maven/model/management/DependencyManagementInjector.html}javadoc}}),
    with its <<<DefaultDependencyManagementInjector>>> implementation
diff --git a/maven-model/pom.xml b/maven-model/pom.xml
index 952fab152c..826c95f9c5 100644
--- a/maven-model/pom.xml
+++ b/maven-model/pom.xml
@@ -25,7 +25,7 @@ under the License.
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.5.4-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-model</artifactId>
diff --git a/maven-plugin-api/pom.xml b/maven-plugin-api/pom.xml
index fcec291fc0..49346b6da6 100644
--- a/maven-plugin-api/pom.xml
+++ b/maven-plugin-api/pom.xml
@@ -25,7 +25,7 @@ under the License.
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.5.4-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-plugin-api</artifactId>
diff --git a/maven-repository-metadata/pom.xml b/maven-repository-metadata/pom.xml
index b58c631e21..1bef9ef722 100644
--- a/maven-repository-metadata/pom.xml
+++ b/maven-repository-metadata/pom.xml
@@ -25,7 +25,7 @@ under the License.
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.5.4-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-repository-metadata</artifactId>
diff --git a/maven-resolver-provider/pom.xml b/maven-resolver-provider/pom.xml
index 20dda36eef..29e7c3873f 100644
--- a/maven-resolver-provider/pom.xml
+++ b/maven-resolver-provider/pom.xml
@@ -25,7 +25,7 @@ under the License.
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.5.4-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-resolver-provider</artifactId>
diff --git a/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/ArtifactDescriptorReaderDelegate.java b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/ArtifactDescriptorReaderDelegate.java
index 82192058c8..b94147b64c 100644
--- a/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/ArtifactDescriptorReaderDelegate.java
+++ b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/ArtifactDescriptorReaderDelegate.java
@@ -19,6 +19,7 @@
  * under the License.
  */
 
+import java.io.File;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -45,12 +46,13 @@
 
 /**
  * Populates Aether {@link ArtifactDescriptorResult} from Maven project {@link Model}.
- * 
+ *
  * <strong>Note:</strong> This class is part of work in progress and can be changed or removed without notice.
  * @since 3.2.4
  */
 public class ArtifactDescriptorReaderDelegate
 {
+
     public void populateResult( RepositorySystemSession session, ArtifactDescriptorResult result, Model model )
     {
         ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry();
@@ -62,7 +64,7 @@ public void populateResult( RepositorySystemSession session, ArtifactDescriptorR
 
         for ( org.apache.maven.model.Dependency dependency : model.getDependencies() )
         {
-            result.addDependency( convert( dependency, stereotypes ) );
+            result.addDependency( convert( dependency, stereotypes ).setSourceHint( toSourceHint( model ) ) );
         }
 
         DependencyManagement mgmt = model.getDependencyManagement();
@@ -70,7 +72,9 @@ public void populateResult( RepositorySystemSession session, ArtifactDescriptorR
         {
             for ( org.apache.maven.model.Dependency dependency : mgmt.getDependencies() )
             {
-                result.addManagedDependency( convert( dependency, stereotypes ) );
+                result.addManagedDependency( convert( dependency, stereotypes ).
+                    setSourceHint( toSourceHint( model ) ) );
+
             }
         }
 
@@ -154,4 +158,66 @@ private void setArtifactProperties( ArtifactDescriptorResult result, Model model
             result.setArtifact( artifact.setProperties( props ) );
         }
     }
+
+    private static String toSourceHint( final Model model )
+    {
+        String sourceHint = null;
+
+        if ( model != null )
+        {
+            final StringBuilder sourceHintBuilder = new StringBuilder( 128 );
+
+            sourceHintBuilder.append( toId( model ) );
+
+            File pomFile = model.getPomFile();
+            if ( pomFile != null )
+            {
+                sourceHintBuilder.append( " @ " ).append( pomFile );
+            }
+
+            sourceHint = sourceHintBuilder.toString();
+        }
+
+        return sourceHint;
+    }
+
+    private static String toId( final Model model )
+    {
+        String id = null;
+
+        if ( model != null )
+        {
+            String groupId = model.getGroupId();
+            if ( groupId == null && model.getParent() != null )
+            {
+                groupId = model.getParent().getGroupId();
+            }
+
+            String artifactId = model.getArtifactId();
+
+            String version = model.getVersion();
+            if ( version == null && model.getParent() != null )
+            {
+                version = model.getParent().getVersion();
+            }
+
+            id = toId( groupId, artifactId, version );
+        }
+
+        return id;
+    }
+
+    private static String toId( final String groupId, final String artifactId, final String version )
+    {
+        final StringBuilder idBuilder = new StringBuilder( 128 );
+
+        idBuilder.append( ( groupId != null && groupId.length() > 0 ) ? groupId : "[unknown-group-id]" );
+        idBuilder.append( ':' );
+        idBuilder.append( ( artifactId != null && artifactId.length() > 0 ) ? artifactId : "[unknown-artifact-id]" );
+        idBuilder.append( ':' );
+        idBuilder.append( ( version != null && version.length() > 0 ) ? version : "[unknown-version]" );
+
+        return idBuilder.toString();
+    }
+
 }
diff --git a/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java
index 6818453469..2411b4e617 100644
--- a/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java
+++ b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java
@@ -70,6 +70,8 @@
 
     private final List<RemoteRepository> externalRepositories;
 
+    private final Set<String> externalRepositoryIds;
+
     private final ArtifactResolver resolver;
 
     private final VersionRangeResolver versionRangeResolver;
@@ -92,8 +94,13 @@
         List<RemoteRepository> externalRepositories = new ArrayList<>();
         externalRepositories.addAll( repositories );
         this.externalRepositories = Collections.unmodifiableList( externalRepositories );
-
         this.repositoryIds = new HashSet<>();
+        this.externalRepositoryIds = new HashSet<>();
+        for ( final RemoteRepository repository : this.repositories )
+        {
+            this.repositoryIds.add( repository.getId() );
+            this.externalRepositoryIds.add( repository.getId() );
+        }
     }
 
     private DefaultModelResolver( DefaultModelResolver original )
@@ -107,6 +114,7 @@ private DefaultModelResolver( DefaultModelResolver original )
         this.repositories = new ArrayList<>( original.repositories );
         this.externalRepositories = original.externalRepositories;
         this.repositoryIds = new HashSet<>( original.repositoryIds );
+        this.externalRepositoryIds = new HashSet<>( original.externalRepositoryIds );
     }
 
     @Override
@@ -127,7 +135,7 @@ public void addRepository( final Repository repository, boolean replace )
 
         if ( !repositoryIds.add( repository.getId() ) )
         {
-            if ( !replace )
+            if ( !replace || this.externalRepositoryIds.contains( repository.getId() ) )
             {
                 return;
             }
diff --git a/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/MavenRepositorySystemUtils.java b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/MavenRepositorySystemUtils.java
index 1b11cb34aa..2e48c43072 100644
--- a/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/MavenRepositorySystemUtils.java
+++ b/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/MavenRepositorySystemUtils.java
@@ -33,7 +33,7 @@
 import org.eclipse.aether.impl.VersionRangeResolver;
 import org.eclipse.aether.impl.VersionResolver;
 import org.eclipse.aether.util.artifact.DefaultArtifactTypeRegistry;
-import org.eclipse.aether.util.graph.manager.ClassicDependencyManager;
+import org.eclipse.aether.util.graph.manager.DefaultDependencyManager;
 import org.eclipse.aether.util.graph.selector.AndDependencySelector;
 import org.eclipse.aether.util.graph.selector.ExclusionDependencySelector;
 import org.eclipse.aether.util.graph.selector.OptionalDependencySelector;
@@ -95,7 +95,7 @@ public static DefaultRepositorySystemSession newSession()
         DependencyTraverser depTraverser = new FatArtifactTraverser();
         session.setDependencyTraverser( depTraverser );
 
-        DependencyManager depManager = new ClassicDependencyManager();
+        DependencyManager depManager = new DefaultDependencyManager();
         session.setDependencyManager( depManager );
 
         DependencySelector depFilter =
diff --git a/maven-settings-builder/pom.xml b/maven-settings-builder/pom.xml
index b18bcd948b..886031cbbc 100644
--- a/maven-settings-builder/pom.xml
+++ b/maven-settings-builder/pom.xml
@@ -25,7 +25,7 @@ under the License.
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.5.4-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-settings-builder</artifactId>
diff --git a/maven-settings-builder/src/main/java/org/apache/maven/settings/merge/MavenSettingsMerger.java b/maven-settings-builder/src/main/java/org/apache/maven/settings/merge/MavenSettingsMerger.java
index 8d9f67b1fc..cb5f6c166f 100644
--- a/maven-settings-builder/src/main/java/org/apache/maven/settings/merge/MavenSettingsMerger.java
+++ b/maven-settings-builder/src/main/java/org/apache/maven/settings/merge/MavenSettingsMerger.java
@@ -111,6 +111,7 @@ public void merge( Settings dominant, Settings recessive, String recessiveSource
                                                                        String recessiveSourceLevel )
     {
         Map<String, T> dominantById = mapById( dominant );
+        final List<T> identifiables = new ArrayList<>( recessive.size() );
 
         for ( T identifiable : recessive )
         {
@@ -118,9 +119,11 @@ public void merge( Settings dominant, Settings recessive, String recessiveSource
             {
                 identifiable.setSourceLevel( recessiveSourceLevel );
 
-                dominant.add( identifiable );
+                identifiables.add( identifiable );
             }
         }
+
+        dominant.addAll( 0, identifiables );
     }
 
     /**
diff --git a/maven-settings/pom.xml b/maven-settings/pom.xml
index c909107bea..39b17914f4 100644
--- a/maven-settings/pom.xml
+++ b/maven-settings/pom.xml
@@ -25,7 +25,7 @@ under the License.
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.5.4-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-settings</artifactId>
diff --git a/maven-slf4j-provider/pom.xml b/maven-slf4j-provider/pom.xml
index ee166a2810..3645ffcb04 100644
--- a/maven-slf4j-provider/pom.xml
+++ b/maven-slf4j-provider/pom.xml
@@ -25,7 +25,7 @@ under the License.
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.5.4-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-slf4j-provider</artifactId>
@@ -97,4 +97,4 @@ under the License.
       </plugin>
     </plugins>
   </build>
-</project>
\ No newline at end of file
+</project>
diff --git a/pom.xml b/pom.xml
index 10a17d29f1..c4b134afb5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,7 +30,7 @@ under the License.
   </parent>
 
   <artifactId>maven</artifactId>
-  <version>3.5.4-SNAPSHOT</version>
+  <version>3.4.0-SNAPSHOT</version>
   <packaging>pom</packaging>
 
   <name>Apache Maven</name>
@@ -65,7 +65,7 @@ under the License.
     <cipherVersion>1.7</cipherVersion>
     <modelloVersion>1.9.1</modelloVersion>
     <jxpathVersion>1.3</jxpathVersion>
-    <resolverVersion>1.1.1</resolverVersion>
+    <resolverVersion>1.2.0-SNAPSHOT</resolverVersion>
     <slf4jVersion>1.7.25</slf4jVersion>
     <maven.test.redirectTestOutputToFile>true</maven.test.redirectTestOutputToFile>
     <!-- Control the name of the distribution and information output by mvn -->


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services