maven-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "ASF GitHub Bot (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (MNG-4777) Match property for profile activation against a regex
Date Tue, 27 Nov 2018 19:30:03 GMT

    [ https://issues.apache.org/jira/browse/MNG-4777?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16700902#comment-16700902 ] 

ASF GitHub Bot commented on MNG-4777:
-------------------------------------

rfscholte closed pull request #80: [MNG-4777] Match property for profile activation against a regex
URL: https://github.com/apache/maven/pull/80
 
 
   

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/README.md b/README.md
index a263dca4d6..5f25a998f7 100644
--- a/README.md
+++ b/README.md
@@ -12,12 +12,12 @@ Maven is available under the [Apache License, Version 2.0](http://www.apache.org
 If you want to bootstrap Maven, you'll need:
 
 - Java 1.7+
-- Ant 1.8 or later
+- Maven 3.0.5 or later
 
-Run Ant, specifying a location into which the completed Maven distro should be installed:
+Run Maven, specifying a location into which the completed Maven distro should be installed:
 
 ```
-ant -Dmaven.home="$HOME/apps/maven/apache-maven-3.3.x-SNAPSHOT"
+mvn -DdistributionTargetFolder="$HOME/app/maven/apache-maven-3.4.x-SNAPSHOT" clean package
 ```
 
 Once the build completes, you should have a new Maven distro ready to roll in that directory!
diff --git a/apache-maven/README.txt b/apache-maven/README.txt
index b05080d658..5d3a30a873 100644
--- a/apache-maven/README.txt
+++ b/apache-maven/README.txt
@@ -16,7 +16,7 @@
   Release Notes
   -------------
 
-  The full list of changes can be found at http://maven.apache.org/release-notes.html.
+  The full list of changes can be found at http://maven.apache.org/docs/history.html.
 
   System Requirements
   -------------------
@@ -39,7 +39,7 @@
   Installing Maven
   ----------------
 
-  1) Unpack the archive where you would like to store the binaries, eg:
+  1) Unpack the archive where you would like to store the binaries, e.g.:
 
     Unix-based operating systems (Linux, Solaris and Mac OS X)
       tar zxvf apache-maven-3.x.y.tar.gz
@@ -48,7 +48,7 @@
 
   2) A directory called "apache-maven-3.x.y" will be created.
 
-  3) Add the bin directory to your PATH, eg:
+  3) Add the bin directory to your PATH, e.g.:
 
     Unix-based operating systems (Linux, Solaris and Mac OS X)
       export PATH=/usr/local/apache-maven-3.x.y/bin:$PATH
@@ -69,11 +69,11 @@
   Maven URLS
   ----------
 
-  Home Page:          http://maven.apache.org/
-  Downloads:          http://maven.apache.org/download.html
-  Release Notes:      http://maven.apache.org/release-notes.html
-  Mailing Lists:      http://maven.apache.org/mail-lists.html
-  Source Code:        https://git-wip-us.apache.org/repos/asf/maven.git/apache-maven
-  Issue Tracking:     http://jira.codehaus.org/browse/MNG
+  Home Page:          https://maven.apache.org/
+  Downloads:          https://maven.apache.org/download.html
+  Release Notes:      https://maven.apache.org/docs/history.html
+  Mailing Lists:      https://maven.apache.org/mail-lists.html
+  Source Code:        https://git-wip-us.apache.org/repos/asf/maven.git
+  Issue Tracking:     https://issues.apache.org/jira/browse/MNG
   Wiki:               https://cwiki.apache.org/confluence/display/MAVEN/
-  Available Plugins:  http://maven.apache.org/plugins/index.html
+  Available Plugins:  https://maven.apache.org/plugins/index.html
diff --git a/apache-maven/pom.xml b/apache-maven/pom.xml
index ce3a5ccbf7..2d00468f9d 100644
--- a/apache-maven/pom.xml
+++ b/apache-maven/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.3.10-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>apache-maven</artifactId>
@@ -151,7 +151,7 @@
         <artifactId>maven-assembly-plugin</artifactId>
         <executions>
           <execution>
-            <id>create-distro</id>
+            <id>create-distro-packages</id>
             <phase>package</phase>
             <goals>
               <goal>single</goal>
@@ -181,6 +181,59 @@
   </pluginRepositories>
 
   <profiles>
+    <profile>
+      <id>create-distribution-in-folder</id>
+      <activation>
+        <property>
+          <name>distributionTargetFolder</name>
+        </property>
+      </activation>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-clean-plugin</artifactId>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>clean</goal>
+                </goals>
+                <id>clean-target-folder</id>
+                <phase>prepare-package</phase>
+                <configuration>
+                  <filesets>
+                    <fileset>
+                      <directory>${distributionTargetFolder}</directory>
+                    </fileset>
+                  </filesets>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+          <plugin>
+            <artifactId>maven-assembly-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>create-distribution-folder</id>
+                <phase>package</phase>
+                <goals>
+                  <goal>single</goal>
+                </goals>
+                <configuration>
+                  <finalName>./</finalName>
+                  <appendAssemblyId>false</appendAssemblyId>
+                  <attach>false</attach>
+                  <outputDirectory>${distributionTargetFolder}</outputDirectory>
+                  <descriptors>
+                    <descriptor>src/main/assembly/dir.xml</descriptor>
+                  </descriptors>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
     <profile>
       <id>apache-release</id>
       <build>
diff --git a/apache-maven/src/bin/m2.conf b/apache-maven/src/bin/m2.conf
index 2991e0b350..213dc55d1d 100644
--- a/apache-maven/src/bin/m2.conf
+++ b/apache-maven/src/bin/m2.conf
@@ -3,6 +3,6 @@ main is org.apache.maven.cli.MavenCli from plexus.core
 set maven.home default ${user.home}/m2
 
 [plexus.core]
+load       ${maven.home}/conf/logging
 optionally ${maven.home}/lib/ext/*.jar
 load       ${maven.home}/lib/*.jar
-load       ${maven.home}/conf/logging
diff --git a/apache-maven/src/bin/mvn b/apache-maven/src/bin/mvn
index 6875628599..c815839c02 100755
--- a/apache-maven/src/bin/mvn
+++ b/apache-maven/src/bin/mvn
@@ -183,6 +183,7 @@ if [ -z "$JAVA_HOME" ] ; then
 fi
 
 CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
+CLASSWORLDS_JAR=`echo "${M2_HOME}"/boot/plexus-classworlds-*.jar`
 
 # For Cygwin, switch paths to Windows format before running java
 if $cygwin; then
@@ -192,34 +193,36 @@ if $cygwin; then
     JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
   [ -n "$CLASSPATH" ] &&
     CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
+  [ -n "$CLASSWORLDS_JAR" ] &&
+    CLASSWORLDS_JAR=`cygpath --path --windows "$CLASSWORLDS_JAR"`
 fi
 
 # traverses directory structure from process work directory to filesystem root
 # first directory with .mvn subdirectory is considered project base directory
 find_maven_basedir() {
-  local basedir
-  local wdir
-  basedir="$(pwd)"
-  wdir="$(pwd)"
+(
+  basedir="`pwd`"
+  wdir="`pwd`"
   while [ "$wdir" != '/' ] ; do
     if [ -d "$wdir"/.mvn ] ; then
       basedir=$wdir
       break
     fi
-    wdir="$(cd "$wdir/.."; pwd)"
+    wdir="`cd "$wdir/.."; pwd`"
   done
   echo "${basedir}"
+)
 }
 
 # concatenates all lines of a file
 concat_lines() {
   if [ -f "$1" ]; then
-    echo "$(tr -s '\n' ' ' < "$1")"
+    echo "`tr -s '\n' ' ' < "$1"`"
   fi
 }
 
-MAVEN_PROJECTBASEDIR="${MAVEN_BASEDIR:-$(find_maven_basedir)}"
-MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
+MAVEN_PROJECTBASEDIR="${MAVEN_BASEDIR:-`find_maven_basedir`}"
+MAVEN_OPTS="`concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config"` $MAVEN_OPTS"
 
 # For Cygwin, switch project base directory path to Windows format before
 # executing Maven. Otherwise this will cause Maven not to consider it.
@@ -238,7 +241,7 @@ export MAVEN_CMD_LINE_ARGS
 exec "$JAVACMD" \
   $MAVEN_OPTS \
   $MAVEN_DEBUG_OPTS \
-  -classpath "${M2_HOME}"/boot/plexus-classworlds-*.jar \
+  -classpath "${CLASSWORLDS_JAR}" \
   "-Dclassworlds.conf=${M2_HOME}/bin/m2.conf" \
   "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
   ${CLASSWORLDS_LAUNCHER} "$@"
diff --git a/apache-maven/src/bin/mvn.cmd b/apache-maven/src/bin/mvn.cmd
index d35c1d2047..12993d9c4d 100644
--- a/apache-maven/src/bin/mvn.cmd
+++ b/apache-maven/src/bin/mvn.cmd
@@ -52,9 +52,6 @@ if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
 
 set ERROR_CODE=0
 
-@REM To isolate internal variables from possible post scripts, we use another setlocal
-@setlocal
-
 @REM ==== START VALIDATION ====
 if not "%JAVA_HOME%" == "" goto OkJHome
 
@@ -118,29 +115,30 @@ set MAVEN_CMD_LINE_ARGS=%*
 set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
 IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
 
-set EXEC_DIR=%CD%
-set WDIR=%EXEC_DIR%
+set "EXEC_DIR=%CD%"
+set "WDIR=%EXEC_DIR%"
+
 :findBaseDir
 IF EXIST "%WDIR%\.mvn" goto baseDirFound
 cd ..
 IF "%WDIR%"=="%CD%" goto baseDirNotFound
-set WDIR=%CD%
+set "WDIR=%CD%"
 goto findBaseDir
 
 :baseDirFound
-set MAVEN_PROJECTBASEDIR=%WDIR%
+set "MAVEN_PROJECTBASEDIR=%WDIR%"
 cd "%EXEC_DIR%"
 goto endDetectBaseDir
 
 :baseDirNotFound
 if "_%EXEC_DIR:~-1%"=="_\" set EXEC_DIR=%EXEC_DIR:~0,-1%
-
-set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+set "MAVEN_PROJECTBASEDIR=%EXEC_DIR%"
 cd "%EXEC_DIR%"
 
 :endDetectBaseDir
 
-IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+set "jvmConfig=\.mvn\jvm.config"
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%%jvmConfig%"  goto endReadAdditionalConfig
 
 @setlocal EnableExtensions EnableDelayedExpansion
 for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
diff --git a/apache-maven/src/bin/mvnDebug b/apache-maven/src/bin/mvnDebug
index a1077ce5da..caf0b45257 100755
--- a/apache-maven/src/bin/mvnDebug
+++ b/apache-maven/src/bin/mvnDebug
@@ -38,4 +38,4 @@ MAVEN_DEBUG_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,addre
 
 echo Preparing to Execute Maven in Debug Mode
 
-env MAVEN_OPTS="$MAVEN_OPTS" MAVEN_DEBUG_OPTS="$MAVEN_DEBUG_OPTS" $(dirname $0)/mvn "$@"
+env MAVEN_OPTS="$MAVEN_OPTS" MAVEN_DEBUG_OPTS="$MAVEN_DEBUG_OPTS" "`dirname "$0"`/mvn" "$@"
diff --git a/apache-maven/src/bin/mvnyjp b/apache-maven/src/bin/mvnyjp
index ef4f8e1d01..3ddec42e9f 100755
--- a/apache-maven/src/bin/mvnyjp
+++ b/apache-maven/src/bin/mvnyjp
@@ -39,4 +39,4 @@ if [ ! -f "$YJPLIB" ]; then
   exit 1
 fi
 
-env MAVEN_OPTS="-agentpath:$YJPLIB=onexit=snapshot,onexit=memory,tracing,onlylocal $MAVEN_OPTS" $(dirname $0)/mvn "$@"
+env MAVEN_OPTS="-agentpath:$YJPLIB=onexit=snapshot,onexit=memory,tracing,onlylocal $MAVEN_OPTS" "`dirname "$0"`/mvn" "$@"
diff --git a/apache-maven/src/main/appended-resources/META-INF/LICENSE.vm b/apache-maven/src/main/appended-resources/META-INF/LICENSE.vm
index 1a46225254..390fa42530 100644
--- a/apache-maven/src/main/appended-resources/META-INF/LICENSE.vm
+++ b/apache-maven/src/main/appended-resources/META-INF/LICENSE.vm
@@ -16,8 +16,6 @@
 ## specific language governing permissions and limitations
 ## under the License.
 ##
-## $Date: 2008-03-09 23:17:06 -0700 (Sun, 09 Mar 2008) $ $Rev: 635446 $
-##
 
 Apache Maven includes a number of components and libraries with separate 
 copyright notices and license terms. Your use of those components are 
diff --git a/apache-maven/src/main/assembly/bin.xml b/apache-maven/src/main/assembly/bin.xml
index ea14a9d8dc..79723c2a78 100644
--- a/apache-maven/src/main/assembly/bin.xml
+++ b/apache-maven/src/main/assembly/bin.xml
@@ -17,78 +17,14 @@ specific language governing permissions and limitations
 under the License.
 -->
 
-<assembly>
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
   <id>bin</id>
   <formats>
     <format>zip</format>
     <format>tar.gz</format>
   </formats>
-  <dependencySets>
-    <dependencySet>
-      <useProjectArtifact>false</useProjectArtifact>
-      <outputDirectory>boot</outputDirectory>
-      <includes>
-        <include>org.codehaus.plexus:plexus-classworlds</include>
-      </includes>
-    </dependencySet>
-    <dependencySet>
-      <useProjectArtifact>false</useProjectArtifact>
-      <outputDirectory>lib</outputDirectory>
-      <excludes>
-        <exclude>org.codehaus.plexus:plexus-classworlds</exclude>
-      </excludes>
-    </dependencySet>
-  </dependencySets>
-  <fileSets>
-    <fileSet>
-      <includes>
-        <include>README*</include>
-      </includes>
-    </fileSet>
-    <fileSet>
-      <directory>target/maven-shared-archive-resources/META-INF</directory>
-      <outputDirectory>/</outputDirectory>
-      <includes>
-        <include>LICENSE</include>
-        <include>NOTICE</include>
-      </includes>
-    </fileSet>
-    <fileSet>
-      <directory>target/licenses/lib</directory>
-      <outputDirectory>lib</outputDirectory>
-      <includes>
-        <include>**</include>
-      </includes>
-    </fileSet>
-    <fileSet>
-      <directory>src/bin</directory>
-      <outputDirectory>bin</outputDirectory>
-      <includes>
-        <include>*.cmd</include>
-        <include>*.conf</include>
-      </includes>
-      <lineEnding>dos</lineEnding>
-    </fileSet>
-    <fileSet>
-      <directory>src/bin</directory>
-      <outputDirectory>bin</outputDirectory>
-      <includes>
-        <include>m2</include>
-        <include>mvn</include>
-        <include>mvnDebug</include>
-        <!-- This is so that CI systems can periodically run the profiler -->
-        <include>mvnyjp</include>
-      </includes>
-      <lineEnding>unix</lineEnding>
-      <fileMode>0755</fileMode>
-    </fileSet>
-    <fileSet>
-      <directory>src/conf</directory>
-      <outputDirectory>conf</outputDirectory>
-    </fileSet>
-    <fileSet>
-      <directory>src/lib</directory>
-      <outputDirectory>lib</outputDirectory>
-    </fileSet>
-  </fileSets>
+  <componentDescriptors>
+    <componentDescriptor>src/main/assembly/component.xml</componentDescriptor>
+  </componentDescriptors>
 </assembly>
diff --git a/apache-maven/src/main/assembly/component.xml b/apache-maven/src/main/assembly/component.xml
new file mode 100644
index 0000000000..36b2232428
--- /dev/null
+++ b/apache-maven/src/main/assembly/component.xml
@@ -0,0 +1,89 @@
+<!--
+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.
+-->
+<component xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/component/1.1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/component/1.1.3 http://maven.apache.org/xsd/component-1.1.3.xsd">
+  <dependencySets>
+    <dependencySet>
+      <useProjectArtifact>false</useProjectArtifact>
+      <outputDirectory>boot</outputDirectory>
+      <includes>
+        <include>org.codehaus.plexus:plexus-classworlds</include>
+      </includes>
+    </dependencySet>
+    <dependencySet>
+      <useProjectArtifact>false</useProjectArtifact>
+      <outputDirectory>lib</outputDirectory>
+      <excludes>
+        <exclude>org.codehaus.plexus:plexus-classworlds</exclude>
+      </excludes>
+    </dependencySet>
+  </dependencySets>
+  <fileSets>
+    <fileSet>
+      <includes>
+        <include>README*</include>
+      </includes>
+    </fileSet>
+    <fileSet>
+      <directory>target/maven-shared-archive-resources/META-INF</directory>
+      <outputDirectory>/</outputDirectory>
+      <includes>
+        <include>LICENSE</include>
+        <include>NOTICE</include>
+      </includes>
+    </fileSet>
+    <fileSet>
+      <directory>target/licenses/lib</directory>
+      <outputDirectory>lib</outputDirectory>
+      <includes>
+        <include>**</include>
+      </includes>
+    </fileSet>
+    <fileSet>
+      <directory>src/bin</directory>
+      <outputDirectory>bin</outputDirectory>
+      <includes>
+        <include>*.cmd</include>
+        <include>*.conf</include>
+      </includes>
+      <lineEnding>dos</lineEnding>
+    </fileSet>
+    <fileSet>
+      <directory>src/bin</directory>
+      <outputDirectory>bin</outputDirectory>
+      <includes>
+        <include>m2</include>
+        <include>mvn</include>
+        <include>mvnDebug</include>
+        <!-- This is so that CI systems can periodically run the profiler -->
+        <include>mvnyjp</include>
+      </includes>
+      <lineEnding>unix</lineEnding>
+      <fileMode>0755</fileMode>
+    </fileSet>
+    <fileSet>
+      <directory>src/conf</directory>
+      <outputDirectory>conf</outputDirectory>
+    </fileSet>
+    <fileSet>
+      <directory>src/lib</directory>
+      <outputDirectory>lib</outputDirectory>
+    </fileSet>
+  </fileSets>
+</component>
diff --git a/apache-maven/src/main/assembly/dir.xml b/apache-maven/src/main/assembly/dir.xml
new file mode 100644
index 0000000000..885a63e106
--- /dev/null
+++ b/apache-maven/src/main/assembly/dir.xml
@@ -0,0 +1,29 @@
+<!--
+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.
+-->
+
+<assembly>
+  <id>dir</id>
+  <formats>
+    <format>dir</format>
+  </formats>
+  <includeBaseDirectory>false</includeBaseDirectory>
+  <componentDescriptors>
+    <componentDescriptor>src/main/assembly/component.xml</componentDescriptor>
+  </componentDescriptors>
+</assembly>
diff --git a/apache-maven/src/main/assembly/src.xml b/apache-maven/src/main/assembly/src.xml
index 3bf10e052c..fb0aee8153 100644
--- a/apache-maven/src/main/assembly/src.xml
+++ b/apache-maven/src/main/assembly/src.xml
@@ -17,7 +17,8 @@ specific language governing permissions and limitations
 under the License.
 -->
 
-<assembly>
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
   <id>src</id>
   <formats>
     <format>zip</format>
diff --git a/build.xml b/build.xml
deleted file mode 100644
index ccfca3bf8d..0000000000
--- a/build.xml
+++ /dev/null
@@ -1,307 +0,0 @@
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-
-<!-- START SNIPPET: ant-bootstrap
-
-By default the bootstrap will use ~/.m2/repository as the integration repository but you can define the integration
-repository by specifying a property on the command line:
-
-ant -Dmaven.repo.local=/my/integration/repository
-
-Those familiar with Maven will note this is the same way the local repository can be set from the command-line.
-This facilitates having a set of builds converge on the same repository for integration purposes.
-
-END SNIPPET: ant-bootstrap -->
-
-<project default="all" basedir="." xmlns:artifact="urn:maven-artifact-ant">
-
-  <property name="distributionDirectory" value="apache-maven"/>
-  <property name="distributionId" value="apache-maven"/>
-  <property name="distributionShortName" value="Maven"/>
-  <property name="distributionName" value="Apache Maven"/>
-  <property name="it.workdir.version" value="3.0.x" />
-  <property name="maven-compile.jvmargs" value="-Xmx512m -Xms512m"/>
-  <property name="maven-compile.fork" value="true"/>
-  <property name="maven-compile.maxmemory" value="512m"/>
-
-  <target name="initTaskDefs">
-    <echo>Building ${distributionName} ...</echo>
-    <xmlproperty file="pom.xml" prefix="xmlPom" />
-    <path id="maven-ant-tasks.classpath" path="maven-ant-tasks-2.1.1.jar" />
-    <typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" />
-  </target>
-
-  <target name="isMavenHomeSet" depends="initTaskDefs">
-    <property environment="env" />
-    <condition property="maven.home" value="${env.M2_HOME}">
-      <isset property="env.M2_HOME" />
-    </condition>
-    <fail message="You must set the M2_HOME environment variable or specify a maven.home property to this Ant script">
-      <condition>
-        <or>
-          <not>
-            <isset property="maven.home" />
-          </not>
-          <equals arg1="${maven.home}" arg2="" trim="true" />
-        </or>
-      </condition>
-    </fail>
-    <available property="maven.home.exists" file="${maven.home}" />
-  </target>
-
-  <target name="prompt-maven-home-exists" depends="isMavenHomeSet" if="maven.home.exists">
-    <input addproperty="maven.home.exists.continue" validargs="yes,no" defaultvalue="no">WARNING:
-The specified target directory
-  ${maven.home}
-already exists. It will be deleted and overwritten by the build.
-Do you want to continue?</input>
-    <fail message="Build was aborted by user">
-      <condition>
-        <equals arg1="${maven.home.exists.continue}" arg2="no" trim="true" casesensitive="false" />
-      </condition>
-    </fail>
-  </target>
-
-  <target name="init" depends="isMavenHomeSet">
-    <!-- Initialize properties -->
-    <property name="maven.home.basename.expected" value="${distributionId}-${xmlPom.project.version}" />
-    <property name="maven.assembly" location="${distributionDirectory}/target/${maven.home.basename.expected}-bin.zip" />
-    <property name="maven.repo.local" value="${user.home}/.m2/repository" />
-    <property name="maven.debug" value="-e" />
-    <property name="maven.test.skip" value="false" />
-    <property name="skipTests" value="false" />
-    <property name="surefire.useFile" value="true" />
-    <property name="maven.test.redirectTestOutputToFile" value="${surefire.useFile}" />
-    <property name="maven.goal" value="install" />
-    <echo>maven.home = ${maven.home}</echo>
-    <echo>maven.repo.local = ${maven.repo.local}</echo>
-    <echo>distributionId = ${distributionId}</echo>
-    <echo>distributionName = ${distributionName}</echo>
-    <echo>distributionDirectory = ${distributionDirectory}</echo>
-  </target>
-
-  <target name="clean-bootstrap" description="cleans up generated bootstrap classes">
-    <delete dir="bootstrap" />
-  </target>
-
-  <target name="pull" depends="init" unless="skip.pull">
-    <!-- Pull the dependencies that Maven needs to build -->
-    <copy file="pom.xml" tofile="dependencies.xml" />
-    <replace file="${basedir}/dependencies.xml" token="&lt;!--bootstrap-start-comment--&gt;" value="&lt;!--" />
-    <replace file="${basedir}/dependencies.xml" token="&lt;!--bootstrap-end-comment--&gt;" value="--&gt;" />
-    <artifact:pom file="${basedir}/dependencies.xml" id="pom">
-      <localRepository path="${maven.repo.local}" />
-    </artifact:pom>
-    <artifact:dependencies pathId="pom.pathid" filesetId="pom.fileset" useScope="compile">
-      <localRepository path="${maven.repo.local}" />
-      <pom refid="pom" />
-    </artifact:dependencies>
-    <delete file="${basedir}/dependencies.xml" />
-
-    <!-- Pull the dependencies for Modello -->
-    <artifact:dependencies pathId="modello.pathid" filesetId="modello.fileset">
-      <localRepository path="${maven.repo.local}" />
-      <dependency groupId="org.codehaus.modello" artifactId="modello-maven-plugin" version="${pom.properties.modelloVersion}" />
-    </artifact:dependencies>
-
-    <!-- Pull the dependencies for the MetadataGenerator CLI -->
-    <artifact:dependencies pathId="pmdg.pathid" filesetId="pmdg.fileset">
-      <localRepository path="${maven.repo.local}" />
-      <dependency groupId="org.codehaus.plexus" artifactId="plexus-component-metadata" version="${pom.properties.plexusVersion}" />
-    </artifact:dependencies>
-
-  </target>
-
-  <target name="process-classes" depends="pull" description="generates plexus component metadata.">
-    <mkdir dir="${basedir}/bootstrap/target" />
-    <mkdir dir="${basedir}/bootstrap/target/classes" />
-
-    <path id="pmdg.classpath">
-      <path refid="maven.classpath" />
-      <path refid="pmdg.pathid" />
-    </path>
-
-    <echo>Using plexus version ${pom.properties.plexusVersion}</echo>
-    <java fork="true" classname="org.codehaus.plexus.metadata.PlexusMetadataGeneratorCli" failonerror="true">
-      <classpath refid="pmdg.classpath" />
-      <!-- We need to generate component descriptors from the maven-artifact sources which use javadoc annotations. -->
-      <arg value="--source" />
-      <arg value="${basedir}/maven-compat/src/main/java" />
-      <!-- We have separated the artifact handlers and lifecycle mappings into a separate file. -->
-      <arg value="--descriptors" />
-      <arg value="${basedir}/maven-core/src/main/resources/META-INF/plexus" />
-      <!-- Search the classes for annotations that we've compiled. -->
-      <arg value="--classes" />
-      <arg value="${basedir}/bootstrap/target/classes" />
-      <!-- We'll make one big fat components descriptor. -->
-      <arg value="--output" />
-      <arg value="${basedir}/bootstrap/target/classes/META-INF/plexus/components.xml" />
-    </java>
-  </target>
-
-  <target name="generate-sources" depends="pull" description="generates Java sources from Modello mdo model files">
-    <mkdir dir="bootstrap/target" />
-    <mkdir dir="bootstrap/target/generated-sources" />
-
-    <macrodef name="modello-single-mode">
-      <attribute name="file" />
-      <attribute name="mode" />
-      <attribute name="version" />
-      <sequential>
-        <java fork="true" classname="org.codehaus.modello.ModelloCli" failonerror="true">
-          <classpath refid="modello.pathid" />
-          <arg file="@{file}" />
-          <!-- model file -->
-          <arg value="@{mode}" />
-          <!-- output type -->
-          <arg file="bootstrap/target/generated-sources" />
-          <!-- output directory -->
-          <arg value="@{version}" />
-          <!-- model version -->
-          <arg value="false" />
-          <!-- package with version -->
-          <arg value="true" />
-          <!-- use Java 5 -->
-          <arg value="UTF-8" />
-          <!-- encoding -->
-        </java>
-      </sequential>
-    </macrodef>
-
-    <macrodef name="modello">
-      <attribute name="file" />
-      <attribute name="version" default="1.0.0" />
-      <sequential>
-        <echo taskname="modello" message="Generating sources for @{file}" />
-        <modello-single-mode file="@{file}" version="@{version}" mode="java" />
-        <modello-single-mode file="@{file}" version="@{version}" mode="xpp3-reader" />
-        <modello-single-mode file="@{file}" version="@{version}" mode="xpp3-writer" />
-      </sequential>
-    </macrodef>
-
-    <macrodef name="modello-ex">
-      <attribute name="file" />
-      <attribute name="version" default="1.0.0" />
-      <sequential>
-        <modello file="@{file}" version="@{version}" />
-        <modello-single-mode file="@{file}" version="@{version}" mode="xpp3-extended-reader" />
-      </sequential>
-    </macrodef>
-
-    <modello-ex file="maven-model/src/main/mdo/maven.mdo" version="4.0.0" />
-    <modello file="maven-plugin-api/src/main/mdo/lifecycle.mdo" />
-    <modello file="maven-model-builder/src/main/mdo/profiles.mdo" />
-    <modello file="maven-settings/src/main/mdo/settings.mdo" version="1.1.0" />
-    <modello file="maven-core/src/main/mdo/toolchains.mdo" version="1.1.0" />
-    <modello file="maven-repository-metadata/src/main/mdo/metadata.mdo" version="1.1.0" />
-    <modello file="maven-compat/src/main/mdo/profiles.mdo" />
-    <modello file="maven-compat/src/main/mdo/paramdoc.mdo" />
-    <modello file="maven-embedder/src/main/mdo/core-extensions.mdo" />
-  </target>
-
-  <target name="compile-boot" depends="generate-sources" description="compiles the bootstrap sources">
-    <path id="sources">
-      <dirset dir=".">
-        <include name="bootstrap/target/generated-sources" />
-        <include name="*/src/main/java" />
-      </dirset>
-    </path>
-
-    <mkdir dir="bootstrap/target/classes" />
-    <javac destdir="bootstrap/target/classes" encoding="UTF-8" source="1.7" target="1.7" debug="true" includeAntRuntime="false">
-      <src refid="sources" />
-      <classpath refid="pom.pathid" />
-    </javac>
-
-    <copy todir="bootstrap/target/classes" encoding="ISO-8859-1">
-      <fileset dir="maven-core/src/main/resources">
-        <include name="**/build.properties" />
-      </fileset>
-      <filterset begintoken="${" endtoken="}">
-        <filter token="project.version" value="${xmlPom.project.version}"/>
-      </filterset>
-    </copy>
-    <echo file="bootstrap/target/classes/META-INF/maven/org.apache.maven/maven-core/pom.properties" encoding="ISO-8859-1">
-      version = ${xmlPom.project.version}
-    </echo>
-
-    <path id="maven.classpath">
-      <pathelement location="bootstrap/target/classes" />
-      <dirset dir=".">
-        <include name="*/src/main/resources" />
-      </dirset>
-      <path refid="pom.pathid" />
-    </path>
-  </target>
-
-  <target name="maven-compile" depends="compile-boot,process-classes" description="compiles Maven using the bootstrap Maven, skipping automated tests">
-    <java fork="${maven-compile.fork}" classname="org.apache.maven.cli.MavenCli" failonerror="true" timeout="600000"  maxmemory="${maven-compile.maxmemory}">
-      <!--jvmarg line="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000"/-->
-      <!--jvmarg value="${maven-compile.jvmargs}"/-->
-      <classpath refid="maven.classpath" />
-      <arg value="${maven.debug}" />
-      <arg value="-B" />
-      <arg value="-V" />
-      <arg value="clean" />
-      <arg value="${maven.goal}" />
-      <arg value="-Dmaven.test.skip=${maven.test.skip}" />
-      <arg value="-DskipTests=${skipTests}" />
-      <arg value="-Dmaven.repo.local=${maven.repo.local}" />
-      <arg value="-Dsurefire.useFile=${surefire.useFile}" />
-      <arg value="-Dmaven.test.redirectTestOutputToFile=${maven.test.redirectTestOutputToFile}" />
-      <arg value="-DdistributionId=${distributionId}" />
-      <arg value="-DdistributionShortName=${distributionShortName}" />
-      <arg value="-DdistributionName=${distributionName}" />
-      <jvmarg value="-Dmaven.multiModuleProjectDirectory=${basedir}" />
-    </java>
-  </target>
-
-  <target name="maven-assembly" depends="maven-compile" description="generates the Maven installation assembly using the bootstrap Maven">
-    <echo>
-The new Maven distribution was created as part of the MAVEN-COMPILE step, above.
-This goal just validates the presence of that distribution.
-</echo>
-    <condition property="build.failed">
-      <not>
-        <available file="${maven.assembly}" />
-      </not>
-    </condition>
-    <fail if="build.failed" message="Assembly task seemed to succeed, but couldn't find assembly file: ${maven.assembly}" />
-  </target>
-
-  <target name="extract-assembly" depends="init,prompt-maven-home-exists,maven-assembly" description="extracts the maven assembly into maven.home">
-    <echo>Extracting assembly to ${maven.home} ...</echo>
-    <!-- If we are starting from scratch make sure the directory is created -->
-    <delete dir="${maven.home}" />
-    <mkdir dir="${maven.home}" />
-    <unzip src="${maven.assembly}" dest="${maven.home}">
-      <mapper type="regexp" from="^[^\\/]+[\\/](.*)$$" to="\1" />
-    </unzip>
-    <chmod perm="+x">
-      <fileset dir="${maven.home}/bin">
-        <include name="mvn" />
-        <include name="mvnDebug" />
-        <include name="mvnyjp" />
-      </fileset>
-    </chmod>
-  </target>
-
-  <target name="all" depends="clean-bootstrap,init,extract-assembly" />
-
-</project>
diff --git a/doap_Maven.rdf b/doap_Maven.rdf
index a50b68f334..88bf82af25 100644
--- a/doap_Maven.rdf
+++ b/doap_Maven.rdf
@@ -33,6 +33,17 @@ under the License.
     <release>
       <Version>
         <name>Latest stable release</name>
+        <created>2015-11-14</created>
+        <revision>3.3.9</revision>
+        <file-release>http://archive.apache.org/dist/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.zip</file-release>
+        <file-release>http://archive.apache.org/dist/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz</file-release>
+        <file-release>http://archive.apache.org/dist/maven/maven-3/3.3.9/source/apache-maven-3.3.9-src.zip</file-release>
+        <file-release>http://archive.apache.org/dist/maven/maven-3/3.3.9/source/apache-maven-3.3.9-src.tar.gz</file-release>
+      </Version>
+    </release>
+    <release>
+      <Version>
+        <name>Apache Maven 3.3.3</name>
         <created>2015-04-28</created>
         <revision>3.3.3</revision>
         <file-release>http://archive.apache.org/dist/maven/maven-3/3.3.3/binaries/apache-maven-3.3.3-bin.zip</file-release>
diff --git a/maven-aether-provider/pom.xml b/maven-aether-provider/pom.xml
index 93e93e92ef..6306d4f0d8 100644
--- a/maven-aether-provider/pom.xml
+++ b/maven-aether-provider/pom.xml
@@ -25,7 +25,7 @@ under the License.
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.3.10-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-aether-provider</artifactId>
@@ -110,7 +110,7 @@ under the License.
     <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-core</artifactId>
-      <version>1.9.5</version>
+      <version>1.10.19</version>
       <scope>test</scope>
     </dependency>
   </dependencies>
diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/ArtifactDescriptorReaderDelegate.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/ArtifactDescriptorReaderDelegate.java
index 2395b36fbd..184c327700 100644
--- a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/ArtifactDescriptorReaderDelegate.java
+++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/ArtifactDescriptorReaderDelegate.java
@@ -124,7 +124,11 @@ private Dependency convert( org.apache.maven.model.Dependency dependency, Artifa
             exclusions.add( convert( exclusion ) );
         }
 
-        Dependency result = new Dependency( artifact, dependency.getScope(), dependency.isOptional(), exclusions );
+        Dependency result = new Dependency( artifact, dependency.getScope(),
+                                            dependency.getOptional() != null
+                                                ? dependency.isOptional()
+                                                : null,
+                                            exclusions );
 
         return result;
     }
diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java
index f344959f14..0832a3ada2 100644
--- a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java
+++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/DefaultModelResolver.java
@@ -26,6 +26,7 @@
 import java.util.List;
 import java.util.Set;
 
+import org.apache.maven.model.Dependency;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
 import org.apache.maven.model.Parent;
@@ -182,25 +183,27 @@ public ModelSource resolveModel( String groupId, String artifactId, String versi
         return new FileModelSource( pomFile );
     }
 
-    public ModelSource resolveModel( Parent parent )
+    @Override
+    public ModelSource resolveModel( final Parent parent )
         throws UnresolvableModelException
     {
-        Artifact artifact = new DefaultArtifact( parent.getGroupId(), parent.getArtifactId(), "", "pom",
-                                                 parent.getVersion() );
-
-        VersionRangeRequest versionRangeRequest = new VersionRangeRequest( artifact, repositories, context );
-        versionRangeRequest.setTrace( trace );
-
         try
         {
-            VersionRangeResult versionRangeResult =
+            final Artifact artifact = new DefaultArtifact( parent.getGroupId(), parent.getArtifactId(), "", "pom",
+                                                           parent.getVersion() );
+
+            final VersionRangeRequest versionRangeRequest = new VersionRangeRequest( artifact, repositories, context );
+            versionRangeRequest.setTrace( trace );
+
+            final VersionRangeResult versionRangeResult =
                 versionRangeResolver.resolveVersionRange( session, versionRangeRequest );
 
             if ( versionRangeResult.getHighestVersion() == null )
             {
-                throw new UnresolvableModelException( "No versions matched the requested range '" + parent.getVersion()
-                                                          + "'", parent.getGroupId(), parent.getArtifactId(),
-                                                      parent.getVersion() );
+                throw new UnresolvableModelException(
+                    String.format( "No versions matched the requested parent version range '%s'",
+                                   parent.getVersion() ),
+                    parent.getGroupId(), parent.getArtifactId(), parent.getVersion() );
 
             }
 
@@ -208,22 +211,69 @@ public ModelSource resolveModel( Parent parent )
                      && versionRangeResult.getVersionConstraint().getRange() != null
                      && versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null )
             {
-                throw new UnresolvableModelException( "The requested version range '" + parent.getVersion()
-                                                          + "' does not specify an upper bound", parent.getGroupId(),
-                                                      parent.getArtifactId(), parent.getVersion() );
+                throw new UnresolvableModelException(
+                    String.format( "The requested parent version range '%s' does not specify an upper bound",
+                                   parent.getVersion() ),
+                    parent.getGroupId(), parent.getArtifactId(), parent.getVersion() );
 
             }
 
             parent.setVersion( versionRangeResult.getHighestVersion().toString() );
+
+            return resolveModel( parent.getGroupId(), parent.getArtifactId(), parent.getVersion() );
         }
-        catch ( VersionRangeResolutionException e )
+        catch ( final VersionRangeResolutionException e )
         {
             throw new UnresolvableModelException( e.getMessage(), parent.getGroupId(), parent.getArtifactId(),
                                                   parent.getVersion(), e );
 
         }
-
-        return resolveModel( parent.getGroupId(), parent.getArtifactId(), parent.getVersion() );
     }
 
+    @Override
+    public ModelSource resolveModel( final Dependency dependency )
+        throws UnresolvableModelException
+    {
+        try
+        {
+            final Artifact artifact = new DefaultArtifact( dependency.getGroupId(), dependency.getArtifactId(), "",
+                                                           "pom", dependency.getVersion() );
+
+            final VersionRangeRequest versionRangeRequest = new VersionRangeRequest( artifact, repositories, context );
+            versionRangeRequest.setTrace( trace );
+
+            final VersionRangeResult versionRangeResult =
+                versionRangeResolver.resolveVersionRange( session, versionRangeRequest );
+
+            if ( versionRangeResult.getHighestVersion() == null )
+            {
+                throw new UnresolvableModelException(
+                    String.format( "No versions matched the requested dependency version range '%s'",
+                                   dependency.getVersion() ),
+                    dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() );
+
+            }
+
+            if ( versionRangeResult.getVersionConstraint() != null
+                     && versionRangeResult.getVersionConstraint().getRange() != null
+                     && versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null )
+            {
+                throw new UnresolvableModelException(
+                    String.format( "The requested dependency version range '%s' does not specify an upper bound",
+                                   dependency.getVersion() ),
+                    dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() );
+
+            }
+
+            dependency.setVersion( versionRangeResult.getHighestVersion().toString() );
+
+            return resolveModel( dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() );
+        }
+        catch ( VersionRangeResolutionException e )
+        {
+            throw new UnresolvableModelException( e.getMessage(), dependency.getGroupId(), dependency.getArtifactId(),
+                                                  dependency.getVersion(), e );
+
+        }
+    }
 }
diff --git a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenRepositorySystemUtils.java b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenRepositorySystemUtils.java
index 5b240efe1d..3a98b2acc5 100644
--- a/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenRepositorySystemUtils.java
+++ b/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/MavenRepositorySystemUtils.java
@@ -106,8 +106,9 @@ public static DefaultRepositorySystemSession newSession()
         DependencyGraphTransformer transformer =
             new ConflictResolver( new NearestVersionSelector(), new JavaScopeSelector(),
                                   new SimpleOptionalitySelector(), new JavaScopeDeriver() );
-        new ChainedDependencyGraphTransformer( transformer, new JavaDependencyContextRefiner() );
-        session.setDependencyGraphTransformer( transformer );
+
+        session.setDependencyGraphTransformer(
+            new ChainedDependencyGraphTransformer( transformer, new JavaDependencyContextRefiner() ) );
 
         DefaultArtifactTypeRegistry stereotypes = new DefaultArtifactTypeRegistry();
         stereotypes.add( new DefaultArtifactType( "pom" ) );
diff --git a/maven-ant-tasks-2.1.1.jar b/maven-ant-tasks-2.1.1.jar
deleted file mode 100644
index 7810a541b8..0000000000
Binary files a/maven-ant-tasks-2.1.1.jar and /dev/null differ
diff --git a/maven-artifact/pom.xml b/maven-artifact/pom.xml
index 97fb70ac61..c8a63b7996 100644
--- a/maven-artifact/pom.xml
+++ b/maven-artifact/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.3.10-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 147e88e4ae..a6d136752b 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
@@ -230,7 +230,7 @@ public String getDependencyConflictId()
     {
         StringBuilder sb = new StringBuilder( 128 );
         sb.append( getGroupId() );
-        sb.append( ":" );
+        sb.append( ':' );
         appendArtifactTypeClassifierString( sb );
         return sb.toString();
     }
@@ -238,11 +238,11 @@ public String getDependencyConflictId()
     private void appendArtifactTypeClassifierString( StringBuilder sb )
     {
         sb.append( getArtifactId() );
-        sb.append( ":" );
+        sb.append( ':' );
         sb.append( getType() );
         if ( hasClassifier() )
         {
-            sb.append( ":" );
+            sb.append( ':' );
             sb.append( getClassifier() );
         }
     }
@@ -272,7 +272,7 @@ public void addMetadata( ArtifactMetadata metadata )
             return Collections.emptyList();
         }
 
-        return metadataMap.values();
+        return Collections.unmodifiableCollection( metadataMap.values() );
     }
 
     // ----------------------------------------------------------------------
@@ -285,10 +285,10 @@ public String toString()
         if ( getGroupId() != null )
         {
             sb.append( getGroupId() );
-            sb.append( ":" );
+            sb.append( ':' );
         }
         appendArtifactTypeClassifierString( sb );
-        sb.append( ":" );
+        sb.append( ':' );
         if ( getBaseVersionInternal() != null )
         {
             sb.append( getBaseVersionInternal() );
@@ -299,7 +299,7 @@ public String toString()
         }
         if ( scope != null )
         {
-            sb.append( ":" );
+            sb.append( ':' );
             sb.append( scope );
         }
         return sb.toString();
diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/repository/ArtifactRepository.java b/maven-artifact/src/main/java/org/apache/maven/artifact/repository/ArtifactRepository.java
index 9ef30387b3..0b33345c73 100644
--- a/maven-artifact/src/main/java/org/apache/maven/artifact/repository/ArtifactRepository.java
+++ b/maven-artifact/src/main/java/org/apache/maven/artifact/repository/ArtifactRepository.java
@@ -79,7 +79,6 @@
     /**
      *
      * @param artifact
-     * @return
      * @since 3.0-alpha-3
      */
     Artifact find( Artifact artifact );
diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/repository/ArtifactRepositoryPolicy.java b/maven-artifact/src/main/java/org/apache/maven/artifact/repository/ArtifactRepositoryPolicy.java
index b6cd8f39cb..c5d24732ee 100644
--- a/maven-artifact/src/main/java/org/apache/maven/artifact/repository/ArtifactRepositoryPolicy.java
+++ b/maven-artifact/src/main/java/org/apache/maven/artifact/repository/ArtifactRepositoryPolicy.java
@@ -160,7 +160,7 @@ public String toString()
         buffer.append( checksumPolicy );
         buffer.append( ", updates=" );
         buffer.append( updatePolicy );
-        buffer.append( "}" );
+        buffer.append( '}' );
         return buffer.toString();
     }
 
diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/AbstractArtifactResolutionException.java b/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/AbstractArtifactResolutionException.java
index 66e147c238..b63428e713 100644
--- a/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/AbstractArtifactResolutionException.java
+++ b/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/AbstractArtifactResolutionException.java
@@ -175,7 +175,7 @@ protected static String constructArtifactPath( List<String> path,
             for ( Iterator<String> i = path.iterator(); i.hasNext(); num++ )
             {
                 sb.append( indentation );
-                sb.append( "\t" );
+                sb.append( '\t' );
                 sb.append( num );
                 sb.append( ") " );
                 sb.append( i.next() );
@@ -201,8 +201,8 @@ private static String constructMessageBase( String message,
         if ( message == null || !message.contains( "from the specified remote repositories:" ) )
         {
             sb.append( LS );
-            sb.append( "  " ).append( groupId ).append( ":" ).append( artifactId ).append( ":" ).append( type ).append(
-                ":" ).append( version );
+            sb.append( "  " ).append( groupId ).append( ':' ).append( artifactId ).append( ':' ).append( type ).append(
+                ':' ).append( version );
             sb.append( LS );
             if ( remoteRepositories != null )
             {
@@ -235,10 +235,10 @@ private static String constructMessageBase( String message,
                         sb.append( ", snapshots=" ).append( snapshots.isEnabled() );
                     }
 
-                    sb.append( ")" );
+                    sb.append( ')' );
                     if ( i.hasNext() )
                     {
-                        sb.append( "," ).append( LS ).append( "  " );
+                        sb.append( ',' ).append( LS ).append( "  " );
                     }
                 }
             }
diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/MultipleArtifactsNotFoundException.java b/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/MultipleArtifactsNotFoundException.java
index 0f13db1571..896710f575 100644
--- a/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/MultipleArtifactsNotFoundException.java
+++ b/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/MultipleArtifactsNotFoundException.java
@@ -84,8 +84,9 @@ public MultipleArtifactsNotFoundException( Artifact originatingArtifact,
 
     private static String constructMessage( List<Artifact> artifacts )
     {
-        StringBuilder buffer = new StringBuilder( "Missing:\n" );
+        StringBuilder buffer = new StringBuilder( 256 );
 
+        buffer.append( "Missing:\n" );
         buffer.append( "----------\n" );
 
         int counter = 0;
diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java b/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java
index e7d24c43fa..f434ef0693 100644
--- a/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java
+++ b/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/ComparableVersion.java
@@ -33,7 +33,7 @@
  *
  * <p>Features:
  * <ul>
- * <li>mixing of '<code>-</code>' (dash) and '<code>.</code>' (dot) separators,</li>
+ * <li>mixing of '<code>-</code>' (hyphen) and '<code>.</code>' (dot) separators,</li>
  * <li>transition between characters and digits also constitutes a separator:
  *     <code>1.0alpha1 =&gt; [1, 0, alpha, 1]</code></li>
  * <li>unlimited number of version components,</li>
@@ -50,7 +50,7 @@
  *     </ul>
  *     Unknown qualifiers are considered after known qualifiers, with lexical order (always case insensitive),
  *   </li>
- * <li>a dash usually precedes a qualifier, and is always less important than something preceded with a dot.</li>
+ * <li>a hyphen usually precedes a qualifier, and is always less important than something preceded with a dot.</li>
  * </ul></p>
  *
  * @see <a href="https://cwiki.apache.org/confluence/display/MAVENOLD/Versioning">"Versioning" on Maven Wiki</a>
diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/DefaultArtifactVersion.java b/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/DefaultArtifactVersion.java
index 99b2b85b81..7fcbce83a0 100644
--- a/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/DefaultArtifactVersion.java
+++ b/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/DefaultArtifactVersion.java
@@ -111,7 +111,7 @@ public final void parseVersion( String version )
     {
         comparable = new ComparableVersion( version );
 
-        int index = version.indexOf( "-" );
+        int index = version.indexOf( '-' );
 
         String part1;
         String part2 = null;
diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/Restriction.java b/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/Restriction.java
index d73d7ea5b0..c728e9f03e 100644
--- a/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/Restriction.java
+++ b/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/Restriction.java
@@ -178,17 +178,17 @@ public String toString()
     {
         StringBuilder buf = new StringBuilder();
 
-        buf.append( isLowerBoundInclusive() ? "[" : "(" );
+        buf.append( isLowerBoundInclusive() ? '[' : '(' );
         if ( getLowerBound() != null )
         {
             buf.append( getLowerBound().toString() );
         }
-        buf.append( "," );
+        buf.append( ',' );
         if ( getUpperBound() != null )
         {
             buf.append( getUpperBound().toString() );
         }
-        buf.append( isUpperBoundInclusive() ? "]" : ")" );
+        buf.append( isUpperBoundInclusive() ? ']' : ')' );
 
         return buf.toString();
     }
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 0d094ef8a4..7d216f4a41 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
@@ -104,8 +104,8 @@ public static VersionRange createFromVersionSpec( String spec )
 
         while ( process.startsWith( "[" ) || process.startsWith( "(" ) )
         {
-            int index1 = process.indexOf( ")" );
-            int index2 = process.indexOf( "]" );
+            int index1 = process.indexOf( ')' );
+            int index2 = process.indexOf( ']' );
 
             int index = index2;
             if ( index2 < 0 || index1 < index2 )
@@ -171,7 +171,7 @@ private static Restriction parseRestriction( String spec )
 
         Restriction restriction;
 
-        int index = process.indexOf( "," );
+        int index = process.indexOf( ',' );
 
         if ( index < 0 )
         {
@@ -261,7 +261,7 @@ public VersionRange restrict( VersionRange restriction )
         }
         else
         {
-            restrictions = intersection( r1, r2 );
+            restrictions = Collections.unmodifiableList( intersection( r1, r2 ) );
         }
 
         ArtifactVersion version = null;
diff --git a/maven-artifact/src/main/java/org/apache/maven/repository/Proxy.java b/maven-artifact/src/main/java/org/apache/maven/repository/Proxy.java
index ea2c0238e7..1dc1a2c75b 100644
--- a/maven-artifact/src/main/java/org/apache/maven/repository/Proxy.java
+++ b/maven-artifact/src/main/java/org/apache/maven/repository/Proxy.java
@@ -158,7 +158,7 @@ public String getProtocol()
     }
 
     /**
-     * @param type the type of the proxy server like <i>SOCKSv4</i>
+     * @param protocol the type of the proxy server like <i>SOCKSv4</i>
      */
     public void setProtocol( String protocol )
     {
diff --git a/maven-builder-support/pom.xml b/maven-builder-support/pom.xml
index 904aa93935..90fa43b58e 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.3.10-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-builder-support</artifactId>
diff --git a/maven-builder-support/src/main/java/org/apache/maven/building/DefaultProblem.java b/maven-builder-support/src/main/java/org/apache/maven/building/DefaultProblem.java
index ad1fc40fb9..427eb2c6e4 100644
--- a/maven-builder-support/src/main/java/org/apache/maven/building/DefaultProblem.java
+++ b/maven-builder-support/src/main/java/org/apache/maven/building/DefaultProblem.java
@@ -151,7 +151,7 @@ public String toString()
     {
         StringBuilder buffer = new StringBuilder( 128 );
 
-        buffer.append( "[" ).append( getSeverity() ).append( "] " );
+        buffer.append( '[' ).append( getSeverity() ).append( "] " );
         buffer.append( getMessage() );
         buffer.append( " @ " ).append( getLocation() );
 
diff --git a/maven-compat/pom.xml b/maven-compat/pom.xml
index 05f28bdcda..0c219c10c9 100644
--- a/maven-compat/pom.xml
+++ b/maven-compat/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.3.10-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/ArtifactScopeEnum.java b/maven-compat/src/main/java/org/apache/maven/artifact/ArtifactScopeEnum.java
index 7051e3bf55..4460a07c3e 100644
--- a/maven-compat/src/main/java/org/apache/maven/artifact/ArtifactScopeEnum.java
+++ b/maven-compat/src/main/java/org/apache/maven/artifact/ArtifactScopeEnum.java
@@ -49,8 +49,6 @@ int getId()
 
     /**
      * Helper method to simplify null processing
-     *
-     * @return
      */
     public static final ArtifactScopeEnum checkScope( ArtifactScopeEnum scope )
     {
diff --git a/maven-compat/src/main/java/org/apache/maven/artifact/UnknownRepositoryLayoutException.java b/maven-compat/src/main/java/org/apache/maven/artifact/UnknownRepositoryLayoutException.java
index 5abe1105a3..cb0af7fc2f 100644
--- a/maven-compat/src/main/java/org/apache/maven/artifact/UnknownRepositoryLayoutException.java
+++ b/maven-compat/src/main/java/org/apache/maven/artifact/UnknownRepositoryLayoutException.java
@@ -19,6 +19,7 @@
  * under the License.
  */
 
+import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
 
 /**
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 e0a55879ea..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
@@ -175,11 +175,11 @@ public void setBlacklisted( boolean blacklisted )
 
     public String toString()
     {
-        StringBuilder sb = new StringBuilder();
+        StringBuilder sb = new StringBuilder( 256 );
 
-        sb.append( "       id: " ).append( getId() ).append( "\n" );
-        sb.append( "      url: " ).append( getUrl() ).append( "\n" );
-        sb.append( "   layout: " ).append( layout != null ? layout : "none" ).append( "\n" );
+        sb.append( "       id: " ).append( getId() ).append( '\n' );
+        sb.append( "      url: " ).append( getUrl() ).append( '\n' );
+        sb.append( "   layout: " ).append( layout != null ? layout : "none" ).append( '\n' );
 
         if ( snapshots != null )
         {
@@ -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/artifact/versioning/ManagedVersionMap.java b/maven-compat/src/main/java/org/apache/maven/artifact/versioning/ManagedVersionMap.java
index 86b49499ad..02ac24cbe5 100644
--- a/maven-compat/src/main/java/org/apache/maven/artifact/versioning/ManagedVersionMap.java
+++ b/maven-compat/src/main/java/org/apache/maven/artifact/versioning/ManagedVersionMap.java
@@ -45,10 +45,10 @@ public String toString()
         while ( iter.hasNext() )
         {
             String key = iter.next();
-            buffer.append( key ).append( "=" ).append( get( key ) );
+            buffer.append( key ).append( '=' ).append( get( key ) );
             if ( iter.hasNext() )
             {
-                buffer.append( "\n" );
+                buffer.append( '\n' );
             }
         }
         return buffer.toString();
diff --git a/maven-compat/src/main/java/org/apache/maven/project/interpolation/AbstractStringBasedModelInterpolator.java b/maven-compat/src/main/java/org/apache/maven/project/interpolation/AbstractStringBasedModelInterpolator.java
index 568196cb99..634c43a361 100644
--- a/maven-compat/src/main/java/org/apache/maven/project/interpolation/AbstractStringBasedModelInterpolator.java
+++ b/maven-compat/src/main/java/org/apache/maven/project/interpolation/AbstractStringBasedModelInterpolator.java
@@ -188,8 +188,6 @@ public Model interpolate( Model model,
      *       with the value, and continue to find other expressions.</li>
      *   <li>If the value is null, get it from the model properties.</li>
      *   <li>
-     * @param overrideContext
-     * @param outputDebugMessages
      */
     public String interpolate( String src,
                                Model model,
diff --git a/maven-compat/src/main/java/org/apache/maven/project/validation/ModelValidationResult.java b/maven-compat/src/main/java/org/apache/maven/project/validation/ModelValidationResult.java
index ad94fe00d1..5033b990d8 100644
--- a/maven-compat/src/main/java/org/apache/maven/project/validation/ModelValidationResult.java
+++ b/maven-compat/src/main/java/org/apache/maven/project/validation/ModelValidationResult.java
@@ -85,7 +85,7 @@ public String render( String indentation )
 //
         for ( int i = 0; i < messages.size(); i++ )
         {
-            message.append( indentation ).append( "[" ).append( i ).append( "]  " ).append( messages.get( i ) ).append(
+            message.append( indentation ).append( '[' ).append( i ).append( "]  " ).append( messages.get( i ) ).append(
                 NEWLINE );
         }
 
diff --git a/maven-compat/src/main/java/org/apache/maven/repository/MetadataGraph.java b/maven-compat/src/main/java/org/apache/maven/repository/MetadataGraph.java
index e994856c17..2aebc74c82 100644
--- a/maven-compat/src/main/java/org/apache/maven/repository/MetadataGraph.java
+++ b/maven-compat/src/main/java/org/apache/maven/repository/MetadataGraph.java
@@ -55,9 +55,6 @@ public void addNode( MetadataGraphNode node )
 
     /**
      * find a node by the GAV (metadata)
-     *
-     * @param md
-     * @return
      */
     public MetadataGraphNode findNode( MavenArtifactMetadata md )
     {
@@ -76,8 +73,6 @@ public MetadataGraphNode findNode( MavenArtifactMetadata md )
 
     /**
      * getter
-     *
-     * @return
      */
     public MetadataGraphNode getEntry()
     {
@@ -86,8 +81,6 @@ public MetadataGraphNode getEntry()
 
     /**
      * getter
-     *
-     * @return
      */
     public Collection<MetadataGraphNode> getNodes()
     {
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 cfdd7f96fc..8b31f22fea 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 )
@@ -322,21 +333,19 @@ public MetadataResolutionResult setRepositories( final List<ArtifactRepository>
 
     public String toString()
     {
-        StringBuilder sb = new StringBuilder();
+        if ( artifacts == null )
+            return "";
 
-        if ( artifacts != null )
+        StringBuilder sb = new StringBuilder( 256 );
+        int i = 1;
+        sb.append( "---------\n" );
+        sb.append( artifacts.size() ).append( '\n' );
+        for ( Artifact a : artifacts )
         {
-            int i = 1;
-            sb.append( "---------" ).append( "\n" );
-            sb.append( artifacts.size() ).append( "\n" );
-            for ( Artifact a : artifacts )
-            {
-                sb.append( i ).append( " " ).append( a ).append( "\n" );
-                i++;
-            }
-            sb.append( "---------" ).append( "\n" );
+            sb.append( i ).append( ' ' ).append( a ).append( '\n' );
+            i++;
         }
-
+        sb.append( "---------\n" );
         return sb.toString();
     }
 
diff --git a/maven-compat/src/main/java/org/apache/maven/repository/legacy/DefaultUpdateCheckManager.java b/maven-compat/src/main/java/org/apache/maven/repository/legacy/DefaultUpdateCheckManager.java
index dfc463b519..4839d689b7 100644
--- a/maven-compat/src/main/java/org/apache/maven/repository/legacy/DefaultUpdateCheckManager.java
+++ b/maven-compat/src/main/java/org/apache/maven/repository/legacy/DefaultUpdateCheckManager.java
@@ -28,15 +28,12 @@
 import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 import org.codehaus.plexus.logging.Logger;
-import org.codehaus.plexus.util.IOUtil;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
 import java.nio.channels.FileChannel;
 import java.nio.channels.FileLock;
 import java.util.Date;
@@ -242,18 +239,12 @@ private void writeLastUpdated( File touchfile, String key, String error )
                 Properties props = new Properties();
 
                 channel = new RandomAccessFile( touchfile, "rw" ).getChannel();
-                lock = channel.lock( 0, channel.size(), false );
+                lock = channel.lock();
 
                 if ( touchfile.canRead() )
                 {
                     getLogger().debug( "Reading resolution-state from: " + touchfile );
-                    ByteBuffer buffer = ByteBuffer.allocate( (int) channel.size() );
-
-                    channel.read( buffer );
-                    buffer.flip();
-
-                    ByteArrayInputStream stream = new ByteArrayInputStream( buffer.array() );
-                    props.load( stream );
+                    props.load( Channels.newInputStream( channel ) );
                 }
 
                 props.setProperty( key, Long.toString( System.currentTimeMillis() ) );
@@ -267,18 +258,15 @@ private void writeLastUpdated( File touchfile, String key, String error )
                     props.remove( key + ERROR_KEY_SUFFIX );
                 }
 
-                ByteArrayOutputStream stream = new ByteArrayOutputStream();
-
                 getLogger().debug( "Writing resolution-state to: " + touchfile );
-                props.store( stream, "Last modified on: " + new Date() );
+                channel.truncate( 0 );
+                props.store( Channels.newOutputStream( channel ), "Last modified on: " + new Date() );
 
-                byte[] data = stream.toByteArray();
-                ByteBuffer buffer = ByteBuffer.allocate( data.length );
-                buffer.put( data );
-                buffer.flip();
+                lock.release();
+                lock = null;
 
-                channel.position( 0 );
-                channel.write( buffer );
+                channel.close();
+                channel = null;
             }
             catch ( IOException e )
             {
@@ -359,27 +347,26 @@ private Properties read( File touchfile )
 
         synchronized ( touchfile.getAbsolutePath().intern() )
         {
+            FileInputStream in = null;
             FileLock lock = null;
-            FileChannel channel = null;
+
             try
             {
                 Properties props = new Properties();
 
-                FileInputStream stream = new FileInputStream( touchfile );
-                try
-                {
-                    channel = stream.getChannel();
-                    lock = channel.lock( 0, channel.size(), true );
+                in = new FileInputStream( touchfile );
+                lock = in.getChannel().lock( 0, Long.MAX_VALUE, true );
 
-                    getLogger().debug( "Reading resolution-state from: " + touchfile );
-                    props.load( stream );
+                getLogger().debug( "Reading resolution-state from: " + touchfile );
+                props.load( in );
 
-                    return props;
-                }
-                finally
-                {
-                    IOUtil.close( stream );
-                }
+                lock.release();
+                lock = null;
+
+                in.close();
+                in = null;
+
+                return props;
             }
             catch ( IOException e )
             {
@@ -402,11 +389,11 @@ private Properties read( File touchfile )
                     }
                 }
 
-                if ( channel != null )
+                if ( in != null )
                 {
                     try
                     {
-                        channel.close();
+                        in.close();
                     }
                     catch ( IOException e )
                     {
diff --git a/maven-compat/src/main/java/org/apache/maven/repository/legacy/LegacyRepositorySystem.java b/maven-compat/src/main/java/org/apache/maven/repository/legacy/LegacyRepositorySystem.java
index 866968ba9d..ba3409649b 100644
--- a/maven-compat/src/main/java/org/apache/maven/repository/legacy/LegacyRepositorySystem.java
+++ b/maven-compat/src/main/java/org/apache/maven/repository/legacy/LegacyRepositorySystem.java
@@ -144,6 +144,9 @@ public Artifact createDependencyArtifact( Dependency d )
         }
         catch ( InvalidVersionSpecificationException e )
         {
+            // MNG-5368: Log a message instead of returning 'null' silently.
+            this.logger.error( String.format( "Invalid version specification '%s' creating dependency artifact '%s'.",
+                                              d.getVersion(), d ), e );
             return null;
         }
 
@@ -180,6 +183,11 @@ public Artifact createExtensionArtifact( String groupId, String artifactId, Stri
         }
         catch ( InvalidVersionSpecificationException e )
         {
+            // MNG-5368: Log a message instead of returning 'null' silently.
+            this.logger.error( String.format(
+                "Invalid version specification '%s' creating extension artifact '%s:%s:%s'.",
+                version, groupId, artifactId, version, e ) );
+
             return null;
         }
 
@@ -193,18 +201,24 @@ public Artifact createParentArtifact( String groupId, String artifactId, String
 
     public Artifact createPluginArtifact( Plugin plugin )
     {
+        String version = plugin.getVersion();
+        if ( StringUtils.isEmpty( version ) )
+        {
+            version = "RELEASE";
+        }
+
         VersionRange versionRange;
         try
         {
-            String version = plugin.getVersion();
-            if ( StringUtils.isEmpty( version ) )
-            {
-                version = "RELEASE";
-            }
             versionRange = VersionRange.createFromVersionSpec( version );
         }
         catch ( InvalidVersionSpecificationException e )
         {
+            // MNG-5368: Log a message instead of returning 'null' silently.
+            this.logger.error( String.format(
+                "Invalid version specification '%s' creating plugin artifact '%s'.",
+                version, plugin, e ) );
+
             return null;
         }
 
diff --git a/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraph.java b/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraph.java
index 3f13888cf0..cdc824dc84 100644
--- a/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraph.java
+++ b/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraph.java
@@ -485,13 +485,13 @@ public String toString()
         }
         for ( MetadataGraphVertex v : vertices )
         {
-            sb.append( "Vertex:  " ).append( v.getMd().toString() ).append( "\n" );
+            sb.append( "Vertex:  " ).append( v.getMd().toString() ).append( '\n' );
             List<MetadataGraphEdge> ins = getIncidentEdges( v );
             if ( ins != null )
             {
                 for ( MetadataGraphEdge e : ins )
                 {
-                    sb.append( "       from :  " ).append( e.toString() ).append( "\n" );
+                    sb.append( "       from :  " ).append( e.toString() ).append( '\n' );
                 }
             }
             else
@@ -504,7 +504,7 @@ public String toString()
             {
                 for ( MetadataGraphEdge e : outs )
                 {
-                    sb.append( "        to :  " ).append( e.toString() ).append( "\n" );
+                    sb.append( "        to :  " ).append( e.toString() ).append( '\n' );
                 }
             }
             else
diff --git a/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraphVertex.java b/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraphVertex.java
index bdccf6a5c0..f7bc3fa0c2 100644
--- a/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraphVertex.java
+++ b/maven-compat/src/main/java/org/apache/maven/repository/metadata/MetadataGraphVertex.java
@@ -192,17 +192,17 @@ public int hashCode()
             return super.hashCode();
         }
         StringBuilder hashString = new StringBuilder( 128 );
-        hashString.append( md.groupId ).append( "|" );
-        hashString.append( md.artifactId ).append( "|" );
+        hashString.append( md.groupId ).append( '|' );
+        hashString.append( md.artifactId ).append( '|' );
 
         if ( compareVersion )
         {
-            hashString.append( md.version ).append( "|" );
+            hashString.append( md.version ).append( '|' );
         }
 
         if ( compareScope )
         {
-            hashString.append( md.getArtifactScope() ).append( "|" );
+            hashString.append( md.getArtifactScope() ).append( '|' );
         }
 
         return hashString.toString().hashCode();
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..365acc48a7 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
@@ -360,8 +360,9 @@ protected RepositorySystemSession initRepoSession()
         DependencyGraphTransformer transformer =
             new ConflictResolver( new NearestVersionSelector(), new JavaScopeSelector(),
                                   new SimpleOptionalitySelector(), new JavaScopeDeriver() );
-        new ChainedDependencyGraphTransformer( transformer, new JavaDependencyContextRefiner() );
-        session.setDependencyGraphTransformer( transformer );
+
+        session.setDependencyGraphTransformer(
+            new ChainedDependencyGraphTransformer( transformer, new JavaDependencyContextRefiner() ) );
 
         LocalRepository localRepo = new LocalRepository( localRepository().getBasedir() );
         session.setLocalRepositoryManager(
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..2e0d7eab21 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
@@ -23,7 +23,9 @@
 import java.util.LinkedHashSet;
 import java.util.Set;
 
-import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer;
+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;
 
@@ -31,8 +33,9 @@
  * @author Benjamin Bentmann
  */
 public class EmptyLifecyclePluginAnalyzer
-    implements LifeCyclePluginAnalyzer
+    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/LegacyLocalRepositoryManager.java b/maven-compat/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java
index 52fdd80478..c919cdf776 100644
--- a/maven-compat/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java
+++ b/maven-compat/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java
@@ -59,7 +59,7 @@ public String getPathForLocalArtifact( Artifact artifact )
 
         path.append( artifact.getGroupId() ).append( '/' );
 
-        path.append( artifact.getExtension() ).append( 's' ).append( '/' );
+        path.append( artifact.getExtension() ).append( "s/" );
 
         path.append( artifact.getArtifactId() ).append( '-' ).append( artifact.getVersion() );
 
diff --git a/maven-compat/src/test/java/org/apache/maven/project/inheritance/AbstractProjectInheritanceTestCase.java b/maven-compat/src/test/java/org/apache/maven/project/inheritance/AbstractProjectInheritanceTestCase.java
index 413d6fea06..93358ecc1f 100644
--- a/maven-compat/src/test/java/org/apache/maven/project/inheritance/AbstractProjectInheritanceTestCase.java
+++ b/maven-compat/src/test/java/org/apache/maven/project/inheritance/AbstractProjectInheritanceTestCase.java
@@ -33,7 +33,7 @@ protected String getTestSeries()
     {
         String className = getClass().getPackage().getName();
 
-        return className.substring( className.lastIndexOf( "." ) + 1 );
+        return className.substring( className.lastIndexOf( '.' ) + 1 );
     }
 
     protected File projectFile( String name )
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/org/apache/maven/project/AbstractMavenProjectTestCase.xml b/maven-compat/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml
index bcc291e174..7e02f5ec8e 100644
--- a/maven-compat/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml
+++ b/maven-compat/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml
@@ -2,7 +2,7 @@
 <plexus>
   <components>
     <component>
-      <role>org.apache.maven.lifecycle.LifeCyclePluginAnalyzer</role>
+      <role>org.apache.maven.lifecycle.LifecyclePluginAnalyzer</role>
       <implementation>org.apache.maven.project.EmptyLifecyclePluginAnalyzer</implementation>
     </component>
   </components>
diff --git a/maven-core/pom.xml b/maven-core/pom.xml
index 199d15d164..f43965100c 100644
--- a/maven-core/pom.xml
+++ b/maven-core/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.3.10-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-core</artifactId>
@@ -117,7 +117,7 @@
     <dependency>
       <groupId>org.mockito</groupId>
       <artifactId>mockito-core</artifactId>
-      <version>1.9.5</version>
+      <version>1.10.19</version>
       <scope>test</scope>
     </dependency>
   </dependencies>
diff --git a/maven-core/src/main/java/org/apache/maven/DefaultArtifactFilterManager.java b/maven-core/src/main/java/org/apache/maven/DefaultArtifactFilterManager.java
index 503dcdb313..1b049d02df 100644
--- a/maven-core/src/main/java/org/apache/maven/DefaultArtifactFilterManager.java
+++ b/maven-core/src/main/java/org/apache/maven/DefaultArtifactFilterManager.java
@@ -84,8 +84,6 @@ public ArtifactFilter getArtifactFilter()
 
     /**
      * Returns the artifact filter for the standard core artifacts.
-     *
-     * @see org.apache.maven.ArtifactFilterManager#getExtensionDependencyFilter()
      */
     public ArtifactFilter getCoreArtifactFilter()
     {
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 86eab4e026..52442b7164 100644
--- a/maven-core/src/main/java/org/apache/maven/RepositoryUtils.java
+++ b/maven-core/src/main/java/org/apache/maven/RepositoryUtils.java
@@ -316,7 +316,12 @@ public static Dependency toDependency( org.apache.maven.model.Dependency depende
             exclusions.add( toExclusion( exclusion ) );
         }
 
-        Dependency result = new Dependency( artifact, dependency.getScope(), dependency.isOptional(), exclusions );
+        Dependency result = new Dependency( artifact,
+                                            dependency.getScope(),
+                                            dependency.getOptional() != null
+                                                ? dependency.isOptional()
+                                                : null,
+                                            exclusions );
 
         return result;
     }
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 8e45b20305..43f345575e 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
@@ -132,15 +132,15 @@ public String getKey()
 
     public String toString()
     {
-        StringBuilder sb = new StringBuilder();
+        StringBuilder sb = new StringBuilder( 256 );
 
-        sb.append( "      id: " ).append( getId() ).append( "\n" );
-        sb.append( "      url: " ).append( getUrl() ).append( "\n" );
-        sb.append( "   layout: " ).append( layout != null ? layout : "none" ).append( "\n" );
+        sb.append( "      id: " ).append( getId() ).append( '\n' );
+        sb.append( "      url: " ).append( getUrl() ).append( '\n' );
+        sb.append( "   layout: " ).append( layout != null ? layout : "none" ).append( '\n' );
 
         if ( proxy != null )
         {
-            sb.append( "    proxy: " ).append( proxy.getHost() ).append( ":" ).append( proxy.getPort() ).append( "\n" );
+            sb.append( "    proxy: " ).append( proxy.getHost() ).append( ':' ).append( proxy.getPort() ).append( '\n' );
         }
 
         if ( snapshots != null )
@@ -220,7 +220,7 @@ public void setUrl( String url )
      */
     private static String protocol( final String url )
     {
-        final int pos = url.indexOf( ":" );
+        final int pos = url.indexOf( ':' );
 
         if ( pos == -1 )
         {
@@ -257,7 +257,7 @@ private String basedir( String url )
                 else
                 {
                     // Now we expect the host
-                    int index = retValue.indexOf( "/" );
+                    int index = retValue.indexOf( '/' );
                     if ( index >= 0 )
                     {
                         retValue = retValue.substring( index + 1 );
@@ -401,7 +401,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/repository/metadata/AbstractRepositoryMetadata.java b/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/AbstractRepositoryMetadata.java
index 05284174a0..37e69e5bea 100644
--- a/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/AbstractRepositoryMetadata.java
+++ b/maven-core/src/main/java/org/apache/maven/artifact/repository/metadata/AbstractRepositoryMetadata.java
@@ -197,7 +197,7 @@ public void merge( ArtifactMetadata metadata )
 
     public String extendedToString()
     {
-        StringBuilder buffer = new StringBuilder();
+        StringBuilder buffer = new StringBuilder( 256 );
 
         buffer.append( "\nRepository Metadata\n--------------------------" );
         buffer.append( "\nGroupId: " ).append( getGroupId() );
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 7795dec620..48ad8e1f63 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
@@ -125,7 +125,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 )
@@ -160,7 +163,10 @@ public boolean hasExceptions()
 
     public List<Exception> getExceptions()
     {
-        return exceptions == null ? Collections.<Exception>emptyList() : exceptions;
+        return exceptions == null
+                   ? Collections.<Exception>emptyList()
+                   : Collections.unmodifiableList( exceptions );
+
     }
 
     // ------------------------------------------------------------------------
@@ -197,7 +203,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 );
+
     }
 
     // ------------------------------------------------------------------------
@@ -229,8 +238,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 );
+
     }
 
     // ------------------------------------------------------------------------
@@ -262,7 +273,7 @@ public ArtifactResolutionResult addErrorArtifactException( ArtifactResolutionExc
             return Collections.emptyList();
         }
 
-        return errorArtifactExceptions;
+        return Collections.unmodifiableList( errorArtifactExceptions );
     }
 
     // ------------------------------------------------------------------------
@@ -299,7 +310,7 @@ public CyclicDependencyException getCircularDependencyException( int i )
             return Collections.emptyList();
         }
 
-        return circularDependencyExceptions;
+        return Collections.unmodifiableList( circularDependencyExceptions );
     }
 
     // ------------------------------------------------------------------------
@@ -313,7 +324,7 @@ public CyclicDependencyException getCircularDependencyException( int i )
             return Collections.emptyList();
         }
 
-        return repositories;
+        return Collections.unmodifiableList( repositories );
     }
 
     public ArtifactResolutionResult setRepositories( final List<ArtifactRepository> repositories )
@@ -343,14 +354,14 @@ public String toString()
         if ( artifacts != null )
         {
             int i = 1;
-            sb.append( "---------" ).append( "\n" );
-            sb.append( artifacts.size() ).append( "\n" );
+            sb.append( "---------\n" );
+            sb.append( artifacts.size() ).append( '\n' );
             for ( Artifact a : artifacts )
             {
-                sb.append( i ).append( " " ).append( a ).append( "\n" );
+                sb.append( i ).append( ' ' ).append( a ).append( '\n' );
                 i++;
             }
-            sb.append( "---------" ).append( "\n" );
+            sb.append( "---------\n" );
         }
 
         return sb.toString();
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 5651641232..cb7e9cfc9d 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
@@ -99,6 +99,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/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/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 53f84c5092..1ec896635b 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
@@ -388,14 +388,16 @@
     MavenExecutionRequest setUseLegacyLocalRepository( boolean useLegacyLocalRepository );
 
     /**
-     * Controls the {@link Builder} used by Maven by specification of the builder's id.
+     * Controls the {@link org.apache.maven.lifecycle.internal.builder.Builder} used by Maven by specification of the
+     * builder's id.
      *
      * @since 3.2.0
      */
     MavenExecutionRequest setBuilderId( String builderId );
 
     /**
-     * Controls the {@link Builder} used by Maven by specification of the builders id.
+     * Controls the {@link org.apache.maven.lifecycle.internal.builder.Builder} used by Maven by specification of the
+     * builders id.
      *
      * @since 3.2.0
      */
diff --git a/maven-core/src/main/java/org/apache/maven/execution/scope/WeakMojoExecutionListener.java b/maven-core/src/main/java/org/apache/maven/execution/scope/WeakMojoExecutionListener.java
index 94e7c10458..dec48e30e9 100644
--- a/maven-core/src/main/java/org/apache/maven/execution/scope/WeakMojoExecutionListener.java
+++ b/maven-core/src/main/java/org/apache/maven/execution/scope/WeakMojoExecutionListener.java
@@ -25,8 +25,8 @@
 /**
  * Extension point that allows build extensions observe and possibly veto mojo executions.
  * <p>
- * Unlike {@link MojoExecutionListener}, this extension point does not trigger instantiation of the component, hence
- * "weak" class name prefix. Only applies to mojo execution scoped components.
+ * Unlike {@link org.apache.maven.execution.MojoExecutionListener}, this extension point does not trigger instantiation
+ * of the component, hence "weak" class name prefix. Only applies to mojo execution scoped components.
  *
  * @see org.apache.maven.execution.MojoExecutionListener
  * @since 3.1.2
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 0c91cf9419..a0c54442a3 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
@@ -132,16 +132,16 @@ else if ( request.isUpdateSnapshots() )
 
         if ( request.isUseLegacyLocalRepository() )
         {
-            logger.warn( "Disabling enhanced local repository: using legacy is strongly discouraged to ensure"
-                             + " build reproducibility." );
             try
             {
                 session.setLocalRepositoryManager( simpleLocalRepoMgrFactory.newInstance( session, localRepo ) );
+                logger.info( "Disabling enhanced local repository: using legacy is strongly discouraged to ensure"
+                                 + " build reproducibility." );
+
             }
             catch ( NoLocalRepositoryManagerException e )
             {
-
-                logger.warn( "Failed to configure legacy local repository: back to default" );
+                logger.error( "Failed to configure legacy local repository: falling back to default" );
                 session.setLocalRepositoryManager( repoSystem.newLocalRepositoryManager( session, localRepo ) );
             }
         }
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 6f994b3d3f..f9215554cb 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
@@ -62,7 +62,7 @@
 {
 
     @Requirement
-    private LifeCyclePluginAnalyzer lifeCyclePluginAnalyzer;
+    private LifecyclePluginAnalyzer lifecyclePluginAnalyzer;
 
     @Requirement
     private DefaultLifecycles defaultLifeCycles;
@@ -88,21 +88,15 @@ 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.4, please use
+     * {@link LifecyclePluginAnalyzer#getLifecycleModel(org.apache.maven.model.Model)}.
+     */
+    @Deprecated
     public Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging )
+        throws LifecycleMappingNotFoundException
     {
-        return lifeCyclePluginAnalyzer.getPluginsBoundByDefaultToAllLifecycles( packaging );
+        return lifecyclePluginAnalyzer.getPluginsBoundByDefaultToAllLifecycles( packaging );
     }
 
     // USED BY MAVEN HELP PLUGIN
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutionException.java b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutionException.java
index 349576cdc9..89b2cb0288 100644
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutionException.java
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleExecutionException.java
@@ -91,7 +91,7 @@ private static String createMessage( MojoExecution execution, MavenProject proje
             buffer.append( execution.getGoal() );
             buffer.append( " (" );
             buffer.append( execution.getExecutionId() );
-            buffer.append( ")" );
+            buffer.append( ')' );
         }
 
         if ( project != null )
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..5e05a55dfd 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
@@ -38,7 +38,7 @@
 /**
  * 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.4, 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/LifeCyclePluginAnalyzer.java b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleMappingNotFoundException.java
similarity index 59%
rename from maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java
rename to maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleMappingNotFoundException.java
index ed07c1d5e7..983f052482 100644
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/LifeCyclePluginAnalyzer.java
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecycleMappingNotFoundException.java
@@ -9,7 +9,7 @@
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
  *
- *  http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
@@ -19,14 +19,27 @@
  * under the License.
  */
 
-import java.util.Set;
-import org.apache.maven.model.Plugin;
-
 /**
- * @since 3.0
- * @author Kristian Rosenvold
+ * Signals a failure to locate a lifecycle mapping.
+ *
+ * @author Christian Schulte
+ *
+ * @since 3.4
  */
-public interface LifeCyclePluginAnalyzer
+public final class LifecycleMappingNotFoundException extends Exception
 {
-    Set<Plugin> getPluginsBoundByDefaultToAllLifecycles( String packaging );
+
+    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/LifecyclePluginAnalyzer.java b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecyclePluginAnalyzer.java
new file mode 100644
index 0000000000..4b67514656
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/LifecyclePluginAnalyzer.java
@@ -0,0 +1,59 @@
+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.
+ */
+
+import java.util.Set;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+
+/**
+ * @since 3.0
+ * @author Kristian Rosenvold
+ */
+public interface LifecyclePluginAnalyzer
+{
+
+    /**
+     * @deprecated As of Maven 3.4, 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.4
+     */
+    Model getLifecycleModel( Model model )
+        throws LifecycleMappingNotFoundException;
+
+}
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 a72ce8edd4..b4f981d719 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,40 +19,43 @@
  * 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.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 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;
-
 /**
  * @since 3.0
  * @author Benjamin Bentmann
  * @author Jason van Zyl
  * @author jdcasey
  * @author Kristian Rosenvold (extracted class only)
- *         <p/>
- *         NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
+ * <p/>
+ * NOTE: This class is not part of any public api and can be changed or deleted without prior notice.
  */
-@Component( role = LifeCyclePluginAnalyzer.class )
+@Component( role = LifecyclePluginAnalyzer.class )
 public class DefaultLifecyclePluginAnalyzer
-    implements LifeCyclePluginAnalyzer
+    implements LifecyclePluginAnalyzer
 {
 
     @Requirement( role = LifecycleMapping.class )
@@ -68,64 +71,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 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.
-    //
-
+    @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 lifecyle mappings for packaging " + packaging + " from "
-                + Thread.currentThread().getContextClassLoader() );
+            logger.debug( "Looking up lifecyle 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()
@@ -137,6 +193,7 @@ else if ( lifecycle.getDefaultLifecyclePhases() != null )
         Collections.sort( lifecycles, new Comparator<Lifecycle>()
         {
 
+            @Override
             public int compare( Lifecycle l1, Lifecycle l2 )
             {
                 return l1.getId().compareTo( l2.getId() );
@@ -147,30 +204,32 @@ public int compare( Lifecycle l1, Lifecycle l2 )
         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 )
                 {
@@ -184,16 +243,48 @@ 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 );
                 execution.setPriority( i - mojos.size() );
                 execution.getGoals().add( gs.goal );
                 execution.setConfiguration( mojo.getConfiguration() );
-                
+
                 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 );
+                    }
+                }
             }
         }
     }
@@ -247,6 +338,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 2e4c117e14..8524c5e7c7 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
@@ -104,32 +104,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/lifecycle/mapping/Lifecycle.java b/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/Lifecycle.java
index d2b6d6cd8f..ad3e486eb1 100644
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/Lifecycle.java
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/Lifecycle.java
@@ -75,8 +75,6 @@ public void setId( String id )
 
     /**
      * Method setLifecyclePhases
-     *
-     * @param phases
      */
     public void setLifecyclePhases( Map<String, LifecyclePhase> lifecyclePhases )
     {
@@ -106,8 +104,13 @@ public void setLifecyclePhases( Map<String, LifecyclePhase> lifecyclePhases )
     }
 
     @Deprecated
-    public void setPhases( Map<String, LifecyclePhase> phases )
+    public void setPhases( Map<String, String> phases )
     {
-        setLifecyclePhases( phases );
+        Map<String, LifecyclePhase> lphases = new LinkedHashMap<>();
+        for ( Map.Entry<String, String> e: phases.entrySet() )
+        {
+            lphases.put( e.getKey(), new LifecyclePhase( e.getValue() ) );
+        }
+        setLifecyclePhases( lphases );
     }
 }
diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/LifecyclePhase.java b/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/LifecyclePhase.java
index 059f234688..295e6421d4 100644
--- a/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/LifecyclePhase.java
+++ b/maven-core/src/main/java/org/apache/maven/lifecycle/mapping/LifecyclePhase.java
@@ -84,7 +84,7 @@ public String toString()
                 }
                 else
                 {
-                    sb.append( "," );
+                    sb.append( ',' );
                 }
                 sb.append( mojo.getGoal() );
             }
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 1401e30a1e..aa491e71af 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,12 @@
  */
 
 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.lifecycle.LifecyclePluginAnalyzer;
 import org.apache.maven.model.Build;
 import org.apache.maven.model.Model;
 import org.apache.maven.model.Plugin;
@@ -34,9 +33,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 +54,34 @@
     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/MojoExecution.java b/maven-core/src/main/java/org/apache/maven/plugin/MojoExecution.java
index bf053cc5f4..71ece87ed0 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/MojoExecution.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/MojoExecution.java
@@ -175,7 +175,7 @@ public String toString()
         {
             buffer.append( mojoDescriptor.getId() );
         }
-        buffer.append( " {execution: " ).append( executionId ).append( "}" );
+        buffer.append( " {execution: " ).append( executionId ).append( '}' );
         return buffer.toString();
     }
 
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterException.java b/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterException.java
index dcf459e7ba..5f431e0aec 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterException.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterException.java
@@ -151,7 +151,7 @@ else if ( isMap )
 
         if ( StringUtils.isEmpty( expression ) )
         {
-            messageBuffer.append( "." );
+            messageBuffer.append( '.' );
         }
         else
         {
@@ -172,7 +172,7 @@ public String buildDiagnosticMessage()
         MojoDescriptor mojo = getMojoDescriptor();
 
         messageBuffer.append( "One or more required plugin parameters are invalid/missing for \'" )
-            .append( mojo.getPluginDescriptor().getGoalPrefix() ).append( ":" ).append( mojo.getGoal() )
+            .append( mojo.getPluginDescriptor().getGoalPrefix() ).append( ':' ).append( mojo.getGoal() )
             .append( "\'\n" );
 
         int idx = 0;
@@ -184,7 +184,7 @@ public String buildDiagnosticMessage()
 
             decomposeParameterIntoUserInstructions( mojo, param, messageBuffer );
 
-            messageBuffer.append( "\n" );
+            messageBuffer.append( '\n' );
         }
 
         return messageBuffer.toString();
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluator.java b/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluator.java
index 9199ba5a94..a7eeb4e307 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluator.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/PluginParameterExpressionEvaluator.java
@@ -160,7 +160,7 @@ public Object evaluate( String expr, Class<?> type )
             int index = expr.indexOf( "${" );
             if ( index >= 0 )
             {
-                int lastIndex = expr.indexOf( "}", index );
+                int lastIndex = expr.indexOf( '}', index );
                 if ( lastIndex >= 0 )
                 {
                     String retVal = expr.substring( 0, index );
@@ -213,7 +213,7 @@ else if ( expression.startsWith( "session" ) )
         {
             try
             {
-                int pathSeparator = expression.indexOf( "/" );
+                int pathSeparator = expression.indexOf( '/' );
 
                 if ( pathSeparator > 0 )
                 {
@@ -253,7 +253,7 @@ else if ( expression.startsWith( "project" ) || expression.startsWith( "pom" ) )
         {
             try
             {
-                int pathSeparator = expression.indexOf( "/" );
+                int pathSeparator = expression.indexOf( '/' );
 
                 if ( pathSeparator > 0 )
                 {
@@ -285,7 +285,7 @@ else if ( expression.startsWith( "mojo" ) )
         {
             try
             {
-                int pathSeparator = expression.indexOf( "/" );
+                int pathSeparator = expression.indexOf( '/' );
 
                 if ( pathSeparator > 0 )
                 {
@@ -313,7 +313,7 @@ else if ( expression.startsWith( "plugin" ) )
         {
             try
             {
-                int pathSeparator = expression.indexOf( "/" );
+                int pathSeparator = expression.indexOf( '/' );
 
                 PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
 
@@ -342,7 +342,7 @@ else if ( expression.startsWith( "settings" ) )
         {
             try
             {
-                int pathSeparator = expression.indexOf( "/" );
+                int pathSeparator = expression.indexOf( '/' );
 
                 if ( pathSeparator > 0 )
                 {
@@ -368,7 +368,7 @@ else if ( "basedir".equals( expression ) )
         }
         else if ( expression.startsWith( "basedir" ) )
         {
-            int pathSeparator = expression.indexOf( "/" );
+            int pathSeparator = expression.indexOf( '/' );
 
             if ( pathSeparator > 0 )
             {
@@ -447,7 +447,7 @@ private static boolean isTypeCompatible( Class<?> type, Object value )
 
     private String stripTokens( String expr )
     {
-        if ( expr.startsWith( "${" ) && ( expr.indexOf( "}" ) == expr.length() - 1 ) )
+        if ( expr.startsWith( "${" ) && ( expr.indexOf( '}' ) == expr.length() - 1 ) )
         {
             expr = expr.substring( 2, expr.length() - 1 );
         }
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 b87994e22a..bad1454c6c 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
@@ -458,7 +458,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/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/DefaultMavenProjectHelper.java b/maven-core/src/main/java/org/apache/maven/project/DefaultMavenProjectHelper.java
index 2cce9f6ac5..54c15bb96e 100644
--- a/maven-core/src/main/java/org/apache/maven/project/DefaultMavenProjectHelper.java
+++ b/maven-core/src/main/java/org/apache/maven/project/DefaultMavenProjectHelper.java
@@ -91,16 +91,15 @@ public void attachArtifact( MavenProject project, File artifactFile, String arti
         attachArtifact( project, artifact );
     }
 
-    /**
-     * Add an attached artifact or replace the file for an existing artifact.
-     *
-     * @see MavenProject#addAttachedArtifact(org.apache.maven.artifact.Artifact)
-     * @param project project reference.
-     * @param artifact artifact to add or replace.
-     */
     public void attachArtifact( MavenProject project, Artifact artifact )
     {
+        final int size = project.getAttachedArtifacts().size();
         project.addAttachedArtifact( artifact );
+
+        if ( project.getAttachedArtifacts().size() == size && this.getLogger().isInfoEnabled() )
+        {
+            this.getLogger().info( String.format( "Replaced artifact %s.", artifact ) );
+        }
     }
 
     public void addResource( MavenProject project, String resourceDirectory, List<String> includes,
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 9d51a6d3a2..fb15c87921 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
@@ -43,7 +43,6 @@
 import org.apache.maven.model.DeploymentRepository;
 import org.apache.maven.model.Extension;
 import org.apache.maven.model.Model;
-import org.apache.maven.model.Parent;
 import org.apache.maven.model.Plugin;
 import org.apache.maven.model.Profile;
 import org.apache.maven.model.ReportPlugin;
@@ -73,9 +72,6 @@
 import org.eclipse.aether.repository.WorkspaceRepository;
 import org.eclipse.aether.resolution.ArtifactRequest;
 import org.eclipse.aether.resolution.ArtifactResult;
-import org.eclipse.aether.resolution.VersionRangeRequest;
-import org.eclipse.aether.resolution.VersionRangeResolutionException;
-import org.eclipse.aether.resolution.VersionRangeResult;
 
 /**
  */
@@ -298,44 +294,6 @@ public ProjectBuildingResult build( Artifact artifact, boolean allowStubModel, P
 
         boolean localProject;
 
-        if ( request.isResolveVersionRanges() )
-        {
-            VersionRangeRequest versionRangeRequest = new VersionRangeRequest( pomArtifact, config.repositories, null );
-
-            try
-            {
-                VersionRangeResult versionRangeResult =
-                    repoSystem.resolveVersionRange( config.session, versionRangeRequest );
-
-                if ( versionRangeResult.getHighestVersion() == null )
-                {
-                    throw new ProjectBuildingException(
-                        artifact.getId(), "Error resolving project artifact: No versions matched the requested range",
-                        (Throwable) null );
-
-                }
-
-                if ( versionRangeResult.getVersionConstraint() != null
-                         && versionRangeResult.getVersionConstraint().getRange() != null
-                         && versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null )
-                {
-                    throw new ProjectBuildingException(
-                        artifact.getId(),
-                        "Error resolving project artifact: The requested version range does not specify an upper bound",
-                        (Throwable) null );
-
-                }
-
-                pomArtifact = pomArtifact.setVersion( versionRangeResult.getHighestVersion().toString() );
-            }
-            catch ( VersionRangeResolutionException e )
-            {
-                throw new ProjectBuildingException(
-                    artifact.getId(), "Error resolving project artifact: " + e.getMessage(), e );
-
-            }
-        }
-
         try
         {
             ArtifactRequest pomRequest = new ArtifactRequest();
@@ -654,11 +612,32 @@ private void initProject( MavenProject project, Map<String, MavenProject> projec
         project.setModel( model );
         project.setOriginalModel( result.getRawModel() );
         project.setFile( model.getPomFile() );
-        Parent p = model.getParent();
-        if ( p != null )
+
+        Model parentModel = null;
+        if ( !result.getModelIds().get( 1 ).isEmpty() )
+        {
+            // Note: The parent model already got resolved by the ModelBuilder based on model.getParent().
+            parentModel = result.getRawModel( result.getModelIds().get( 1 ) );
+        }
+
+        if ( parentModel != null )
         {
-            project.setParentArtifact( repositorySystem.createProjectArtifact( p.getGroupId(), p.getArtifactId(),
-                                                                               p.getVersion() ) );
+            String parentGroupId = parentModel.getGroupId();
+            if ( parentGroupId == null && parentModel.getParent() != null )
+            {
+                parentGroupId = parentModel.getParent().getGroupId();
+            }
+
+            String parentVersion = parentModel.getVersion();
+            if ( parentVersion == null && parentModel.getParent() != null )
+            {
+                parentVersion = parentModel.getParent().getVersion();
+            }
+
+            project.setParentArtifact( repositorySystem.createProjectArtifact( parentGroupId,
+                                                                               parentModel.getArtifactId(),
+                                                                               parentVersion ) );
+
             // org.apache.maven.its.mng4834:parent:0.1
             String parentModelId = result.getModelIds().get( 1 );
             File parentPomFile = result.getRawModel( parentModelId ).getPomFile();
@@ -807,7 +786,7 @@ private void initProject( MavenProject project, Map<String, MavenProject> projec
             List<Dependency> deps;
             DependencyManagement dependencyManagement = project.getDependencyManagement();
             if ( ( dependencyManagement != null ) && ( ( deps = dependencyManagement.getDependencies() ) != null )
-                && ( deps.size() > 0 ) )
+                     && ( deps.size() > 0 ) )
             {
                 map = new HashMap<>();
                 for ( Dependency d : dependencyManagement.getDependencies() )
@@ -819,6 +798,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 f439240bf4..97eb2762c5 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
@@ -62,6 +62,7 @@
 
     private boolean resolveDependencies;
 
+    @Deprecated
     private boolean resolveVersionRanges;
 
     private RepositoryMerging repositoryMerging = RepositoryMerging.POM_DOMINANT;
@@ -221,14 +222,24 @@ public boolean isResolveDependencies()
         return resolveDependencies;
     }
 
-    /** @since 3.2.2 */
+    /**
+     * @since 3.2.2
+     * @deprecated This got added when implementing MNG-2199 and is no longer used.
+     * Commit 6cf9320942c34bc68205425ab696b1712ace9ba4 updated the way 'MavenProject' objects are initialized.
+     */
+    @Deprecated
     public ProjectBuildingRequest setResolveVersionRanges( boolean value )
     {
         this.resolveVersionRanges = value;
         return this;
     }
 
-    /** @since 3.2.2 */
+    /**
+     * @since 3.2.2
+     * @deprecated This got added when implementing MNG-2199 and is no longer used.
+     * Commit 6cf9320942c34bc68205425ab696b1712ace9ba4 updated the way 'MavenProject' objects are initialized.
+     */
+    @Deprecated
     public boolean isResolveVersionRanges()
     {
         return this.resolveVersionRanges;
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 50c9e3560d..529a63cf85 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
@@ -263,7 +263,7 @@ public boolean visitEnter( DependencyNode node )
                 {
                     buffer.append( " (scope managed from " ).append( premanagedScope );
                     appendManagementSource( buffer, art, "scope" );
-                    buffer.append( ")" );
+                    buffer.append( ')' );
                 }
 
                 String premanagedVersion = DependencyManagerUtils.getPremanagedVersion( node );
@@ -271,7 +271,15 @@ public boolean visitEnter( DependencyNode node )
                 {
                     buffer.append( " (version managed from " ).append( premanagedVersion );
                     appendManagementSource( buffer, art, "version" );
-                    buffer.append( ")" );
+                    buffer.append( ')' );
+                }
+
+                Boolean premanagedOptional = DependencyManagerUtils.getPremanagedOptional( node );
+                if ( premanagedOptional != null && !premanagedOptional.equals( dep.getOptional() ) )
+                {
+                    buffer.append( " (optionality managed from " ).append( premanagedOptional );
+                    appendManagementSource( buffer, art, "optional" );
+                    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 9d66eb0eed..85bd001a8f 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
@@ -49,7 +49,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 952622ffa2..d7d6ce8e85 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()
@@ -909,19 +909,38 @@ public void setInjectedProfileIds( String source, List<String> injectedProfileId
     }
 
     /**
-     * Add or replace an artifact. This method is now deprecated. Use the @{MavenProjectHelper} to attach artifacts to a
-     * project. In spite of the 'throws' declaration on this API, this method has never thrown an exception since Maven
-     * 3.0.x. Historically, it logged and ignored a second addition of the same g/a/v/c/t. Now it replaces the file for
-     * the artifact, so that plugins (e.g. shade) can change the pathname of the file for a particular set of
-     * coordinates.
+     * Adds or replaces an artifact.
      *
-     * @param artifact the artifact to add or replace.
-     * @throws DuplicateArtifactAttachmentException
+     * @param artifact The artifact to add or replace.
+     *
+     * @deprecated Please use {@link MavenProjectHelper}
+     * @see "https://issues.apache.org/jira/browse/MNG-5868"
+     * @see "https://issues.apache.org/jira/browse/MNG-5387"
+     * @see "https://issues.apache.org/jira/browse/MNG-4013"
+     * @see "https://issues.apache.org/jira/browse/MNG-3119"
      */
+    @Deprecated
     public void addAttachedArtifact( Artifact artifact )
-        throws DuplicateArtifactAttachmentException
     {
-        getAttachedArtifacts().add( artifact );
+        getAttachedArtifacts();
+        assert this.attachedArtifacts != null : "Unexpected missing attached artifacts.";
+
+        boolean replaced = false;
+        for ( int i = 0, s0 = this.attachedArtifacts.size(); i < s0; i++ )
+        {
+            final Artifact a = this.attachedArtifacts.get( i );
+
+            if ( a.equals( artifact ) )
+            {
+                this.attachedArtifacts.set( i, artifact );
+                replaced = true;
+            }
+        }
+
+        if ( !replaced )
+        {
+            this.attachedArtifacts.add( artifact );
+        }
     }
 
     public List<Artifact> getAttachedArtifacts()
@@ -930,7 +949,7 @@ public void addAttachedArtifact( Artifact artifact )
         {
             attachedArtifacts = new ArrayList<>();
         }
-        return attachedArtifacts;
+        return Collections.unmodifiableList( attachedArtifacts );
     }
 
     public Xpp3Dom getGoalConfiguration( String pluginGroupId, String pluginArtifactId, String executionId,
@@ -1079,7 +1098,7 @@ public int hashCode()
         }
         else
         {
-            return build.getExtensions();
+            return Collections.unmodifiableList( build.getExtensions() );
         }
     }
 
@@ -1133,9 +1152,9 @@ public String toString()
         StringBuilder sb = new StringBuilder( 128 );
         sb.append( "MavenProject: " );
         sb.append( getGroupId() );
-        sb.append( ":" );
+        sb.append( ':' );
         sb.append( getArtifactId() );
-        sb.append( ":" );
+        sb.append( ':' );
         sb.append( getVersion() );
         sb.append( " @ " );
 
@@ -1605,7 +1624,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();
 
@@ -1619,7 +1638,7 @@ public void addScriptSourceRoot( String path )
                 list.add( dependency );
             }
         }
-        return list;
+        return Collections.unmodifiableList( list );
     }
 
     @Deprecated
@@ -1663,7 +1682,7 @@ public void addScriptSourceRoot( String path )
 
             list.add( dependency );
         }
-        return list;
+        return Collections.unmodifiableList( list );
     }
 
     @Deprecated // used by the Maven ITs
@@ -1678,7 +1697,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() ) )
@@ -1695,7 +1714,7 @@ public void addScriptSourceRoot( String path )
                 list.add( dependency );
             }
         }
-        return list;
+        return Collections.unmodifiableList( list );
     }
 
     @Deprecated
@@ -1791,7 +1810,7 @@ public void addScriptSourceRoot( String path )
                 list.add( dependency );
             }
         }
-        return list;
+        return Collections.unmodifiableList( list );
     }
 
     @Deprecated
@@ -1863,8 +1882,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/ProjectBuildingRequest.java b/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingRequest.java
index 0380278bf9..17a53b1613 100644
--- a/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingRequest.java
+++ b/maven-core/src/main/java/org/apache/maven/project/ProjectBuildingRequest.java
@@ -168,10 +168,20 @@
      */
     RepositoryMerging getRepositoryMerging();
 
-    /** @since 3.2.2 */
+    /**
+     * @since 3.2.2
+     * @deprecated This got added when implementing MNG-2199 and is no longer used.
+     * Commit 6cf9320942c34bc68205425ab696b1712ace9ba4 updated the way 'MavenProject' objects are initialized.
+     */
+    @Deprecated
     boolean isResolveVersionRanges();
 
-    /** @since 3.2.2 */
+    /**
+     * @since 3.2.2
+     * @deprecated This got added when implementing MNG-2199 and is no longer used.
+     * Commit 6cf9320942c34bc68205425ab696b1712ace9ba4 updated the way 'MavenProject' objects are initialized.
+     */
+    @Deprecated
     ProjectBuildingRequest setResolveVersionRanges( boolean value );
 
     /**
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 184be70f51..f11e77db47 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
@@ -26,6 +26,7 @@
 import java.util.List;
 import java.util.Set;
 
+import org.apache.maven.model.Dependency;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
 
@@ -203,24 +204,26 @@ public ModelSource resolveModel( String groupId, String artifactId, String versi
         return new FileModelSource( pomFile );
     }
 
-    public ModelSource resolveModel( Parent parent )
+    @Override
+    public ModelSource resolveModel( final Parent parent )
         throws UnresolvableModelException
     {
-        Artifact artifact = new DefaultArtifact( parent.getGroupId(), parent.getArtifactId(), "", "pom",
-                                                 parent.getVersion() );
-
-        VersionRangeRequest versionRangeRequest = new VersionRangeRequest( artifact, repositories, context );
-        versionRangeRequest.setTrace( trace );
-
         try
         {
-            VersionRangeResult versionRangeResult = resolver.resolveVersionRange( session, versionRangeRequest );
+            final Artifact artifact = new DefaultArtifact( parent.getGroupId(), parent.getArtifactId(), "", "pom",
+                                                           parent.getVersion() );
+
+            final VersionRangeRequest versionRangeRequest = new VersionRangeRequest( artifact, repositories, context );
+            versionRangeRequest.setTrace( trace );
+
+            final VersionRangeResult versionRangeResult = resolver.resolveVersionRange( session, versionRangeRequest );
 
             if ( versionRangeResult.getHighestVersion() == null )
             {
-                throw new UnresolvableModelException( "No versions matched the requested range '" + parent.getVersion()
-                                                          + "'", parent.getGroupId(), parent.getArtifactId(),
-                                                      parent.getVersion() );
+                throw new UnresolvableModelException(
+                    String.format( "No versions matched the requested parent version range '%s'",
+                                   parent.getVersion() ),
+                    parent.getGroupId(), parent.getArtifactId(), parent.getVersion() );
 
             }
 
@@ -228,21 +231,68 @@ public ModelSource resolveModel( Parent parent )
                      && versionRangeResult.getVersionConstraint().getRange() != null
                      && versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null )
             {
-                throw new UnresolvableModelException( "The requested version range '" + parent.getVersion()
-                                                          + "' does not specify an upper bound", parent.getGroupId(),
-                                                      parent.getArtifactId(), parent.getVersion() );
+                throw new UnresolvableModelException(
+                    String.format( "The requested parent version range '%s' does not specify an upper bound",
+                                   parent.getVersion() ),
+                    parent.getGroupId(), parent.getArtifactId(), parent.getVersion() );
 
             }
 
             parent.setVersion( versionRangeResult.getHighestVersion().toString() );
+
+            return resolveModel( parent.getGroupId(), parent.getArtifactId(), parent.getVersion() );
         }
-        catch ( VersionRangeResolutionException e )
+        catch ( final VersionRangeResolutionException e )
         {
             throw new UnresolvableModelException( e.getMessage(), parent.getGroupId(), parent.getArtifactId(),
                                                   parent.getVersion(), e );
 
         }
+    }
+
+    @Override
+    public ModelSource resolveModel( final Dependency dependency )
+        throws UnresolvableModelException
+    {
+        try
+        {
+            final Artifact artifact = new DefaultArtifact( dependency.getGroupId(), dependency.getArtifactId(), "",
+                                                           "pom", dependency.getVersion() );
+
+            final VersionRangeRequest versionRangeRequest = new VersionRangeRequest( artifact, repositories, context );
+            versionRangeRequest.setTrace( trace );
+
+            final VersionRangeResult versionRangeResult = resolver.resolveVersionRange( session, versionRangeRequest );
+
+            if ( versionRangeResult.getHighestVersion() == null )
+            {
+                throw new UnresolvableModelException(
+                    String.format( "No versions matched the requested dependency version range '%s'",
+                                   dependency.getVersion() ),
+                    dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() );
+
+            }
+
+            if ( versionRangeResult.getVersionConstraint() != null
+                     && versionRangeResult.getVersionConstraint().getRange() != null
+                     && versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null )
+            {
+                throw new UnresolvableModelException(
+                    String.format( "The requested dependency version range '%s' does not specify an upper bound",
+                                   dependency.getVersion() ),
+                    dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() );
+
+            }
+
+            dependency.setVersion( versionRangeResult.getHighestVersion().toString() );
+
+            return resolveModel( dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() );
+        }
+        catch ( VersionRangeResolutionException e )
+        {
+            throw new UnresolvableModelException( e.getMessage(), dependency.getGroupId(), dependency.getArtifactId(),
+                                                  dependency.getVersion(), e );
 
-        return resolveModel( parent.getGroupId(), parent.getArtifactId(), parent.getVersion() );
+        }
     }
 }
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 1d4a2a313b..7113dd31e2 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
@@ -56,7 +56,10 @@ public MavenProject getProject()
     public List<Dependency> getManagedDependencies()
     {
         DependencyManagement depMngt = project.getDependencyManagement();
-        return ( depMngt != null ) ? depMngt.getDependencies() : Collections.<Dependency>emptyList();
+        return ( depMngt != null )
+                   ? Collections.unmodifiableList( depMngt.getDependencies() )
+                   : Collections.<Dependency>emptyList();
+
     }
 
     static class PomArtifactHandler
diff --git a/maven-core/src/main/java/org/apache/maven/properties/internal/SystemProperties.java b/maven-core/src/main/java/org/apache/maven/properties/internal/SystemProperties.java
index aa5fed9d4d..0372558198 100644
--- a/maven-core/src/main/java/org/apache/maven/properties/internal/SystemProperties.java
+++ b/maven-core/src/main/java/org/apache/maven/properties/internal/SystemProperties.java
@@ -29,7 +29,7 @@
     /**
      * Thread-safe System.properties copy implementation.
      *
-     * @see https://issues.apache.org/jira/browse/MNG-5670
+     * @see "https://issues.apache.org/jira/browse/MNG-5670"
      */
     public static void addSystemProperties( Properties props )
     {
diff --git a/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferEvent.java b/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferEvent.java
index 09729ddd2c..0d31eb2d06 100644
--- a/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferEvent.java
+++ b/maven-core/src/main/java/org/apache/maven/repository/ArtifactTransferEvent.java
@@ -242,7 +242,7 @@ public void setDataLength( int dataLength )
 
     public String toString()
     {
-        StringBuilder sb = new StringBuilder();
+        StringBuilder sb = new StringBuilder( 64 );
 
         sb.append( "TransferEvent[" );
 
@@ -259,7 +259,7 @@ public String toString()
                 break;
         }
 
-        sb.append( "|" );
+        sb.append( '|' );
         switch ( this.getEventType() )
         {
             case TRANSFER_COMPLETED:
@@ -282,9 +282,9 @@ public String toString()
                 break;
         }
 
-        sb.append( "|" );
-        sb.append( this.getLocalFile() ).append( "|" );
-        sb.append( "]" );
+        sb.append( '|' );
+        sb.append( this.getLocalFile() ).append( '|' );
+        sb.append( ']' );
 
         return sb.toString();
     }
diff --git a/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/AbstractArtifactMetadata.java b/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/AbstractArtifactMetadata.java
index 352e5bbb1c..def20e4726 100644
--- a/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/AbstractArtifactMetadata.java
+++ b/maven-core/src/main/java/org/apache/maven/repository/legacy/metadata/AbstractArtifactMetadata.java
@@ -53,7 +53,7 @@ public String getArtifactId()
 
     public String extendedToString()
     {
-        StringBuilder buffer = new StringBuilder();
+        StringBuilder buffer = new StringBuilder( 256 );
 
         buffer.append( "\nArtifact Metadata\n--------------------------" );
         buffer.append( "\nGroupId: " ).append( getGroupId() );
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/main/java/org/apache/maven/toolchain/ToolchainManager.java b/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainManager.java
index 8eddac54c5..bc0a91dd4c 100644
--- a/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainManager.java
+++ b/maven-core/src/main/java/org/apache/maven/toolchain/ToolchainManager.java
@@ -44,8 +44,8 @@
      * <code>maven-toolchains-plugin</code> contains the configuration to select the appropriate
      * toolchain and is executed at the beginning of the build.
      *
-     * @param session the Maven session, must not be {@code null}
      * @param type the type, must not be {@code null}
+     * @param context the Maven session, must not be {@code null}
      * @return the toolchain selected by <code>maven-toolchains-plugin</code>
      */
     Toolchain getToolchainFromBuildContext( String type, MavenSession context );
diff --git a/maven-core/src/main/resources/META-INF/plexus/components.xml b/maven-core/src/main/resources/META-INF/plexus/components.xml
index 3f099cb167..0beb57e7e9 100644
--- a/maven-core/src/main/resources/META-INF/plexus/components.xml
+++ b/maven-core/src/main/resources/META-INF/plexus/components.xml
@@ -78,7 +78,7 @@ under the License.
         </phases>
         <default-phases>
           <clean>
-            org.apache.maven.plugins:maven-clean-plugin:2.5:clean
+            org.apache.maven.plugins:maven-clean-plugin:3.0.0:clean
           </clean>
         </default-phases>
         <!-- END SNIPPET: clean -->
@@ -101,10 +101,10 @@ under the License.
         </phases>
         <default-phases>
           <site>
-            org.apache.maven.plugins:maven-site-plugin:3.3:site
+            org.apache.maven.plugins:maven-site-plugin:3.5:site
           </site>
           <site-deploy>
-            org.apache.maven.plugins:maven-site-plugin:3.3:deploy
+            org.apache.maven.plugins:maven-site-plugin:3.5:deploy
           </site-deploy>
         </default-phases>
         <!-- END SNIPPET: site -->
diff --git a/maven-core/src/main/resources/META-INF/plexus/default-bindings.xml b/maven-core/src/main/resources/META-INF/plexus/default-bindings.xml
index 4a303db572..f7ebe8d1c8 100644
--- a/maven-core/src/main/resources/META-INF/plexus/default-bindings.xml
+++ b/maven-core/src/main/resources/META-INF/plexus/default-bindings.xml
@@ -41,10 +41,10 @@ Mappings to default lifecycle, specific for each packaging.
             <!-- START SNIPPET: pom-lifecycle -->
             <phases>
               <install>
-                org.apache.maven.plugins:maven-install-plugin:2.4:install
+                org.apache.maven.plugins:maven-install-plugin:2.5.2:install
               </install>
               <deploy>
-                org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+                org.apache.maven.plugins:maven-deploy-plugin:2.8.2:deploy
               </deploy>
             </phases>
             <!-- END SNIPPET: pom-lifecycle -->
@@ -67,28 +67,28 @@ Mappings to default lifecycle, specific for each packaging.
             <!-- START SNIPPET: jar-lifecycle -->
             <phases>
               <process-resources>
-                org.apache.maven.plugins:maven-resources-plugin:2.6:resources
+                org.apache.maven.plugins:maven-resources-plugin:2.7:resources
               </process-resources>
               <compile>
-                org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
+                org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile
               </compile>
               <process-test-resources>
-                org.apache.maven.plugins:maven-resources-plugin:2.6:testResources
+                org.apache.maven.plugins:maven-resources-plugin:2.7:testResources
               </process-test-resources>
               <test-compile>
-                org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile
+                org.apache.maven.plugins:maven-compiler-plugin:3.5.1:testCompile
               </test-compile>
               <test>
-                org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
+                org.apache.maven.plugins:maven-surefire-plugin:2.19.1:test
               </test>
               <package>
-                org.apache.maven.plugins:maven-jar-plugin:2.4:jar
+                org.apache.maven.plugins:maven-jar-plugin:2.6:jar
               </package>
               <install>
-                org.apache.maven.plugins:maven-install-plugin:2.4:install
+                org.apache.maven.plugins:maven-install-plugin:2.5.2:install
               </install>
               <deploy>
-                org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+                org.apache.maven.plugins:maven-deploy-plugin:2.8.2:deploy
               </deploy>
             </phases>
             <!-- END SNIPPET: jar-lifecycle -->
@@ -111,28 +111,28 @@ Mappings to default lifecycle, specific for each packaging.
             <!-- START SNIPPET: ejb-lifecycle -->
             <phases>
               <process-resources>
-                org.apache.maven.plugins:maven-resources-plugin:2.6:resources
+                org.apache.maven.plugins:maven-resources-plugin:2.7:resources
               </process-resources>
               <compile>
-                org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
+                org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile
               </compile>
               <process-test-resources>
-                org.apache.maven.plugins:maven-resources-plugin:2.6:testResources
+                org.apache.maven.plugins:maven-resources-plugin:2.7:testResources
               </process-test-resources>
               <test-compile>
-                org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile
+                org.apache.maven.plugins:maven-compiler-plugin:3.5.1:testCompile
               </test-compile>
               <test>
-                org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
+                org.apache.maven.plugins:maven-surefire-plugin:2.19.1:test
               </test>
               <package>
-                org.apache.maven.plugins:maven-ejb-plugin:2.3:ejb
+                org.apache.maven.plugins:maven-ejb-plugin:2.5.1:ejb
               </package>
               <install>
-                org.apache.maven.plugins:maven-install-plugin:2.4:install
+                org.apache.maven.plugins:maven-install-plugin:2.5.2:install
               </install>
               <deploy>
-                org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+                org.apache.maven.plugins:maven-deploy-plugin:2.8.2:deploy
               </deploy>
             </phases>
             <!-- END SNIPPET: ejb-lifecycle -->
@@ -155,32 +155,32 @@ Mappings to default lifecycle, specific for each packaging.
             <!-- START SNIPPET: maven-plugin-lifecycle -->
             <phases>
               <process-resources>
-                org.apache.maven.plugins:maven-resources-plugin:2.6:resources
+                org.apache.maven.plugins:maven-resources-plugin:2.7:resources
               </process-resources>
               <compile>
-                org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
+                org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile
               </compile>
               <process-classes>
-                org.apache.maven.plugins:maven-plugin-plugin:3.2:descriptor
+                org.apache.maven.plugins:maven-plugin-plugin:3.3:descriptor
               </process-classes>
               <process-test-resources>
-                org.apache.maven.plugins:maven-resources-plugin:2.6:testResources
+                org.apache.maven.plugins:maven-resources-plugin:2.7:testResources
               </process-test-resources>
               <test-compile>
-                org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile
+                org.apache.maven.plugins:maven-compiler-plugin:3.5.1:testCompile
               </test-compile>
               <test>
-                org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
+                org.apache.maven.plugins:maven-surefire-plugin:2.19.1:test
               </test>
               <package>
-                org.apache.maven.plugins:maven-jar-plugin:2.4:jar,
-                org.apache.maven.plugins:maven-plugin-plugin:3.2:addPluginArtifactMetadata
+                org.apache.maven.plugins:maven-jar-plugin:2.6:jar,
+                org.apache.maven.plugins:maven-plugin-plugin:3.3:addPluginArtifactMetadata
               </package>
               <install>
-                org.apache.maven.plugins:maven-install-plugin:2.4:install
+                org.apache.maven.plugins:maven-install-plugin:2.5.2:install
               </install>
               <deploy>
-                org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+                org.apache.maven.plugins:maven-deploy-plugin:2.8.2:deploy
               </deploy>
             </phases>
             <!-- END SNIPPET: maven-plugin-lifecycle -->
@@ -203,28 +203,28 @@ Mappings to default lifecycle, specific for each packaging.
             <!-- START SNIPPET: war-lifecycle -->
             <phases>
               <process-resources>
-                org.apache.maven.plugins:maven-resources-plugin:2.6:resources
+                org.apache.maven.plugins:maven-resources-plugin:2.7:resources
               </process-resources>
               <compile>
-                org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
+                org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile
               </compile>
               <process-test-resources>
-                org.apache.maven.plugins:maven-resources-plugin:2.6:testResources
+                org.apache.maven.plugins:maven-resources-plugin:2.7:testResources
               </process-test-resources>
               <test-compile>
-                org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile
+                org.apache.maven.plugins:maven-compiler-plugin:3.5.1:testCompile
               </test-compile>
               <test>
-                org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
+                org.apache.maven.plugins:maven-surefire-plugin:2.19.1:test
               </test>
               <package>
-                org.apache.maven.plugins:maven-war-plugin:2.2:war
+                org.apache.maven.plugins:maven-war-plugin:2.6:war
               </package>
               <install>
-                org.apache.maven.plugins:maven-install-plugin:2.4:install
+                org.apache.maven.plugins:maven-install-plugin:2.5.2:install
               </install>
               <deploy>
-                org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+                org.apache.maven.plugins:maven-deploy-plugin:2.8.2:deploy
               </deploy>
             </phases>
             <!-- END SNIPPET: war-lifecycle -->
@@ -247,19 +247,19 @@ Mappings to default lifecycle, specific for each packaging.
             <!-- START SNIPPET: ear-lifecycle -->
             <phases>
               <generate-resources>
-                org.apache.maven.plugins:maven-ear-plugin:2.8:generate-application-xml
+                org.apache.maven.plugins:maven-ear-plugin:2.9.1:generate-application-xml
               </generate-resources>
               <process-resources>
-                org.apache.maven.plugins:maven-resources-plugin:2.6:resources
+                org.apache.maven.plugins:maven-resources-plugin:2.7:resources
               </process-resources>
               <package>
-                org.apache.maven.plugins:maven-ear-plugin:2.8:ear
+                org.apache.maven.plugins:maven-ear-plugin:2.9.1:ear
               </package>
               <install>
-                org.apache.maven.plugins:maven-install-plugin:2.4:install
+                org.apache.maven.plugins:maven-install-plugin:2.5.2:install
               </install>
               <deploy>
-                org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+                org.apache.maven.plugins:maven-deploy-plugin:2.8.2:deploy
               </deploy>
             </phases>
             <!-- END SNIPPET: ear-lifecycle -->
@@ -282,28 +282,28 @@ Mappings to default lifecycle, specific for each packaging.
             <!-- START SNIPPET: rar-lifecycle -->
             <phases>
               <process-resources>
-                org.apache.maven.plugins:maven-resources-plugin:2.6:resources
+                org.apache.maven.plugins:maven-resources-plugin:2.7:resources
               </process-resources>
               <compile>
-                org.apache.maven.plugins:maven-compiler-plugin:3.1:compile
+                org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile
               </compile>
               <process-test-resources>
-                org.apache.maven.plugins:maven-resources-plugin:2.6:testResources
+                org.apache.maven.plugins:maven-resources-plugin:2.7:testResources
               </process-test-resources>
               <test-compile>
-                org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile
+                org.apache.maven.plugins:maven-compiler-plugin:3.5.1:testCompile
               </test-compile>
               <test>
-                org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
+                org.apache.maven.plugins:maven-surefire-plugin:2.19.1:test
               </test>
               <package>
-                org.apache.maven.plugins:maven-rar-plugin:2.2:rar
+                org.apache.maven.plugins:maven-rar-plugin:2.4:rar
               </package>
               <install>
-                org.apache.maven.plugins:maven-install-plugin:2.4:install
+                org.apache.maven.plugins:maven-install-plugin:2.5.2:install
               </install>
               <deploy>
-                org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
+                org.apache.maven.plugins:maven-deploy-plugin:2.8.2:deploy
               </deploy>
             </phases>
             <!-- END SNIPPET: rar-lifecycle -->
diff --git a/maven-core/src/site/apt/configuration-management.apt b/maven-core/src/site/apt/configuration-management.apt
index 4af0f0b1c5..ffec0e1091 100644
--- a/maven-core/src/site/apt/configuration-management.apt
+++ b/maven-core/src/site/apt/configuration-management.apt
@@ -120,7 +120,7 @@ Unified source directory
  problems with the current solution are:
  1. information is duplicate. once in POM's dependencies and once in the
  maven.multiproject.includes property.
- 2. it works without problems only for projects with relative paths, eg. from
+ 2. it works without problems only for projects with relative paths, e.g., from
  one CVS repository.. for projects from multiple SCM repositories it's harder
  to maintain the same relative links on all developer computers.
  not sure the unified source directory structure addresses this issue.
diff --git a/maven-core/src/site/apt/default-bindings.apt.vm b/maven-core/src/site/apt/default-bindings.apt.vm
index 02d6c4a93e..50c4654b2e 100644
--- a/maven-core/src/site/apt/default-bindings.apt.vm
+++ b/maven-core/src/site/apt/default-bindings.apt.vm
@@ -42,10 +42,6 @@ Plugin Bindings for <<<default>>> Lifecycle Reference
 
 %{snippet|id=ejb-lifecycle|file=${project.basedir}/src/main/resources/META-INF/plexus/default-bindings.xml}
 
-* Plugin bindings for <<<ejb3>>> packaging
-
-%{snippet|id=ejb3-lifecycle|file=${project.basedir}/src/main/resources/META-INF/plexus/default-bindings.xml}
-
 * Plugin bindings for <<<maven-plugin>>> packaging
 
 %{snippet|id=maven-plugin-lifecycle|file=${project.basedir}/src/main/resources/META-INF/plexus/default-bindings.xml}
@@ -62,6 +58,3 @@ Plugin Bindings for <<<default>>> Lifecycle Reference
 
 %{snippet|id=rar-lifecycle|file=${project.basedir}/src/main/resources/META-INF/plexus/default-bindings.xml}
 
-* Plugin bindings for <<<par>>> packaging
-
-%{snippet|id=par-lifecycle|file=${project.basedir}/src/main/resources/META-INF/plexus/default-bindings.xml}
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..21791da5ec 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;
 
@@ -30,8 +32,9 @@
  * @author Benjamin Bentmann
  */
 public class EmptyLifecyclePluginAnalyzer
-    implements LifeCyclePluginAnalyzer
+    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/LifecycleExecutorSubModulesTest.java b/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorSubModulesTest.java
index 01ebeac08b..73a4f7e1ad 100644
--- a/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorSubModulesTest.java
+++ b/maven-core/src/test/java/org/apache/maven/lifecycle/LifecycleExecutorSubModulesTest.java
@@ -50,7 +50,7 @@
     private LifecycleExecutionPlanCalculator lifeCycleExecutionPlanCalculator;
 
     @Requirement
-    private LifeCyclePluginAnalyzer lifeCyclePluginAnalyzer;
+    private LifecyclePluginAnalyzer lifeCyclePluginAnalyzer;
 
     @Requirement
     private LifecycleTaskSegmentCalculator lifeCycleTaskSegmentCalculator;
@@ -65,7 +65,7 @@ protected void setUp()
         lifeCycleBuilder = lookup( LifecycleModuleBuilder.class );
         lifeCycleDependencyResolver = lookup( LifecycleDependencyResolver.class );
         lifeCycleExecutionPlanCalculator = lookup( LifecycleExecutionPlanCalculator.class );
-        lifeCyclePluginAnalyzer = lookup( LifeCyclePluginAnalyzer.class );
+        lifeCyclePluginAnalyzer = lookup( LifecyclePluginAnalyzer.class );
         lifeCycleTaskSegmentCalculator = lookup( LifecycleTaskSegmentCalculator.class );
         lookup( ExceptionHandler.class );
     }
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
similarity index 73%
rename from maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifeCyclePluginAnalyzerStub.java
rename to maven-core/src/test/java/org/apache/maven/lifecycle/internal/stub/LifecyclePluginAnalyzerStub.java
index b067e244a9..5a1d9db6ba 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.lifecycle.LifecyclePluginAnalyzer;
+import org.apache.maven.model.Model;
 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.model.Build;
 
 /**
  * @author Kristian Rosenvold
  */
-public class LifeCyclePluginAnalyzerStub
-    implements LifeCyclePluginAnalyzer
+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-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java b/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java
index 73bdbcae45..71616fa63f 100644
--- a/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java
+++ b/maven-core/src/test/java/org/apache/maven/project/AbstractMavenProjectTestCase.java
@@ -169,6 +169,17 @@ protected MavenProject getProject( File pom )
         return projectBuilder.build( pom, configuration ).getProject();
     }
 
+    protected MavenProject getProjectFromRemoteRepository( final File pom )
+        throws Exception
+    {
+        final ProjectBuildingRequest configuration = new DefaultProjectBuildingRequest();
+        configuration.setLocalRepository( this.getLocalRepository() );
+        configuration.setRemoteRepositories( Arrays.asList( this.repositorySystem.createDefaultRemoteRepository() ) );
+        initRepoSession( configuration );
+
+        return projectBuilder.build( pom, configuration ).getProject();
+    }
+
     protected ProjectBuildingRequest newBuildingRequest()
         throws Exception
     {
diff --git a/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java b/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java
index d61fc6ea10..3959cdd393 100644
--- a/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java
+++ b/maven-core/src/test/java/org/apache/maven/project/DefaultMavenProjectBuilderTest.java
@@ -189,4 +189,134 @@ public void testImportScopePomResolvesFromPropertyBasedRepository()
         request.setResolveDependencies( true );
         projectBuilder.build( pomFile, request );
     }
+
+    /**
+     * Tests whether local version range parent references are build correctly.
+     *
+     * @throws Exception
+     */
+    public void testBuildValidParentVersionRangeLocally() throws Exception
+    {
+        File f1 = getTestFile( "src/test/resources/projects/parent-version-range-local-valid/child/pom.xml" );
+
+        final MavenProject childProject = getProject( f1 );
+
+        assertNotNull( childProject.getParentArtifact() );
+        assertEquals( childProject.getParentArtifact().getVersion(), "1" );
+        assertNotNull( childProject.getParent() );
+        assertEquals( childProject.getParent().getVersion(), "1" );
+        assertNotNull( childProject.getModel().getParent() );
+        assertEquals( childProject.getModel().getParent().getVersion(), "[1,10]" );
+    }
+
+    /**
+     * Tests whether local version range parent references are build correctly.
+     *
+     * @throws Exception
+     */
+    public void testBuildParentVersionRangeLocallyWithoutChildVersion() throws Exception
+    {
+        File f1 =
+            getTestFile( "src/test/resources/projects/parent-version-range-local-child-without-version/child/pom.xml" );
+
+        try
+        {
+            getProject( f1 );
+            fail( "Expected 'ProjectBuildingException' not thrown." );
+        }
+        catch ( final ProjectBuildingException e )
+        {
+            assertNotNull( e.getMessage() );
+            assertTrue( e.getMessage().contains( "Version must be a constant" ) );
+        }
+    }
+
+    /**
+     * Tests whether local version range parent references are build correctly.
+     *
+     * @throws Exception
+     */
+    public void testBuildParentVersionRangeLocallyWithChildVersionExpression() throws Exception
+    {
+        File f1 =
+            getTestFile(
+                "src/test/resources/projects/parent-version-range-local-child-version-expression/child/pom.xml" );
+
+        try
+        {
+            getProject( f1 );
+            fail( "Expected 'ProjectBuildingException' not thrown." );
+        }
+        catch ( final ProjectBuildingException e )
+        {
+            assertNotNull( e.getMessage() );
+            assertTrue( e.getMessage().contains( "Version must be a constant" ) );
+        }
+    }
+
+    /**
+     * Tests whether external version range parent references are build correctly.
+     *
+     * @throws Exception
+     */
+    public void testBuildParentVersionRangeExternally() throws Exception
+    {
+        File f1 = getTestFile( "src/test/resources/projects/parent-version-range-external-valid/pom.xml" );
+
+        final MavenProject childProject = this.getProjectFromRemoteRepository( f1 );
+
+        assertNotNull( childProject.getParentArtifact() );
+        assertEquals( childProject.getParentArtifact().getVersion(), "1" );
+        assertNotNull( childProject.getParent() );
+        assertEquals( childProject.getParent().getVersion(), "1" );
+        assertNotNull( childProject.getModel().getParent() );
+        assertEquals( childProject.getModel().getParent().getVersion(), "[1,1]" );
+    }
+
+    /**
+     * Tests whether external version range parent references are build correctly.
+     *
+     * @throws Exception
+     */
+    public void testBuildParentVersionRangeExternallyWithoutChildVersion() throws Exception
+    {
+        File f1 =
+            getTestFile(
+                "src/test/resources/projects/parent-version-range-external-child-without-version/pom.xml" );
+
+        try
+        {
+            this.getProjectFromRemoteRepository( f1 );
+            fail( "Expected 'ProjectBuildingException' not thrown." );
+        }
+        catch ( final ProjectBuildingException e )
+        {
+            assertNotNull( e.getMessage() );
+            assertTrue( e.getMessage().contains( "Version must be a constant" ) );
+        }
+    }
+
+    /**
+     * Tests whether external version range parent references are build correctly.
+     *
+     * @throws Exception
+     */
+    public void testBuildParentVersionRangeExternallyWithChildVersionExpression() throws Exception
+    {
+        File f1 =
+            getTestFile(
+                "src/test/resources/projects/parent-version-range-external-child-version-expression/pom.xml" );
+
+        try
+        {
+            this.getProjectFromRemoteRepository( f1 );
+            fail( "Expected 'ProjectBuildingException' not thrown." );
+        }
+        catch ( final ProjectBuildingException e )
+        {
+            assertNotNull( e.getMessage() );
+            assertTrue( e.getMessage().contains( "Version must be a constant" ) );
+        }
+    }
+
 }
diff --git a/maven-core/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java b/maven-core/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java
index 52fdd80478..c919cdf776 100644
--- a/maven-core/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java
+++ b/maven-core/src/test/java/org/apache/maven/project/LegacyLocalRepositoryManager.java
@@ -59,7 +59,7 @@ public String getPathForLocalArtifact( Artifact artifact )
 
         path.append( artifact.getGroupId() ).append( '/' );
 
-        path.append( artifact.getExtension() ).append( 's' ).append( '/' );
+        path.append( artifact.getExtension() ).append( "s/" );
 
         path.append( artifact.getArtifactId() ).append( '-' ).append( artifact.getVersion() );
 
diff --git a/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnector.java b/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnector.java
index 91ace4f1e8..cb1243ced5 100644
--- a/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnector.java
+++ b/maven-core/src/test/java/org/apache/maven/repository/TestRepositoryConnector.java
@@ -27,6 +27,7 @@
 
 import org.codehaus.plexus.util.FileUtils;
 import org.eclipse.aether.artifact.Artifact;
+import org.eclipse.aether.metadata.Metadata;
 import org.eclipse.aether.repository.RemoteRepository;
 import org.eclipse.aether.spi.connector.ArtifactDownload;
 import org.eclipse.aether.spi.connector.ArtifactUpload;
@@ -35,6 +36,8 @@
 import org.eclipse.aether.spi.connector.RepositoryConnector;
 import org.eclipse.aether.transfer.ArtifactNotFoundException;
 import org.eclipse.aether.transfer.ArtifactTransferException;
+import org.eclipse.aether.transfer.MetadataNotFoundException;
+import org.eclipse.aether.transfer.MetadataTransferException;
 
 /**
  * @author Benjamin Bentmann
@@ -89,6 +92,28 @@ public void get( Collection<? extends ArtifactDownload> artifactDownloads,
                 }
             }
         }
+        if ( metadataDownloads != null )
+        {
+            for ( final MetadataDownload download : metadataDownloads )
+            {
+                File remoteFile = new File( basedir, path( download.getMetadata() ) );
+                try
+                {
+                    FileUtils.copyFile( remoteFile, download.getFile() );
+                }
+                catch ( IOException e )
+                {
+                    if ( !remoteFile.exists() )
+                    {
+                        download.setException( new MetadataNotFoundException( download.getMetadata(), repository ) );
+                    }
+                    else
+                    {
+                        download.setException( new MetadataTransferException( download.getMetadata(), repository, e ) );
+                    }
+                }
+            }
+        }
     }
 
     private String path( Artifact artifact )
@@ -113,6 +138,19 @@ private String path( Artifact artifact )
         return path.toString();
     }
 
+    private String path( Metadata metadata )
+    {
+        StringBuilder path = new StringBuilder( 128 );
+
+        path.append( metadata.getGroupId().replace( '.', '/' ) ).append( '/' );
+
+        path.append( metadata.getArtifactId() ).append( '/' );
+
+        path.append( "maven-metadata.xml" );
+
+        return path.toString();
+    }
+
     public void put( Collection<? extends ArtifactUpload> artifactUploads,
                      Collection<? extends MetadataUpload> metadataUploads )
     {
diff --git a/maven-core/src/test/remote-repo/org/apache/apache/1/apache-1.pom b/maven-core/src/test/remote-repo/org/apache/apache/1/apache-1.pom
new file mode 100644
index 0000000000..ad6b854380
--- /dev/null
+++ b/maven-core/src/test/remote-repo/org/apache/apache/1/apache-1.pom
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ Copyright 2005-2006 The Apache Software Foundation.
+  ~
+  ~ Licensed 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <!-- Shared parent. Doesn't define a lot of things about Apache like general mailing lists, but does
+       define the settings common to all projects at Apache -->
+  <groupId>org.apache</groupId>
+  <artifactId>apache</artifactId>
+  <version>1</version>
+  <packaging>pom</packaging>
+  <name>The Apache Software Foundation</name>
+  <description>
+    The Apache Software Foundation provides support for the Apache community of open-source software projects.
+    The Apache projects are characterized by a collaborative, consensus based development process, an open and
+    pragmatic software license, and a desire to create high quality software that leads the way in its field.
+    We consider ourselves not simply a group of projects sharing a server, but rather a community of developers
+    and users.
+  </description>
+  <licenses>
+    <license>
+      <name>The Apache Software License, Version 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+      <distribution>repo</distribution>
+    </license>
+  </licenses>
+  <organization>
+    <name>Apache Software Foundation</name>
+    <url>http://www.apache.org/</url>
+  </organization>
+  <url>http://www.apache.org/</url>
+  <repositories>
+    <repository>
+      <id>apache.snapshots</id>
+      <name>Apache Snapshot Repository</name>
+      <url>http://svn.apache.org/maven-snapshot-repository</url>
+      <releases>
+        <enabled>false</enabled>
+      </releases>
+    </repository>
+  </repositories>
+  <distributionManagement>
+    <!-- Site omitted - each project must provide their own -->
+    <repository>
+      <id>apache.releases</id>
+      <name>Apache Release Distribution Repository</name>
+      <url>scp://minotaur.apache.org/www/www.apache.org/dist/maven-repository</url>
+    </repository>
+    <snapshotRepository>
+      <id>apache.snapshots</id>
+      <name>Apache Development Snapshot Repository</name>
+      <url>scp://minotaur.apache.org/www/cvs.apache.org/maven-snapshot-repository</url>
+    </snapshotRepository>
+  </distributionManagement>
+  <mailingLists>
+    <mailingList>
+      <name>Apache Announce List</name>
+      <subscribe>announce-subscribe@apache.org</subscribe>
+      <unsubscribe>announce-unsubscribe@apache.org</unsubscribe>
+      <post>announce@apache.org</post>
+      <archive>http://mail-archives.apache.org/mod_mbox/www-announce/</archive>
+    </mailingList>
+  </mailingLists>
+</project>
+
diff --git a/maven-core/src/test/remote-repo/org/apache/apache/maven-metadata.xml b/maven-core/src/test/remote-repo/org/apache/apache/maven-metadata.xml
new file mode 100644
index 0000000000..596f967e40
--- /dev/null
+++ b/maven-core/src/test/remote-repo/org/apache/apache/maven-metadata.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<metadata>
+  <groupId>org.apache</groupId>
+  <artifactId>apache</artifactId>
+  <versioning>
+    <latest>1</latest>
+    <release>1</release>
+    <versions>
+      <version>1</version>
+    </versions>
+    <lastUpdated>20150428055824</lastUpdated>
+  </versioning>
+</metadata>
diff --git a/maven-core/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml b/maven-core/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml
index e052489bb6..d48de048f2 100644
--- a/maven-core/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml
+++ b/maven-core/src/test/resources/org/apache/maven/project/AbstractMavenProjectTestCase.xml
@@ -2,7 +2,7 @@
 <plexus>
   <components>
     <component>
-      <role>org.apache.maven.lifecycle.LifeCyclePluginAnalyzer</role>
+      <role>org.apache.maven.lifecycle.LifecyclePluginAnalyzer</role>
       <implementation>org.apache.maven.lifecycle.EmptyLifecyclePluginAnalyzer</implementation>
     </component>
   </components>
diff --git a/maven-core/src/test/resources/org/apache/maven/project/PomConstructionTest.xml b/maven-core/src/test/resources/org/apache/maven/project/PomConstructionTest.xml
index e3c3ab340c..40b5f9380f 100644
--- a/maven-core/src/test/resources/org/apache/maven/project/PomConstructionTest.xml
+++ b/maven-core/src/test/resources/org/apache/maven/project/PomConstructionTest.xml
@@ -2,7 +2,7 @@
 <plexus>
   <components>
     <component>
-      <role>org.apache.maven.lifecycle.LifeCyclePluginAnalyzer</role>
+      <role>org.apache.maven.lifecycle.LifecyclePluginAnalyzer</role>
       <implementation>org.apache.maven.lifecycle.EmptyLifecyclePluginAnalyzer</implementation>
     </component>
     <component>
diff --git a/maven-core/src/test/resources/projects/parent-version-range-external-child-version-expression/pom.xml b/maven-core/src/test/resources/projects/parent-version-range-external-child-version-expression/pom.xml
new file mode 100644
index 0000000000..d07ad6eb56
--- /dev/null
+++ b/maven-core/src/test/resources/projects/parent-version-range-external-child-version-expression/pom.xml
@@ -0,0 +1,12 @@
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache</groupId>
+    <artifactId>apache</artifactId>
+    <version>[1,1]</version>
+  </parent>
+  <artifactId>child</artifactId>
+  <!-- Must not use expressions from parent due to version range. -->
+  <version>${some.property}</version>
+  <packaging>pom</packaging>
+</project>
diff --git a/maven-core/src/test/resources/projects/parent-version-range-external-child-without-version/pom.xml b/maven-core/src/test/resources/projects/parent-version-range-external-child-without-version/pom.xml
new file mode 100644
index 0000000000..4f5a004f91
--- /dev/null
+++ b/maven-core/src/test/resources/projects/parent-version-range-external-child-without-version/pom.xml
@@ -0,0 +1,11 @@
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache</groupId>
+    <artifactId>apache</artifactId>
+    <version>[1,1]</version>
+  </parent>
+  <artifactId>child</artifactId>
+  <!-- version>2</version Must not inherit version from parent due to version range. -->
+  <packaging>pom</packaging>
+</project>
diff --git a/maven-core/src/test/resources/projects/parent-version-range-external-valid/pom.xml b/maven-core/src/test/resources/projects/parent-version-range-external-valid/pom.xml
new file mode 100644
index 0000000000..54eea90cd0
--- /dev/null
+++ b/maven-core/src/test/resources/projects/parent-version-range-external-valid/pom.xml
@@ -0,0 +1,11 @@
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache</groupId>
+    <artifactId>apache</artifactId>
+    <version>[1,1]</version>
+  </parent>
+  <artifactId>child</artifactId>
+  <version>2</version>
+  <packaging>pom</packaging>
+</project>
diff --git a/maven-core/src/test/resources/projects/parent-version-range-local-child-version-expression/child/pom.xml b/maven-core/src/test/resources/projects/parent-version-range-local-child-version-expression/child/pom.xml
new file mode 100644
index 0000000000..066a11ecdb
--- /dev/null
+++ b/maven-core/src/test/resources/projects/parent-version-range-local-child-version-expression/child/pom.xml
@@ -0,0 +1,12 @@
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>parent-version-range-local</groupId>
+    <artifactId>parent</artifactId>
+    <version>[1,10]</version>
+  </parent>
+  <artifactId>child</artifactId>
+  <!-- Must not use expressions from parent due to version range. -->
+  <version>${some.property}</version>
+  <packaging>pom</packaging>
+</project>
diff --git a/maven-core/src/test/resources/projects/parent-version-range-local-child-version-expression/pom.xml b/maven-core/src/test/resources/projects/parent-version-range-local-child-version-expression/pom.xml
new file mode 100644
index 0000000000..a82bbf2a40
--- /dev/null
+++ b/maven-core/src/test/resources/projects/parent-version-range-local-child-version-expression/pom.xml
@@ -0,0 +1,7 @@
+<project>
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>parent-version-range-local</groupId>
+	<artifactId>parent</artifactId>
+	<version>1</version>
+	<packaging>pom</packaging>
+</project>
diff --git a/maven-core/src/test/resources/projects/parent-version-range-local-child-without-version/child/pom.xml b/maven-core/src/test/resources/projects/parent-version-range-local-child-without-version/child/pom.xml
new file mode 100644
index 0000000000..645a8f13f5
--- /dev/null
+++ b/maven-core/src/test/resources/projects/parent-version-range-local-child-without-version/child/pom.xml
@@ -0,0 +1,11 @@
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>parent-version-range-local</groupId>
+    <artifactId>parent</artifactId>
+    <version>[1,10]</version>
+  </parent>
+  <artifactId>child</artifactId>
+  <!-- version>1</version Must not inherit version from parent due to version range. -->
+  <packaging>pom</packaging>
+</project>
diff --git a/maven-core/src/test/resources/projects/parent-version-range-local-child-without-version/pom.xml b/maven-core/src/test/resources/projects/parent-version-range-local-child-without-version/pom.xml
new file mode 100644
index 0000000000..a82bbf2a40
--- /dev/null
+++ b/maven-core/src/test/resources/projects/parent-version-range-local-child-without-version/pom.xml
@@ -0,0 +1,7 @@
+<project>
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>parent-version-range-local</groupId>
+	<artifactId>parent</artifactId>
+	<version>1</version>
+	<packaging>pom</packaging>
+</project>
diff --git a/maven-core/src/test/resources/projects/parent-version-range-local-valid/child/pom.xml b/maven-core/src/test/resources/projects/parent-version-range-local-valid/child/pom.xml
new file mode 100644
index 0000000000..886bcdf358
--- /dev/null
+++ b/maven-core/src/test/resources/projects/parent-version-range-local-valid/child/pom.xml
@@ -0,0 +1,11 @@
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>parent-version-range-local</groupId>
+    <artifactId>parent</artifactId>
+    <version>[1,10]</version>
+  </parent>
+  <artifactId>child</artifactId>
+  <version>1</version>
+  <packaging>pom</packaging>
+</project>
diff --git a/maven-core/src/test/resources/projects/parent-version-range-local-valid/pom.xml b/maven-core/src/test/resources/projects/parent-version-range-local-valid/pom.xml
new file mode 100644
index 0000000000..a82bbf2a40
--- /dev/null
+++ b/maven-core/src/test/resources/projects/parent-version-range-local-valid/pom.xml
@@ -0,0 +1,7 @@
+<project>
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>parent-version-range-local</groupId>
+	<artifactId>parent</artifactId>
+	<version>1</version>
+	<packaging>pom</packaging>
+</project>
diff --git a/maven-embedder/pom.xml b/maven-embedder/pom.xml
index c011e91605..2cfa670723 100644
--- a/maven-embedder/pom.xml
+++ b/maven-embedder/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.3.10-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/CLIReportingUtils.java b/maven-embedder/src/main/java/org/apache/maven/cli/CLIReportingUtils.java
index 2397d5d033..a901cc532a 100644
--- a/maven-embedder/src/main/java/org/apache/maven/cli/CLIReportingUtils.java
+++ b/maven-embedder/src/main/java/org/apache/maven/cli/CLIReportingUtils.java
@@ -19,15 +19,15 @@
  * under the License.
  */
 
-import org.codehaus.plexus.util.Os;
-import org.slf4j.Logger;
-
 import java.io.IOException;
 import java.io.InputStream;
+import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Locale;
 import java.util.Properties;
-import java.util.TimeZone;
+
+import org.apache.commons.lang3.SystemUtils;
+import org.slf4j.Logger;
 
 /**
  * Utility class used to report errors, statistics, application version info, etc.
@@ -54,7 +54,7 @@ public static String showVersion()
     {
         final String ls = System.getProperty( "line.separator" );
         Properties properties = getBuildProperties();
-        StringBuilder version = new StringBuilder();
+        StringBuilder version = new StringBuilder( 256 );
         version.append( createMavenVersionString( properties ) ).append( ls );
         version.append( reduce(
             properties.getProperty( "distributionShortName" ) + " home: " + System.getProperty( "maven.home",
@@ -68,8 +68,19 @@ public static String showVersion()
         version.append( "Java home: " ).append( System.getProperty( "java.home", "<unknown Java home>" ) ).append( ls );
         version.append( "Default locale: " ).append( Locale.getDefault() ).append( ", platform encoding: " ).append(
             System.getProperty( "file.encoding", "<unknown encoding>" ) ).append( ls );
-        version.append( "OS name: \"" ).append( Os.OS_NAME ).append( "\", version: \"" ).append( Os.OS_VERSION ).append(
-            "\", arch: \"" ).append( Os.OS_ARCH ).append( "\", family: \"" ).append( Os.OS_FAMILY ).append( "\"" );
+        version.append( "OS name: \"" ).append( SystemUtils.OS_NAME ).
+            append( "\", version: \"" ).append( SystemUtils.OS_VERSION ).
+            append( "\", arch: \"" ).append( SystemUtils.OS_ARCH );
+        String osFamily = "<unknown family>";
+        if ( SystemUtils.IS_OS_WINDOWS )
+        {
+            osFamily = "Windows";
+        }
+        else if ( SystemUtils.IS_OS_UNIX )
+        {
+            osFamily = "Unix";
+        }
+        version.append( "\", family: \"" ).append( osFamily ).append( '\"' );
         return version.toString();
     }
 
@@ -152,24 +163,8 @@ public static void showError( Logger logger, String message, Throwable e, boolea
 
     public static String formatTimestamp( long timestamp )
     {
-        // Manual construction of the tz offset because only Java 7 is aware of ISO 8601 time zones
-        TimeZone tz = TimeZone.getDefault();
-        int offset = tz.getRawOffset();
-
-        // Raw offset ignores DST, so check if we are in DST now and add the offset
-        if ( tz.inDaylightTime( new Date( timestamp ) ) )
-        {
-            offset += tz.getDSTSavings();
-        }
-
-        // CHECKSTYLE_OFF: MagicNumber
-        long m = Math.abs( ( offset / ONE_MINUTE ) % 60 );
-        long h = Math.abs( ( offset / ONE_HOUR ) % 24 );
-        // CHECKSTYLE_ON: MagicNumber
-
-        int offsetDir = (int) Math.signum( (float) offset );
-        char offsetSign = offsetDir >= 0 ? '+' : '-';
-        return String.format( "%tFT%<tT%s%02d:%02d", timestamp, offsetSign, h, m );
+        SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssXXX" );
+        return sdf.format( new Date( timestamp ) );
     }
 
     public static String formatDuration( long duration )
@@ -185,18 +180,22 @@ public static String formatDuration( long duration )
         String format;
         if ( d > 0 )
         {
+            // Length 11+ chars
             format = "%d d %02d:%02d h";
         }
         else if ( h > 0 )
         {
+            // Length 7 chars
             format = "%2$02d:%3$02d h";
         }
         else if ( m > 0 )
         {
+            // Length 9 chars
             format = "%3$02d:%4$02d min";
         }
         else
         {
+            // Length 7-8 chars
             format = "%4$d.%5$03d s";
         }
 
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 176ce4d843..c5a2256add 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,15 +19,34 @@
  * under the License.
  */
 
-import com.google.common.base.Charsets;
-import com.google.common.io.Files;
-import com.google.inject.AbstractModule;
+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.util.ArrayList;
+import java.util.Arrays;
+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 org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.ParseException;
 import org.apache.commons.cli.UnrecognizedOptionException;
 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 +77,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;
@@ -77,6 +104,9 @@
 import org.codehaus.plexus.logging.LoggerManager;
 import org.codehaus.plexus.util.StringUtils;
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
+import com.google.inject.AbstractModule;
 import org.eclipse.aether.transfer.TransferListener;
 import org.slf4j.ILoggerFactory;
 import org.slf4j.Logger;
@@ -87,27 +117,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.util.ArrayList;
-import java.util.Arrays;
-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;
-
 // TODO: push all common bits back to plexus cli and prepare for transition to Guice. We don't need 50 ways to make CLIs
 
 /**
@@ -172,6 +181,8 @@
 
     private Map<String, ConfigurationProcessor> configurationProcessors;
 
+    private ProfileSelector profileSelector;
+
     public MavenCli()
     {
         this( null );
@@ -285,6 +296,7 @@ public int doMain( CliRequest cliRequest )
             populateRequest( cliRequest );
             encryption( cliRequest );
             repository( cliRequest );
+            profiles( cliRequest );
             return execute( cliRequest );
         }
         catch ( ExitException e )
@@ -594,6 +606,8 @@ protected void configure()
 
         dispatcher = (DefaultSecDispatcher) container.lookup( SecDispatcher.class, "maven" );
 
+        profileSelector = container.lookup( ProfileSelector.class );
+
         return container;
     }
 
@@ -657,9 +671,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
             {
@@ -846,13 +866,104 @@ 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 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
     {
@@ -1005,13 +1116,13 @@ private void configure( CliRequest cliRequest )
         // present supplied by the user. The rule is that we only allow the execution of one ConfigurationProcessor.
         // If there is more than one then we execute the one supplied by the user, otherwise we execute the
         // the default SettingsXmlConfigurationProcessor.
-        // 
+        //
         int userSuppliedConfigurationProcessorCount = configurationProcessors.size() - 1;
 
         if ( userSuppliedConfigurationProcessorCount == 0 )
         {
             //
-            // Our settings.xml source is historically how we have configured Maven from the CLI so we are going to 
+            // Our settings.xml source is historically how we have configured Maven from the CLI so we are going to
             // have to honour its existence forever. So let's run it.
             //
             configurationProcessors.get( SettingsXmlConfigurationProcessor.HINT ).process( cliRequest );
@@ -1288,7 +1399,7 @@ else if ( request.isInteractiveMode() && !cliRequest.commandLine.hasOption( CLIM
             // If we're logging to a file then we don't want the console transfer listener as it will spew
             // download progress all over the place
             //
-            transferListener = getConsoleTransferListener();
+            transferListener = getConsoleTransferListener( cliRequest.commandLine.hasOption( CLIManager.DEBUG ) );
         }
         else
         {
@@ -1547,7 +1658,7 @@ private static void setCliProperty( String property, Properties properties )
 
         String value;
 
-        int i = property.indexOf( "=" );
+        int i = property.indexOf( '=' );
 
         if ( i <= 0 )
         {
@@ -1588,9 +1699,9 @@ public ExitException( int exitCode )
     // Customizations available via the CLI
     //
 
-    protected TransferListener getConsoleTransferListener()
+    protected TransferListener getConsoleTransferListener( boolean printResourceNames )
     {
-        return new ConsoleMavenTransferListener( System.out );
+        return new ConsoleMavenTransferListener( System.out, printResourceNames );
     }
 
     protected TransferListener getBatchTransferListener()
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 791a226747..7ba2194650 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;
@@ -51,6 +46,7 @@
 public class SettingsXmlConfigurationProcessor
     implements ConfigurationProcessor
 {
+
     public static final String HINT = "settings";
 
     public static final String USER_HOME = System.getProperty( "user.home" );
@@ -59,8 +55,8 @@
 
     public static final File DEFAULT_USER_SETTINGS_FILE = new File( USER_MAVEN_CONFIGURATION_HOME, "settings.xml" );
 
-    public static final File DEFAULT_GLOBAL_SETTINGS_FILE = new File( System.getProperty( "maven.home", System
-        .getProperty( "user.dir", "" ) ), "conf/settings.xml" );
+    public static final File DEFAULT_GLOBAL_SETTINGS_FILE =
+        new File( System.getProperty( "maven.home", System.getProperty( "user.dir", "" ) ), "conf/settings.xml" );
 
     @Requirement
     private Logger logger;
@@ -68,9 +64,6 @@
     @Requirement
     private SettingsBuilder settingsBuilder;
 
-    @Requirement
-    private SettingsDecrypter settingsDecrypter;
-
     @Override
     public void process( CliRequest cliRequest )
         throws Exception
@@ -88,8 +81,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
@@ -106,8 +100,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
@@ -129,10 +124,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 );
 
@@ -218,43 +216,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;
     }
 
@@ -287,4 +255,5 @@ else if ( file.getPath().startsWith( File.separator ) )
             return new File( workingDirectory, file.getPath() ).getAbsoluteFile();
         }
     }
+
 }
diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/event/ExecutionEventLogger.java b/maven-embedder/src/main/java/org/apache/maven/cli/event/ExecutionEventLogger.java
index ce8d26cfd6..89c59cbba8 100644
--- a/maven-embedder/src/main/java/org/apache/maven/cli/event/ExecutionEventLogger.java
+++ b/maven-embedder/src/main/java/org/apache/maven/cli/event/ExecutionEventLogger.java
@@ -161,7 +161,7 @@ else if ( buildSummary instanceof BuildSuccess )
                     buffer.append( chars( ' ', padSize ) );
                 }
                 buffer.append( buildTimeDuration );
-                buffer.append( "]" );
+                buffer.append( ']' );
             }
             else if ( buildSummary instanceof BuildFailure )
             {
@@ -173,7 +173,7 @@ else if ( buildSummary instanceof BuildFailure )
                     buffer.append( chars( ' ', padSize ) );
                 }
                 buffer.append( buildTimeDuration );
-                buffer.append( "]" );
+                buffer.append( ']' );
             }
 
             logger.info( buffer.toString() );
diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/UnsupportedSlf4jBindingConfiguration.java b/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/UnsupportedSlf4jBindingConfiguration.java
index 2e91b251f1..d269770852 100644
--- a/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/UnsupportedSlf4jBindingConfiguration.java
+++ b/maven-embedder/src/main/java/org/apache/maven/cli/logging/impl/UnsupportedSlf4jBindingConfiguration.java
@@ -59,7 +59,7 @@ public void activate()
         for ( Map.Entry<URL, Set<Object>> entry : supported.entrySet() )
         {
             StringBuilder sb = new StringBuilder();
-            sb.append( "(from " ).append( entry.getKey().toExternalForm() ).append( ")" );
+            sb.append( "(from " ).append( entry.getKey().toExternalForm() ).append( ')' );
 
             for ( Object binding : entry.getValue() )
             {
diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/transfer/AbstractMavenTransferListener.java b/maven-embedder/src/main/java/org/apache/maven/cli/transfer/AbstractMavenTransferListener.java
index 58b1a5dcba..e72aa47d8e 100644
--- a/maven-embedder/src/main/java/org/apache/maven/cli/transfer/AbstractMavenTransferListener.java
+++ b/maven-embedder/src/main/java/org/apache/maven/cli/transfer/AbstractMavenTransferListener.java
@@ -24,6 +24,7 @@
 import java.text.DecimalFormatSymbols;
 import java.util.Locale;
 
+import org.apache.commons.lang3.Validate;
 import org.eclipse.aether.transfer.AbstractTransferListener;
 import org.eclipse.aether.transfer.TransferCancelledException;
 import org.eclipse.aether.transfer.TransferEvent;
@@ -33,6 +34,178 @@
     extends AbstractTransferListener
 {
 
+    // CHECKSTYLE_OFF: LineLength
+    /**
+     * Formats file size with the associated <a href="https://en.wikipedia.org/wiki/Metric_prefix">SI</a> prefix
+     * (GB, MB, kB) and using the patterns <code>#0.0</code> for numbers between 1 and 10
+     * and <code>###0</code> for numbers between 10 and 1000+ by default.
+     *
+     * @see <a href="https://en.wikipedia.org/wiki/Metric_prefix">https://en.wikipedia.org/wiki/Metric_prefix</a>
+     * @see <a href="https://en.wikipedia.org/wiki/Binary_prefix">https://en.wikipedia.org/wiki/Binary_prefix</a>
+     * @see <a
+     *      href="https://en.wikipedia.org/wiki/Octet_%28computing%29">https://en.wikipedia.org/wiki/Octet_(computing)</a>
+     */
+    // CHECKSTYLE_ON: LineLength
+    // TODO Move me to Maven Shared Utils
+    static class FileSizeFormat
+    {
+        static enum ScaleUnit
+        {
+            BYTE
+            {
+                @Override
+                public long bytes()
+                {
+                    return 1L;
+                }
+
+                @Override
+                public String symbol()
+                {
+                    return "B";
+                }
+            },
+            KILOBYTE
+            {
+                @Override
+                public long bytes()
+                {
+                    return 1000L;
+                }
+
+                @Override
+                public String symbol()
+                {
+                    return "kB";
+                }
+            },
+            MEGABYTE
+            {
+                @Override
+                public long bytes()
+                {
+                    return KILOBYTE.bytes() * KILOBYTE.bytes();
+                }
+
+                @Override
+                public String symbol()
+                {
+                    return "MB";
+                }
+            },
+            GIGABYTE
+            {
+                @Override
+                public long bytes()
+                {
+                    return MEGABYTE.bytes() * KILOBYTE.bytes();
+                };
+
+                @Override
+                public String symbol()
+                {
+                    return "GB";
+                }
+            };
+
+            public abstract long bytes();
+            public abstract String symbol();
+
+            public static ScaleUnit getScaleUnit( long size )
+            {
+                Validate.isTrue( size >= 0, "File size cannot be negative: %s", size );
+
+                if ( size >= GIGABYTE.bytes() )
+                {
+                    return GIGABYTE;
+                }
+                else if ( size >= MEGABYTE.bytes() )
+                {
+                    return MEGABYTE;
+                }
+                else if ( size >= KILOBYTE.bytes() )
+                {
+                    return KILOBYTE;
+                }
+                else
+                {
+                    return BYTE;
+                }
+            }
+        }
+
+        private DecimalFormat smallFormat;
+        private DecimalFormat largeFormat;
+
+        public FileSizeFormat( Locale locale )
+        {
+            smallFormat = new DecimalFormat( "#0.0", new DecimalFormatSymbols( locale ) );
+            largeFormat = new DecimalFormat( "###0", new DecimalFormatSymbols( locale ) );
+        }
+
+        public String format( long size )
+        {
+            return format( size, null );
+        }
+
+        public String format( long size, ScaleUnit unit )
+        {
+            return format( size, unit, false );
+        }
+
+        public String format( long size, ScaleUnit unit, boolean omitSymbol )
+        {
+            Validate.isTrue( size >= 0, "File size cannot be negative: %s", size );
+
+            if ( unit == null )
+            {
+                unit = ScaleUnit.getScaleUnit( size );
+            }
+
+            double scaledSize = (double) size / unit.bytes();
+            String scaledSymbol = " " + unit.symbol();
+
+            if ( omitSymbol )
+            {
+                scaledSymbol = "";
+            }
+
+            if ( unit == ScaleUnit.BYTE )
+            {
+                return largeFormat.format( size ) + scaledSymbol;
+            }
+
+            if ( scaledSize < 0.05 || scaledSize >= 10.0 )
+            {
+                return largeFormat.format( scaledSize ) + scaledSymbol;
+            }
+            else
+            {
+                return smallFormat.format( scaledSize ) + scaledSymbol;
+            }
+        }
+
+        public String formatProgress( long progressedSize, long size )
+        {
+            Validate.isTrue( progressedSize >= 0L, "Progressed file size cannot be negative: %s", progressedSize );
+            Validate.isTrue( size >= 0L && progressedSize <= size || size < 0L,
+                "Progressed file size cannot be bigger than size: %s > %s", progressedSize, size );
+
+            if ( size >= 0 && progressedSize != size )
+            {
+                ScaleUnit unit = ScaleUnit.getScaleUnit( size );
+                String formattedProgressedSize = format( progressedSize, unit, true );
+                String formattedSize = format( size, unit );
+
+                return formattedProgressedSize + "/" + formattedSize;
+            }
+            else
+            {
+                return format( progressedSize );
+            }
+        }
+    }
+
     protected PrintStream out;
 
     protected AbstractMavenTransferListener( PrintStream out )
@@ -43,9 +216,10 @@ protected AbstractMavenTransferListener( PrintStream out )
     @Override
     public void transferInitiated( TransferEvent event )
     {
-        String message = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading";
+        String type = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading";
 
-        out.println( message + ": " + event.getResource().getRepositoryUrl() + event.getResource().getResourceName() );
+        TransferResource resource = event.getResource();
+        out.println( type + ": " + resource.getRepositoryUrl() + resource.getResourceName() );
     }
 
     @Override
@@ -53,7 +227,6 @@ public void transferCorrupted( TransferEvent event )
         throws TransferCancelledException
     {
         TransferResource resource = event.getResource();
-
         out.println( "[WARNING] " + event.getException().getMessage() + " for " + resource.getRepositoryUrl()
             + resource.getResourceName() );
     }
@@ -63,28 +236,21 @@ public void transferSucceeded( TransferEvent event )
     {
         TransferResource resource = event.getResource();
         long contentLength = event.getTransferredBytes();
-        if ( contentLength >= 0 )
-        {
-            String type = ( event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded" );
-            String len = contentLength >= 1024 ? toKB( contentLength ) + " KB" : contentLength + " B";
 
-            String throughput = "";
-            long duration = System.currentTimeMillis() - resource.getTransferStartTime();
-            if ( duration > 0 )
-            {
-                DecimalFormat format = new DecimalFormat( "0.0", new DecimalFormatSymbols( Locale.ENGLISH ) );
-                double kbPerSec = ( contentLength / 1024.0 ) / ( duration / 1000.0 );
-                throughput = " at " + format.format( kbPerSec ) + " KB/sec";
-            }
+        FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
+        String type = ( event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded" );
+        String len = format.format( contentLength );
 
-            out.println( type + ": " + resource.getRepositoryUrl() + resource.getResourceName() + " (" + len
-                + throughput + ")" );
+        String throughput = "";
+        long duration = System.currentTimeMillis() - resource.getTransferStartTime();
+        if ( duration > 0L )
+        {
+            double bytesPerSecond = contentLength / ( duration / 1000.0 );
+            throughput = " at " + format.format( (long) bytesPerSecond ) + "/s";
         }
-    }
 
-    protected long toKB( long bytes )
-    {
-        return ( bytes + 1023 ) / 1024;
+        out.println( type + ": " + resource.getRepositoryUrl() + resource.getResourceName() + " (" + len
+            + throughput + ")" );
     }
 
 }
diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListener.java b/maven-embedder/src/main/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListener.java
index 5f87836440..a61f2e1388 100644
--- a/maven-embedder/src/main/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListener.java
+++ b/maven-embedder/src/main/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListener.java
@@ -20,9 +20,13 @@
  */
 
 import java.io.PrintStream;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Locale;
 import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
 
+import org.apache.commons.lang3.StringUtils;
 import org.eclipse.aether.transfer.TransferCancelledException;
 import org.eclipse.aether.transfer.TransferEvent;
 import org.eclipse.aether.transfer.TransferResource;
@@ -36,32 +40,58 @@
     extends AbstractMavenTransferListener
 {
 
-    private Map<TransferResource, Long> downloads = new ConcurrentHashMap<>();
+    private Map<TransferResource, Long> transfers = Collections.synchronizedMap(
+                                                        new LinkedHashMap<TransferResource, Long>() );
 
+    private boolean printResourceNames;
     private int lastLength;
 
-    public ConsoleMavenTransferListener( PrintStream out )
+    public ConsoleMavenTransferListener( PrintStream out, boolean printResourceNames )
     {
         super( out );
+        this.printResourceNames = printResourceNames;
     }
 
     @Override
-    public void transferProgressed( TransferEvent event )
+    public synchronized void transferInitiated( TransferEvent event )
+    {
+        overridePreviousTransfer( event );
+
+        super.transferInitiated( event );
+    }
+
+    @Override
+    public synchronized void transferCorrupted( TransferEvent event )
+        throws TransferCancelledException
+    {
+        overridePreviousTransfer( event );
+
+        super.transferCorrupted( event );
+    }
+
+    @Override
+    public synchronized void transferProgressed( TransferEvent event )
         throws TransferCancelledException
     {
         TransferResource resource = event.getResource();
-        downloads.put( resource, event.getTransferredBytes() );
+        transfers.put( resource, event.getTransferredBytes() );
 
-        StringBuilder buffer = new StringBuilder( 64 );
+        StringBuilder buffer = new StringBuilder( 128 );
+        buffer.append( "Progress (" ).append(  transfers.size() ).append( "): " );
 
-        for ( Map.Entry<TransferResource, Long> entry : downloads.entrySet() )
+        synchronized ( transfers )
         {
-            long total = entry.getKey().getContentLength();
-            Long complete = entry.getValue();
-            // NOTE: This null check guards against http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6312056
-            if ( complete != null )
+            Iterator<Map.Entry<TransferResource, Long>> entries = transfers.entrySet().iterator();
+            while ( entries.hasNext() )
             {
-                buffer.append( getStatus( complete, total ) ).append( "  " );
+                Map.Entry<TransferResource, Long> entry = entries.next();
+                long total = entry.getKey().getContentLength();
+                Long complete = entry.getValue();
+                buffer.append( getStatus( entry.getKey().getResourceName(), complete, total ) );
+                if ( entries.hasNext() )
+                {
+                    buffer.append( " | " );
+                }
             }
         }
 
@@ -69,28 +99,29 @@ public void transferProgressed( TransferEvent event )
         lastLength = buffer.length();
         pad( buffer, pad );
         buffer.append( '\r' );
-
         out.print( buffer.toString() );
+        out.flush();
     }
 
-    private String getStatus( long complete, long total )
+    private String getStatus( String resourceName, long complete, long total )
     {
-        if ( total >= 1024 )
-        {
-            return toKB( complete ) + "/" + toKB( total ) + " KB ";
-        }
-        else if ( total >= 0 )
-        {
-            return complete + "/" + total + " B ";
-        }
-        else if ( complete >= 1024 )
+        FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
+        StringBuilder status = new StringBuilder();
+
+        if ( printResourceNames )
         {
-            return toKB( complete ) + " KB ";
+            status.append( StringUtils.substringAfterLast( resourceName,  "/" ) );
+            status.append( " (" );
         }
-        else
+
+        status.append( format.formatProgress( complete, total ) );
+
+        if ( printResourceNames )
         {
-            return complete + " B ";
+            status.append( ")" );
         }
+
+        return status.toString();
     }
 
     private void pad( StringBuilder buffer, int spaces )
@@ -105,29 +136,34 @@ private void pad( StringBuilder buffer, int spaces )
     }
 
     @Override
-    public void transferSucceeded( TransferEvent event )
+    public synchronized void transferSucceeded( TransferEvent event )
     {
-        transferCompleted( event );
+        transfers.remove( event.getResource() );
+        overridePreviousTransfer( event );
 
         super.transferSucceeded( event );
     }
 
     @Override
-    public void transferFailed( TransferEvent event )
+    public synchronized void transferFailed( TransferEvent event )
     {
-        transferCompleted( event );
+        transfers.remove( event.getResource() );
+        overridePreviousTransfer( event );
 
         super.transferFailed( event );
     }
 
-    private void transferCompleted( TransferEvent event )
+    private void overridePreviousTransfer( TransferEvent event )
     {
-        downloads.remove( event.getResource() );
-
-        StringBuilder buffer = new StringBuilder( 64 );
-        pad( buffer, lastLength );
-        buffer.append( '\r' );
-        out.print( buffer.toString() );
+        if ( lastLength > 0 )
+        {
+            StringBuilder buffer = new StringBuilder( 128 );
+            pad( buffer, lastLength );
+            buffer.append( '\r' );
+            out.print( buffer.toString() );
+            out.flush();
+            lastLength = 0;
+        }
     }
 
 }
diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/transfer/Slf4jMavenTransferListener.java b/maven-embedder/src/main/java/org/apache/maven/cli/transfer/Slf4jMavenTransferListener.java
index bb72db3677..5bfb7b448c 100644
--- a/maven-embedder/src/main/java/org/apache/maven/cli/transfer/Slf4jMavenTransferListener.java
+++ b/maven-embedder/src/main/java/org/apache/maven/cli/transfer/Slf4jMavenTransferListener.java
@@ -19,10 +19,9 @@
  * under the License.
  */
 
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
 import java.util.Locale;
 
+import org.apache.maven.cli.transfer.AbstractMavenTransferListener.FileSizeFormat;
 import org.eclipse.aether.transfer.AbstractTransferListener;
 import org.eclipse.aether.transfer.TransferCancelledException;
 import org.eclipse.aether.transfer.TransferEvent;
@@ -50,9 +49,10 @@ public Slf4jMavenTransferListener( Logger out )
     @Override
     public void transferInitiated( TransferEvent event )
     {
-        String message = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading";
+        String type = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading";
 
-        out.info( message + ": " + event.getResource().getRepositoryUrl() + event.getResource().getResourceName() );
+        TransferResource resource = event.getResource();
+        out.info( type + ": " + resource.getRepositoryUrl() + resource.getResourceName() );
     }
 
     @Override
@@ -60,7 +60,6 @@ public void transferCorrupted( TransferEvent event )
         throws TransferCancelledException
     {
         TransferResource resource = event.getResource();
-
         out.warn( event.getException().getMessage() + " for " + resource.getRepositoryUrl()
             + resource.getResourceName() );
     }
@@ -70,28 +69,21 @@ public void transferSucceeded( TransferEvent event )
     {
         TransferResource resource = event.getResource();
         long contentLength = event.getTransferredBytes();
-        if ( contentLength >= 0 )
-        {
-            String type = ( event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded" );
-            String len = contentLength >= 1024 ? toKB( contentLength ) + " KB" : contentLength + " B";
 
-            String throughput = "";
-            long duration = System.currentTimeMillis() - resource.getTransferStartTime();
-            if ( duration > 0 )
-            {
-                DecimalFormat format = new DecimalFormat( "0.0", new DecimalFormatSymbols( Locale.ENGLISH ) );
-                double kbPerSec = ( contentLength / 1024.0 ) / ( duration / 1000.0 );
-                throughput = " at " + format.format( kbPerSec ) + " KB/sec";
-            }
+        FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
+        String type = ( event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded" );
+        String len = format.format( contentLength );
 
-            out.info( type + ": " + resource.getRepositoryUrl() + resource.getResourceName() + " (" + len
-                + throughput + ")" );
+        String throughput = "";
+        long duration = System.currentTimeMillis() - resource.getTransferStartTime();
+        if ( duration > 0L )
+        {
+            double bytesPerSecond = contentLength / ( duration / 1000.0 );
+            throughput = " at " + format.format( (long) bytesPerSecond ) + "/s";
         }
-    }
 
-    protected long toKB( long bytes )
-    {
-        return ( bytes + 1023 ) / 1024;
+        out.info( type + ": " + resource.getRepositoryUrl() + resource.getResourceName() + " (" + len
+            + throughput + ")" );
     }
 
 }
diff --git a/maven-embedder/src/main/resources/META-INF/MANIFEST.MF b/maven-embedder/src/main/resources/META-INF/MANIFEST.MF
deleted file mode 100644
index 57576ed9d5..0000000000
--- a/maven-embedder/src/main/resources/META-INF/MANIFEST.MF
+++ /dev/null
@@ -1,7 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: Maven 2.x Embedder Plug-in
-Bundle-Vendor: maven.org
-Bundle-SymbolicName: org.maven.ide.embedder
-Bundle-Version: ${bundleVersion}
-Bundle-ClassPath: .
diff --git a/maven-embedder/src/main/resources/META-INF/maven/slf4j-configuration.properties b/maven-embedder/src/main/resources/META-INF/maven/slf4j-configuration.properties
index 87418363b1..cd01f9e6bb 100644
--- a/maven-embedder/src/main/resources/META-INF/maven/slf4j-configuration.properties
+++ b/maven-embedder/src/main/resources/META-INF/maven/slf4j-configuration.properties
@@ -18,5 +18,5 @@
 # key = Slf4j effective logger factory implementation
 # value = corresponding o.a.m.cli.logging.Slf4jConfiguration class
 org.slf4j.impl.SimpleLoggerFactory org.apache.maven.cli.logging.impl.Slf4jSimpleConfiguration
-org.slf4j.helpers.Log4jLoggerFactory org.apache.maven.cli.logging.impl.Log4j2Configuration
+org.apache.logging.slf4j.Log4jLoggerFactory org.apache.maven.cli.logging.impl.Log4j2Configuration
 ch.qos.logback.classic.LoggerContext org.apache.maven.cli.logging.impl.LogbackConfiguration
diff --git a/maven-embedder/src/test/java/org/apache/maven/cli/CLIManagerDocumentationTest.java b/maven-embedder/src/test/java/org/apache/maven/cli/CLIManagerDocumentationTest.java
index a06f0a1c58..f58d75b3ff 100644
--- a/maven-embedder/src/test/java/org/apache/maven/cli/CLIManagerDocumentationTest.java
+++ b/maven-embedder/src/test/java/org/apache/maven/cli/CLIManagerDocumentationTest.java
@@ -62,7 +62,7 @@ public int compare( Option opt1, Option opt2 )
 
     public String getOptionsAsHtml()
     {
-        StringBuilder sb = new StringBuilder();
+        StringBuilder sb = new StringBuilder( 512 );
         boolean a = true;
         sb.append( "<table border='1' class='zebra-striped'><tr class='a'><th><b>Options</b></th><th><b>Description</b></th></tr>" );
         for ( Option option : new CLIManagerExtension().getOptions() )
diff --git a/maven-embedder/src/test/java/org/apache/maven/cli/transfer/FileSizeFormatTest.java b/maven-embedder/src/test/java/org/apache/maven/cli/transfer/FileSizeFormatTest.java
new file mode 100644
index 0000000000..44bc1b3992
--- /dev/null
+++ b/maven-embedder/src/test/java/org/apache/maven/cli/transfer/FileSizeFormatTest.java
@@ -0,0 +1,322 @@
+package org.apache.maven.cli.transfer;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Locale;
+
+import org.apache.commons.lang3.JavaVersion;
+import org.apache.commons.lang3.SystemUtils;
+import org.apache.maven.cli.transfer.AbstractMavenTransferListener.FileSizeFormat;
+import org.apache.maven.cli.transfer.AbstractMavenTransferListener.FileSizeFormat.ScaleUnit;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+
+public class FileSizeFormatTest {
+
+    @Test( expected = IllegalArgumentException.class )
+    public void testNegativeSize()
+    {
+        FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
+
+        long negativeSize = -100L;
+        format.format( negativeSize );
+    }
+
+    @Test
+    public void testSize()
+    {
+        FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
+
+        long _0_bytes = 0L;
+        assertEquals( "0 B", format.format( _0_bytes ) );
+
+        long _5_bytes = 5L;
+        assertEquals( "5 B", format.format( _5_bytes ) );
+
+        long _10_bytes = 10L;
+        assertEquals( "10 B", format.format( _10_bytes ) );
+
+        long _15_bytes = 15L;
+        assertEquals( "15 B", format.format( _15_bytes ) );
+
+        long _999_bytes = 999L;
+        assertEquals( "999 B", format.format( _999_bytes ) );
+
+        long _1000_bytes = 1000L;
+        assertEquals( "1.0 kB", format.format( _1000_bytes ) );
+
+        long _5500_bytes = 5500L;
+        assertEquals( "5.5 kB", format.format( _5500_bytes ) );
+
+        long _10_kilobytes = 10L * 1000L;
+        assertEquals( "10 kB", format.format( _10_kilobytes ) );
+
+        long _15_kilobytes = 15L * 1000L;
+        assertEquals( "15 kB", format.format( _15_kilobytes ) );
+
+        long _999_kilobytes = 999L * 1000L;
+        assertEquals( "999 kB", format.format( _999_kilobytes ) );
+
+        long _1000_kilobytes = 1000L * 1000L;
+        assertEquals( "1.0 MB", format.format( _1000_kilobytes ) );
+
+        long _5500_kilobytes = 5500L * 1000L;
+        assertEquals( "5.5 MB", format.format( _5500_kilobytes ) );
+
+        long _10_megabytes = 10L * 1000L * 1000L;
+        assertEquals( "10 MB", format.format( _10_megabytes ) );
+
+        long _15_megabytes = 15L * 1000L * 1000L;
+        assertEquals( "15 MB", format.format( _15_megabytes ) );
+
+        long _999_megabytes = 999L * 1000L * 1000L;
+        assertEquals( "999 MB", format.format( _999_megabytes ) );
+
+        long _1000_megabytes = 1000L * 1000L * 1000L;
+        assertEquals( "1.0 GB", format.format( _1000_megabytes ) );
+
+        long _5500_megabytes = 5500L * 1000L * 1000L;
+        assertEquals( "5.5 GB", format.format( _5500_megabytes ) );
+
+        long _10_gigabytes = 10L * 1000L * 1000L * 1000L;
+        assertEquals( "10 GB", format.format( _10_gigabytes ) );
+
+        long _15_gigabytes = 15L * 1000L * 1000L * 1000L;
+        assertEquals( "15 GB", format.format( _15_gigabytes ) );
+
+        long _1000_gigabytes = 1000L * 1000L * 1000L * 1000L;
+        assertEquals( "1000 GB", format.format( _1000_gigabytes ) );
+    }
+
+    @Test
+    public void testSizeWithSelectedScaleUnit()
+    {
+        FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
+
+        long _0_bytes = 0L;
+        assertEquals( "0 B", format.format( _0_bytes ) );
+        assertEquals( "0 B", format.format( _0_bytes, ScaleUnit.BYTE ) );
+        assertEquals( "0 kB", format.format( _0_bytes, ScaleUnit.KILOBYTE ) );
+        assertEquals( "0 MB", format.format( _0_bytes, ScaleUnit.MEGABYTE ) );
+        assertEquals( "0 GB", format.format( _0_bytes, ScaleUnit.GIGABYTE ) );
+
+        long _5_bytes = 5L;
+        assertEquals( "5 B", format.format( _5_bytes ) );
+        assertEquals( "5 B", format.format( _5_bytes, ScaleUnit.BYTE ) );
+        assertEquals( "0 kB", format.format( _5_bytes, ScaleUnit.KILOBYTE ) );
+        assertEquals( "0 MB", format.format( _5_bytes, ScaleUnit.MEGABYTE ) );
+        assertEquals( "0 GB", format.format( _5_bytes, ScaleUnit.GIGABYTE ) );
+
+
+        long _49_bytes = 49L;
+        assertEquals( "49 B", format.format( _49_bytes ) );
+        assertEquals( "49 B", format.format( _49_bytes, ScaleUnit.BYTE ) );
+        assertEquals( "0 kB", format.format( _49_bytes, ScaleUnit.KILOBYTE ) );
+        assertEquals( "0 MB", format.format( _49_bytes, ScaleUnit.MEGABYTE ) );
+        assertEquals( "0 GB", format.format( _49_bytes, ScaleUnit.GIGABYTE ) );
+
+        long _50_bytes = 50L;
+        assertEquals( "50 B", format.format( _50_bytes ) );
+        assertEquals( "50 B", format.format( _50_bytes, ScaleUnit.BYTE ) );
+        if ( SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_1_8 ) )
+        {
+            assertEquals( "0.1 kB", format.format( _50_bytes, ScaleUnit.KILOBYTE ) );
+        }
+        assertEquals( "0 MB", format.format( _50_bytes, ScaleUnit.MEGABYTE ) );
+        assertEquals( "0 GB", format.format( _50_bytes, ScaleUnit.GIGABYTE ) );
+
+        long _999_bytes = 999L;
+        assertEquals( "999 B", format.format( _999_bytes ) );
+        assertEquals( "999 B", format.format( _999_bytes, ScaleUnit.BYTE ) );
+        assertEquals( "1.0 kB", format.format( _999_bytes, ScaleUnit.KILOBYTE ) );
+        assertEquals( "0 MB", format.format( _999_bytes, ScaleUnit.MEGABYTE ) );
+        assertEquals( "0 GB", format.format( _999_bytes, ScaleUnit.GIGABYTE ) );
+
+        long _1000_bytes = 1000L;
+        assertEquals( "1.0 kB", format.format( _1000_bytes ) );
+        assertEquals( "1000 B", format.format( _1000_bytes, ScaleUnit.BYTE ) );
+        assertEquals( "1.0 kB", format.format( _1000_bytes, ScaleUnit.KILOBYTE ) );
+        assertEquals( "0 MB", format.format( _1000_bytes, ScaleUnit.MEGABYTE ) );
+        assertEquals( "0 GB", format.format( _1000_bytes, ScaleUnit.GIGABYTE ) );
+
+        long _49_kilobytes = 49L * 1000L;
+        assertEquals( "49 kB", format.format( _49_kilobytes ) );
+        assertEquals( "49000 B", format.format( _49_kilobytes, ScaleUnit.BYTE ) );
+        assertEquals( "49 kB", format.format( _49_kilobytes, ScaleUnit.KILOBYTE ) );
+        assertEquals( "0 MB", format.format( _49_kilobytes, ScaleUnit.MEGABYTE ) );
+        assertEquals( "0 GB", format.format( _49_kilobytes, ScaleUnit.GIGABYTE ) );
+
+        long _50_kilobytes = 50L * 1000L;
+        assertEquals( "50 kB", format.format( _50_kilobytes ) );
+        assertEquals( "50000 B", format.format( _50_kilobytes, ScaleUnit.BYTE ) );
+        assertEquals( "50 kB", format.format( _50_kilobytes, ScaleUnit.KILOBYTE ) );
+        if ( SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_1_8 ) )
+        {
+            assertEquals( "0.1 MB", format.format( _50_kilobytes, ScaleUnit.MEGABYTE ) );
+        }
+        assertEquals( "0 GB", format.format( _50_kilobytes, ScaleUnit.GIGABYTE ) );
+
+        long _999_kilobytes = 999L * 1000L;
+        assertEquals( "999 kB", format.format( _999_kilobytes ) );
+        assertEquals( "999000 B", format.format( _999_kilobytes, ScaleUnit.BYTE ) );
+        assertEquals( "999 kB", format.format( _999_kilobytes, ScaleUnit.KILOBYTE ) );
+        assertEquals( "1.0 MB", format.format( _999_kilobytes, ScaleUnit.MEGABYTE ) );
+        assertEquals( "0 GB", format.format( _999_kilobytes, ScaleUnit.GIGABYTE ) );
+
+        long _1000_kilobytes = 1000L * 1000L;
+        assertEquals( "1.0 MB", format.format( _1000_kilobytes ) );
+        assertEquals( "1000000 B", format.format( _1000_kilobytes, ScaleUnit.BYTE ) );
+        assertEquals( "1000 kB", format.format( _1000_kilobytes, ScaleUnit.KILOBYTE ) );
+        assertEquals( "1.0 MB", format.format( _1000_kilobytes, ScaleUnit.MEGABYTE ) );
+        assertEquals( "0 GB", format.format( _1000_kilobytes, ScaleUnit.GIGABYTE ) );
+
+        long _49_megabytes = 49L * 1000L * 1000L;
+        assertEquals( "49 MB", format.format( _49_megabytes ) );
+        assertEquals( "49000000 B", format.format( _49_megabytes, ScaleUnit.BYTE ) );
+        assertEquals( "49000 kB", format.format( _49_megabytes, ScaleUnit.KILOBYTE ) );
+        assertEquals( "49 MB", format.format( _49_megabytes, ScaleUnit.MEGABYTE ) );
+        assertEquals( "0 GB", format.format( _49_megabytes, ScaleUnit.GIGABYTE ) );
+
+        long _50_megabytes = 50L * 1000L * 1000L;
+        assertEquals( "50 MB", format.format( _50_megabytes ) );
+        assertEquals( "50000000 B", format.format( _50_megabytes, ScaleUnit.BYTE ) );
+        assertEquals( "50000 kB", format.format( _50_megabytes, ScaleUnit.KILOBYTE ) );
+        assertEquals( "50 MB", format.format( _50_megabytes, ScaleUnit.MEGABYTE ) );
+        if ( SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_1_8 ) )
+        {
+            assertEquals( "0.1 GB", format.format( _50_megabytes, ScaleUnit.GIGABYTE ) );
+        }
+
+        long _999_megabytes = 999L * 1000L * 1000L;
+        assertEquals( "999 MB", format.format( _999_megabytes ) );
+        assertEquals( "999000000 B", format.format( _999_megabytes, ScaleUnit.BYTE ) );
+        assertEquals( "999000 kB", format.format( _999_megabytes, ScaleUnit.KILOBYTE ) );
+        assertEquals( "999 MB", format.format( _999_megabytes, ScaleUnit.MEGABYTE ) );
+        assertEquals( "1.0 GB", format.format( _999_megabytes, ScaleUnit.GIGABYTE ) );
+
+        long _1000_megabytes = 1000L * 1000L * 1000L;
+        assertEquals( "1.0 GB", format.format( _1000_megabytes ) );
+        assertEquals( "1000000000 B", format.format( _1000_megabytes, ScaleUnit.BYTE ) );
+        assertEquals( "1000000 kB", format.format( _1000_megabytes, ScaleUnit.KILOBYTE ) );
+        assertEquals( "1000 MB", format.format( _1000_megabytes, ScaleUnit.MEGABYTE ) );
+        assertEquals( "1.0 GB", format.format( _1000_megabytes, ScaleUnit.GIGABYTE ) );
+    }
+
+    @Test( expected = IllegalArgumentException.class )
+    public void testNegativeProgessedSize()
+    {
+        FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
+
+        long negativeProgessedSize = -100L;
+        format.formatProgress( negativeProgessedSize, 10L );
+    }
+
+    @Test( expected = IllegalArgumentException.class )
+    public void testNegativeProgessedSizeBiggerThanSize()
+    {
+        FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
+
+        format.formatProgress( 100L, 10L );
+    }
+
+    @Test
+    public void testProgressedSizeWithoutSize()
+    {
+         FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
+
+         long _0_bytes = 0L;
+         assertEquals( "0 B", format.formatProgress( _0_bytes, -1L ) );
+
+         long _1000_bytes = 1000L;
+         assertEquals( "1.0 kB", format.formatProgress( _1000_bytes, -1L ) );
+
+         long _1000_kilobytes = 1000L * 1000L;
+         assertEquals( "1.0 MB", format.formatProgress( _1000_kilobytes, -1L ) );
+
+         long _1000_megabytes = 1000L * 1000L * 1000L;
+         assertEquals( "1.0 GB", format.formatProgress( _1000_megabytes, -1L ) );
+
+    }
+
+    @Test
+    public void testProgressedSizeWithZeroSize()
+    {
+         FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
+
+         long _0_bytes = 0L;
+         assertEquals( "0 B", format.formatProgress( _0_bytes, _0_bytes ) );
+    }
+
+    @Test
+    public void testProgressedSizeZeroAndSizeZero()
+    {
+         FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
+
+         long _0_bytes = 0L;
+         assertEquals( "0 B", format.formatProgress( _0_bytes, _0_bytes ) );
+    }
+
+    @Test
+    public void testProgressedSizeWithSize()
+    {
+         FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
+
+         long _0_bytes = 0L;
+         long _400_bytes = 400L;
+         long _800_bytes = 2L * _400_bytes;
+         assertEquals( "0/800 B", format.formatProgress( _0_bytes, _800_bytes ) );
+         assertEquals( "400/800 B", format.formatProgress( _400_bytes, _800_bytes ) );
+         assertEquals( "800 B", format.formatProgress( _800_bytes, _800_bytes ) );
+
+         long _4000_bytes = 4000L;
+         long _8000_bytes = 2L * _4000_bytes;
+         long _50_kilobytes = 50000L;
+         assertEquals( "0/8.0 kB", format.formatProgress( _0_bytes, _8000_bytes ) );
+         assertEquals( "0.4/8.0 kB", format.formatProgress( _400_bytes, _8000_bytes ) );
+         assertEquals( "4.0/8.0 kB", format.formatProgress( _4000_bytes, _8000_bytes ) );
+         assertEquals( "8.0 kB", format.formatProgress( _8000_bytes, _8000_bytes ) );
+         assertEquals( "8.0/50 kB", format.formatProgress( _8000_bytes, _50_kilobytes ) );
+         assertEquals( "16/50 kB", format.formatProgress( 2L * _8000_bytes, _50_kilobytes ) );
+         assertEquals( "50 kB", format.formatProgress( _50_kilobytes, _50_kilobytes ) );
+
+         long _500_kilobytes = 500000L;
+         long _1000_kilobytes = 2L * _500_kilobytes;;
+         long _5000_kilobytes = 5L * _1000_kilobytes;
+         long _15_megabytes = 3L * _5000_kilobytes;
+         assertEquals( "0/5.0 MB", format.formatProgress( _0_bytes, _5000_kilobytes ) );
+         assertEquals( "0.5/5.0 MB", format.formatProgress( _500_kilobytes, _5000_kilobytes ) );
+         assertEquals( "1.0/5.0 MB", format.formatProgress( _1000_kilobytes, _5000_kilobytes ) );
+         assertEquals( "5.0 MB", format.formatProgress( _5000_kilobytes, _5000_kilobytes ) );
+         assertEquals( "5.0/15 MB", format.formatProgress( _5000_kilobytes, _15_megabytes ) );
+         assertEquals( "15 MB", format.formatProgress( _15_megabytes, _15_megabytes ) );
+
+         long _500_megabytes = 500000000L;
+         long _1000_megabytes = 2L * _500_megabytes;
+         long _5000_megabytes = 5L * _1000_megabytes;
+         long _15_gigabytes = 3L * _5000_megabytes;
+         assertEquals( "0/500 MB", format.formatProgress( _0_bytes, _500_megabytes ) );
+         assertEquals( "1.0/5.0 GB", format.formatProgress( _1000_megabytes, _5000_megabytes ) );
+         assertEquals( "5.0 GB", format.formatProgress( _5000_megabytes, _5000_megabytes ) );
+         assertEquals( "5.0/15 GB", format.formatProgress( _5000_megabytes, _15_gigabytes ) );
+         assertEquals( "15 GB", format.formatProgress( _15_gigabytes, _15_gigabytes ) );
+    }
+
+}
diff --git a/maven-model-builder/pom.xml b/maven-model-builder/pom.xml
index 2d2f94ed65..d88ff78be0 100644
--- a/maven-model-builder/pom.xml
+++ b/maven-model-builder/pom.xml
@@ -16,7 +16,7 @@
   <parent>
     <groupId>org.apache.maven</groupId>
     <artifactId>maven</artifactId>
-    <version>3.3.10-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-model-builder</artifactId>
@@ -71,7 +71,7 @@
     <dependency>
       <groupId>xmlunit</groupId>
       <artifactId>xmlunit</artifactId>
-      <version>1.3</version>
+      <version>1.6</version>
       <scope>test</scope>
     </dependency>
   </dependencies>
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 a6a872570a..df9d2bdb91 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,7 +19,6 @@
  * under the License.
  */
 
-
 import org.apache.commons.lang3.Validate;
 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
@@ -68,6 +67,7 @@
 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;
@@ -84,6 +84,7 @@
 public class DefaultModelBuilder
     implements ModelBuilder
 {
+
     @Requirement
     private ModelProcessor modelProcessor;
 
@@ -250,8 +251,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 );
 
@@ -298,8 +299,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 );
@@ -333,14 +335,14 @@ public ModelBuildingResult build( ModelBuildingRequest request )
                 currentData = superData;
             }
             else if ( currentData == resultData )
-            { // First iteration - add initial parent id after version resolution.
-                currentData.setGroupId( currentData.getRawModel().getGroupId() == null ? parentData.getGroupId()
-                                                                                      : currentData.getRawModel()
-                                                                                          .getGroupId() );
+            { // First iteration - add initial id after version resolution.
+                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() );
@@ -359,8 +361,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();
             }
@@ -373,24 +376,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() );
@@ -404,6 +417,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() )
@@ -417,21 +431,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, 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 );
 
@@ -451,9 +485,6 @@ private ModelBuildingResult build( ModelBuildingRequest request, ModelBuildingRe
             lifecycleBindingsInjector.injectLifecycleBindings( resultModel, request, problems );
         }
 
-        // dependency management import
-        importDependencyManagement( resultModel, request, problems, imports );
-
         // dependency management injection
         dependencyManagementInjector.injectManagement( resultModel, request, problems );
 
@@ -485,10 +516,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() );
@@ -553,15 +587,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 ) );
+
                 }
             }
 
@@ -573,14 +609,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
@@ -593,14 +631,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 ) )
@@ -632,92 +674,185 @@ private void configureResolver( ModelResolver modelResolver, Model model, Defaul
     private void configureResolver( ModelResolver modelResolver, Model model, DefaultModelProblemCollector problems,
                                     boolean replaceRepositories )
     {
-        if ( modelResolver == null )
+        if ( modelResolver != null )
         {
-            return;
-        }
+            problems.setSource( model );
 
-        problems.setSource( model );
+            List<Repository> repositories = model.getRepositories();
 
-        List<Repository> repositories = model.getRepositories();
+            for ( Repository repository : repositories )
+            {
+                try
+                {
+                    modelResolver.addRepository( repository, replaceRepositories );
+                }
+                catch ( InvalidRepositoryException e )
+                {
+                    problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).
+                        setMessage( "Invalid repository " + repository.getId() + ": " + e.getMessage() ).
+                        setLocation( repository.getLocation( "" ) ).
+                        setException( e ) );
 
-        for ( Repository repository : repositories )
+                }
+            }
+        }
+    }
+
+    private void checkPluginVersions( List<ModelData> lineage, ModelBuildingRequest request,
+                                      ModelProblemCollector problems )
+    {
+        if ( request.getValidationLevel() >= ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 )
         {
-            try
+            Map<String, Plugin> plugins = new HashMap<>();
+            Map<String, String> versions = new HashMap<>();
+            Map<String, String> managedVersions = new HashMap<>();
+
+            for ( int i = lineage.size() - 1; i >= 0; i-- )
             {
-                modelResolver.addRepository( repository, replaceRepositories );
+                Model model = lineage.get( i ).getModel();
+                Build build = model.getBuild();
+                if ( build != null )
+                {
+                    for ( Plugin plugin : build.getPlugins() )
+                    {
+                        String key = plugin.getKey();
+                        if ( versions.get( key ) == null )
+                        {
+                            versions.put( key, plugin.getVersion() );
+                            plugins.put( key, plugin );
+                        }
+                    }
+                    PluginManagement mngt = build.getPluginManagement();
+                    if ( mngt != null )
+                    {
+                        for ( Plugin plugin : mngt.getPlugins() )
+                        {
+                            String key = plugin.getKey();
+                            if ( managedVersions.get( key ) == null )
+                            {
+                                managedVersions.put( key, plugin.getVersion() );
+                            }
+                        }
+                    }
+                }
             }
-            catch ( InvalidRepositoryException e )
+
+            for ( String key : versions.keySet() )
             {
-                problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
-                    .setMessage( "Invalid repository " + repository.getId() + ": " + e.getMessage() )
-                    .setLocation( repository.getLocation( "" ) ).setException( e ) );
+                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 ) );
+
+                }
             }
         }
     }
 
-    private void checkPluginVersions( List<ModelData> lineage, ModelBuildingRequest request,
-                                      ModelProblemCollector problems )
+    private void processImports( final List<Model> lineage, final ModelBuildingRequest request,
+                                 final DefaultModelProblemCollector problems )
     {
-        if ( request.getValidationLevel() < ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 )
+        // [MNG-5971] Imported dependencies should be available to inheritance processing
+
+        // Creates an intermediate model with only property and repository inheritance.
+        final List<Model> intermediateLineage = new ArrayList<>( lineage.size() );
+
+        for ( int i = 0, s0 = lineage.size(); i < s0; i++ )
         {
-            return;
+            intermediateLineage.add( lineage.get( i ).clone() );
         }
 
-        Map<String, Plugin> plugins = new HashMap<>();
-        Map<String, String> versions = new HashMap<>();
-        Map<String, String> managedVersions = new HashMap<>();
-
-        for ( int i = lineage.size() - 1; i >= 0; i-- )
+        for ( int i = intermediateLineage.size() - 2; i >= 0; i-- )
         {
-            Model model = lineage.get( i ).getModel();
-            Build build = model.getBuild();
-            if ( build != null )
+            final Model parent = intermediateLineage.get( i + 1 );
+            final Model child = intermediateLineage.get( i );
+
+            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() )
             {
-                for ( Plugin plugin : build.getPlugins() )
+                if ( !repositories.contains( parentRepository ) )
                 {
-                    String key = plugin.getKey();
-                    if ( versions.get( key ) == null )
-                    {
-                        versions.put( key, plugin.getVersion() );
-                        plugins.put( key, plugin );
-                    }
+                    repositories.add( parentRepository );
                 }
-                PluginManagement mngt = build.getPluginManagement();
-                if ( mngt != null )
+            }
+
+            child.setRepositories( repositories );
+        }
+
+        final DefaultModelProblemCollector intermediateProblems =
+            new DefaultModelProblemCollector( new DefaultModelBuildingResult() );
+
+        // Interpolates the intermediate model.
+        for ( int i = 0, s0 = intermediateLineage.size(); i < s0; i++ )
+        {
+            final Model model = intermediateLineage.get( i );
+            intermediateProblems.setSource( model );
+            this.interpolateModel( model, request, intermediateProblems );
+        }
+
+        // Exchanges 'import' 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++ )
                 {
-                    for ( Plugin plugin : mngt.getPlugins() )
+                    final Dependency dependency = model.getDependencyManagement().getDependencies().get( j );
+
+                    if ( "import".equals( dependency.getScope() ) && "pom".equals( dependency.getType() ) )
                     {
-                        String key = plugin.getKey();
-                        if ( managedVersions.get( key ) == null )
-                        {
-                            managedVersions.put( key, plugin.getVersion() );
-                        }
+                        final Dependency interpolated =
+                            intermediateLineage.get( i ).getDependencyManagement().getDependencies().get( j );
+
+                        model.getDependencyManagement().getDependencies().set( j, interpolated );
                     }
                 }
             }
         }
 
-        for ( String key : versions.keySet() )
+        // [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 )
         {
-            if ( versions.get( key ) == null && managedVersions.get( key ) == null )
+            lenientRequest = new FilterModelBuildingRequest( request )
             {
-                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 ) );
-            }
+
+                @Override
+                public int getValidationLevel()
+                {
+                    return ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0;
+                }
+
+            };
+        }
+
+        // Imports dependencies into the original model using the repositories of the intermediate model.
+        for ( int i = 0, s0 = lineage.size(), superModelIdx = lineage.size() - 1; i < s0; i++ )
+        {
+            final Model model = lineage.get( i );
+            this.configureResolver( lenientRequest.getModelResolver(), intermediateLineage.get( i ), problems, true );
+            this.importDependencyManagement( model, "import", lenientRequest, problems, new HashSet<String>() );
         }
     }
 
-    private void assembleInheritance( List<ModelData> lineage, ModelBuildingRequest request,
+    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 );
         }
     }
@@ -817,7 +952,7 @@ private ModelData readParent( Model childModel, ModelSource childSource, ModelBu
                     ModelSource expectedParentSource = getParentPomFile( childModel, childSource );
 
                     if ( expectedParentSource instanceof ModelSource2
-                        && !pomFile.toURI().equals( ( (ModelSource2) expectedParentSource ).getLocationURI() ) )
+                             && !pomFile.toURI().equals( ( (ModelSource2) expectedParentSource ).getLocationURI() ) )
                     {
                         parentData = readParentExternally( childModel, request, problems );
                     }
@@ -828,10 +963,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
@@ -873,11 +1009,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 )
@@ -892,7 +1032,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 )
         {
@@ -906,7 +1045,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'" );
@@ -914,13 +1053,15 @@ private ModelData readParentLocally( Model childModel, ModelSource childSource,
             {
                 buffer.append( " of POM " ).append( ModelProblemUtils.toSourceHint( childModel ) );
             }
-            buffer.append( " points at " ).append( groupId ).append( ":" ).append( artifactId );
-            buffer.append( " instead of " ).append( parent.getGroupId() ).append( ":" );
+            buffer.append( " points at " ).append( groupId ).append( ':' ).append( artifactId );
+            buffer.append( " instead of " ).append( parent.getGroupId() ).append( ':' );
             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() ) )
@@ -938,6 +1079,27 @@ private ModelData readParentLocally( Model childModel, ModelSource childSource,
                     // version skew drop back to resolution from the repository
                     return null;
                 }
+
+                // Validate versions aren't inherited when using parent ranges the same way as when read externally.
+                if ( childModel.getVersion() == null )
+                {
+                    problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.V31 ).
+                        setMessage( "Version must be a constant" ).
+                        setLocation( childModel.getLocation( "" ) ) );
+
+                }
+                else
+                {
+                    if ( childModel.getVersion().contains( "${" ) )
+                    {
+                        problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.V31 ).
+                            setMessage( "Version must be a constant" ).
+                            setLocation( childModel.getLocation( "version" ) ) );
+
+                    }
+                }
+
+                // MNG-2199: What else to check here ?
             }
             catch ( InvalidVersionSpecificationException e )
             {
@@ -954,7 +1116,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;
@@ -992,7 +1153,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
@@ -1005,7 +1167,7 @@ private ModelData readParentExternally( Model childModel, ModelBuildingRequest r
             buffer.append( "Non-resolvable parent POM" );
             if ( !containsCoordinates( e.getMessage(), groupId, artifactId, version ) )
             {
-                buffer.append( " " ).append( ModelProblemUtils.toId( groupId, artifactId, version ) );
+                buffer.append( ' ' ).append( ModelProblemUtils.toId( groupId, artifactId, version ) );
             }
             if ( childModel != problems.getRootModel() )
             {
@@ -1024,8 +1186,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();
         }
 
@@ -1034,11 +1199,13 @@ private ModelData readParentExternally( Model childModel, ModelBuildingRequest r
         {
             lenientRequest = new FilterModelBuildingRequest( request )
             {
+
                 @Override
                 public int getValidationLevel()
                 {
                     return ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0;
                 }
+
             };
         }
 
@@ -1048,18 +1215,18 @@ public int getValidationLevel()
         {
             if ( childModel.getVersion() == null )
             {
-                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
             {
-                if ( childModel.getVersion()
-                               .contains( "${" ) )
+                if ( childModel.getVersion().contains( "${" ) )
                 {
-                    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" ) ) );
 
                 }
             }
@@ -1078,185 +1245,213 @@ private Model getSuperModel()
         return superPomProvider.getSuperModel( "4.0.0" ).clone();
     }
 
-    private void importDependencyManagement( Model model, ModelBuildingRequest request,
+    private void importDependencyManagement( Model model, String scope, ModelBuildingRequest request,
                                              DefaultModelProblemCollector problems, Collection<String> importIds )
     {
         DependencyManagement depMngt = model.getDependencyManagement();
 
-        if ( depMngt == null )
+        if ( depMngt != null )
         {
-            return;
-        }
+            problems.setSource( model );
 
-        String importing = model.getGroupId() + ':' + model.getArtifactId() + ':' + model.getVersion();
+            String importing = model.getGroupId() + ':' + model.getArtifactId() + ':' + model.getVersion();
 
-        importIds.add( importing );
+            importIds.add( importing );
 
-        final WorkspaceModelResolver workspaceResolver = request.getWorkspaceModelResolver();
-        final ModelResolver modelResolver = request.getModelResolver();
+            final WorkspaceModelResolver workspaceResolver = request.getWorkspaceModelResolver();
+            final ModelResolver modelResolver = request.getModelResolver();
 
-        ModelBuildingRequest importRequest = null;
+            ModelBuildingRequest importRequest = null;
 
-        List<DependencyManagement> importMngts = null;
-
-        for ( Iterator<Dependency> it = depMngt.getDependencies().iterator(); it.hasNext(); )
-        {
-            Dependency dependency = it.next();
+            List<DependencyManagement> importMngts = null;
 
-            if ( !"pom".equals( dependency.getType() ) || !"import".equals( dependency.getScope() ) )
+            for ( Iterator<Dependency> it = depMngt.getDependencies().iterator(); it.hasNext(); )
             {
-                continue;
-            }
+                Dependency dependency = it.next();
 
-            it.remove();
+                if ( !"pom".equals( dependency.getType() ) || !scope.equals( dependency.getScope() ) )
+                {
+                    continue;
+                }
 
-            String groupId = dependency.getGroupId();
-            String artifactId = dependency.getArtifactId();
-            String version = dependency.getVersion();
+                it.remove();
 
-            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( "" ) ) );
-                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( "" ) ) );
-                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( "" ) ) );
-                continue;
-            }
+                String groupId = dependency.getGroupId();
+                String artifactId = dependency.getArtifactId();
+                String version = dependency.getVersion();
 
-            String imported = groupId + ':' + artifactId + ':' + version;
-
-            if ( importIds.contains( imported ) )
-            {
-                String message = "The dependencies of type=pom and with scope=import form a cycle: ";
-                for ( String modelId : importIds )
+                if ( groupId == null || groupId.length() <= 0 )
                 {
-                    message += modelId + " -> ";
-                }
-                message += imported;
-                problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).setMessage( message ) );
-
-                continue;
-            }
+                    problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
+                        .setMessage( "'dependencyManagement.dependencies.dependency.groupId' for "
+                                         + dependency.getManagementKey() + " is missing." )
+                        .setLocation( dependency.getLocation( "" ) ) );
 
-            DependencyManagement importMngt = getCache( request.getModelCache(), groupId, artifactId, version,
-                                                        ModelCacheTag.IMPORT );
+                    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( "" ) ) );
 
-            if ( importMngt == null )
-            {
-                if ( workspaceResolver == null && modelResolver == null )
+                    continue;
+                }
+                if ( version == null || version.length() <= 0 )
                 {
-                    throw new NullPointerException( String.format(
-                        "request.workspaceModelResolver and request.modelResolver cannot be null"
-                        + " (parent POM %s and POM %s)",
-                        ModelProblemUtils.toId( groupId, artifactId, version ),
-                        ModelProblemUtils.toSourceHint( model ) ) );
+                    problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).
+                        setMessage( "'dependencyManagement.dependencies.dependency.version' for "
+                                        + dependency.getManagementKey() + " is missing." ).
+                        setLocation( dependency.getLocation( "" ) ) );
+
+                    continue;
                 }
 
-                Model importModel = null;
-                if ( workspaceResolver != null )
+                String imported = groupId + ':' + artifactId + ':' + version;
+
+                if ( importIds.contains( imported ) )
                 {
-                    try
+                    String message = "The dependencies of type=pom and scope=" + scope + " form a cycle: ";
+                    for ( String modelId : importIds )
                     {
-                        importModel = workspaceResolver.resolveEffectiveModel( groupId, artifactId, version );
-                    }
-                    catch ( UnresolvableModelException e )
-                    {
-                        problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.BASE )
-                            .setMessage( e.getMessage().toString() ).setException( e ) );
-                        continue;
+                        message += modelId + " -> ";
                     }
+                    message += imported;
+                    problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).
+                        setMessage( message ) );
+
+                    continue;
                 }
 
-                // no workspace resolver or workspace resolver returned null (i.e. model not in workspace)
-                if ( importModel == null )
+                DependencyManagement importMngt = getCache( request.getModelCache(), groupId, artifactId, version,
+                                                            ModelCacheTag.IMPORT );
+
+                if ( importMngt == null )
                 {
-                    final ModelSource importSource;
-                    try
+                    if ( workspaceResolver == null && modelResolver == null )
                     {
-                        importSource = modelResolver.resolveModel( groupId, artifactId, version );
+                        throw new NullPointerException( String.format(
+                            "request.workspaceModelResolver and request.modelResolver cannot be null"
+                                + " (parent POM %s and POM %s)",
+                            ModelProblemUtils.toId( groupId, artifactId, version ),
+                            ModelProblemUtils.toSourceHint( model ) ) );
+
                     }
-                    catch ( UnresolvableModelException e )
+
+                    Model importModel = null;
+                    if ( workspaceResolver != null )
                     {
-                        StringBuilder buffer = new StringBuilder( 256 );
-                        buffer.append( "Non-resolvable import POM" );
-                        if ( !containsCoordinates( e.getMessage(), groupId, artifactId, version ) )
+                        try
                         {
-                            buffer.append( " " ).append( ModelProblemUtils.toId( groupId, artifactId, version ) );
+                            importModel = workspaceResolver.resolveEffectiveModel( groupId, artifactId, version );
                         }
-                        buffer.append( ": " ).append( e.getMessage() );
+                        catch ( UnresolvableModelException e )
+                        {
+                            problems.add( new ModelProblemCollectorRequest( Severity.FATAL, Version.BASE ).
+                                setMessage( e.getMessage() ).
+                                setException( e ) );
 
-                        problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE )
-                            .setMessage( buffer.toString() ).setLocation( dependency.getLocation( "" ) )
-                            .setException( e ) );
-                        continue;
+                            continue;
+                        }
                     }
 
-                    if ( importRequest == null )
+                    // no workspace resolver or workspace resolver returned null (i.e. model not in workspace)
+                    if ( importModel == null )
                     {
-                        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() );
-                    }
+                        final ModelSource importSource;
+                        try
+                        {
+                            dependency = dependency.clone();
+                            importSource = modelResolver.resolveModel( dependency );
+                            final String resolvedId =
+                                dependency.getGroupId() + ':' + dependency.getArtifactId() + ':'
+                                    + dependency.getVersion();
+
+                            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=" + scope + " form a cycle: ";
+                                for ( String modelId : importIds )
+                                {
+                                    message += modelId + " -> ";
+                                }
+                                message += resolvedId;
+                                problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).
+                                    setMessage( message ) );
+
+                                continue;
+                            }
+                        }
+                        catch ( UnresolvableModelException e )
+                        {
+                            StringBuilder buffer = new StringBuilder( 256 );
+                            buffer.append( "Non-resolvable " + scope + " POM" );
+                            if ( !containsCoordinates( e.getMessage(), groupId, artifactId, version ) )
+                            {
+                                buffer.append( ' ' ).append( ModelProblemUtils.toId( groupId, artifactId, version ) );
+                            }
+                            buffer.append( ": " ).append( e.getMessage() );
+
+                            problems.add( new ModelProblemCollectorRequest( Severity.ERROR, Version.BASE ).
+                                setMessage( buffer.toString() ).
+                                setLocation( dependency.getLocation( "" ) ).
+                                setException( e ) );
+
+                            continue;
+                        }
 
-                    importRequest.setModelSource( importSource );
-                    importRequest.setModelResolver( modelResolver.newCopy() );
+                        if ( importRequest == null )
+                        {
+                            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() );
+                        }
 
-                    final ModelBuildingResult importResult;
-                    try
-                    {
-                        importResult = build( importRequest );
+                        importRequest.setModelSource( importSource );
+                        importRequest.setModelResolver( modelResolver.newCopy() );
+
+                        final ModelBuildingResult importResult;
+                        try
+                        {
+                            importResult = build( importRequest );
+                        }
+                        catch ( ModelBuildingException e )
+                        {
+                            problems.addAll( e.getProblems() );
+                            continue;
+                        }
+
+                        problems.addAll( importResult.getProblems() );
+
+                        importModel = importResult.getEffectiveModel();
                     }
-                    catch ( ModelBuildingException e )
+
+                    importMngt = importModel.getDependencyManagement();
+
+                    if ( importMngt == null )
                     {
-                        problems.addAll( e.getProblems() );
-                        continue;
+                        importMngt = new DependencyManagement();
                     }
 
-                    problems.addAll( importResult.getProblems() );
-
-                    importModel = importResult.getEffectiveModel();
+                    putCache( request.getModelCache(), groupId, artifactId, version, ModelCacheTag.IMPORT, importMngt );
                 }
 
-                importMngt = importModel.getDependencyManagement();
-
-                if ( importMngt == null )
+                if ( importMngts == null )
                 {
-                    importMngt = new DependencyManagement();
+                    importMngts = new ArrayList<>();
                 }
 
-                putCache( request.getModelCache(), groupId, artifactId, version, ModelCacheTag.IMPORT, importMngt );
+                importMngts.add( importMngt );
             }
 
-            if ( importMngts == null )
-            {
-                importMngts = new ArrayList<>();
-            }
+            importIds.remove( importing );
 
-            importMngts.add( importMngt );
+            dependencyManagementImporter.importManagement( model, importMngts, request, problems );
         }
-
-        importIds.remove( importing );
-
-        dependencyManagementImporter.importManagement( model, importMngts, request, problems );
     }
 
     private <T> void putCache( ModelCache modelCache, String groupId, String artifactId, String version,
@@ -1298,9 +1493,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/DefaultModelBuilderFactory.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java
index 36a0f46a1b..313d307d58 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelBuilderFactory.java
@@ -108,8 +108,11 @@ protected ProfileSelector newProfileSelector()
 
     protected ProfileActivator[] newProfileActivators()
     {
-        return new ProfileActivator[] { new JdkVersionProfileActivator(), new OperatingSystemProfileActivator(),
-            new PropertyProfileActivator(), new FileProfileActivator().setPathTranslator( newPathTranslator() ) };
+        return new ProfileActivator[]
+        {
+            new JdkVersionProfileActivator(), new OperatingSystemProfileActivator(),
+            new PropertyProfileActivator(), new FileProfileActivator().setPathTranslator( newPathTranslator() )
+        };
     }
 
     protected UrlNormalizer newUrlNormalizer()
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 7bf45b5fbb..fe1c7ae858 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 @@ public DefaultModelBuildingResult()
         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/DefaultModelProblem.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblem.java
index 0892f0a580..78e81e380c 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblem.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblem.java
@@ -165,7 +165,7 @@ public String toString()
     {
         StringBuilder buffer = new StringBuilder( 128 );
 
-        buffer.append( "[" ).append( getSeverity() ).append( "] " );
+        buffer.append( '[' ).append( getSeverity() ).append( "] " );
         buffer.append( getMessage() );
         buffer.append( " @ " ).append( ModelProblemUtils.formatLocation( this, null ) );
 
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblemCollector.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblemCollector.java
index 89d5cb2184..16740dc110 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblemCollector.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/DefaultModelProblemCollector.java
@@ -146,7 +146,7 @@ public void add( ModelProblemCollectorRequest req )
     {
         int line = -1;
         int column = -1;
-        String source = null;
+        String src = null;
         String modelId = null;
 
         if ( req.getLocation() != null )
@@ -156,15 +156,17 @@ public void add( ModelProblemCollectorRequest req )
             if ( req.getLocation().getSource() != null )
             {
                 modelId = req.getLocation().getSource().getModelId();
-                source = req.getLocation().getSource().getLocation();
+                src = req.getLocation().getSource().getLocation();
             }
         }
 
-        if ( modelId == null )
-        {
-            modelId = getModelId();
-            source = getSource();
-        }
+        modelId = modelId != null
+                      ? this.getModelId() + " [" + modelId + "]"
+                      : this.getModelId();
+
+        src = src != null
+                  ? this.getSource() + " [" + src + "]"
+                  : this.getSource();
 
         if ( line <= 0 && column <= 0 && req.getException() instanceof ModelParseException )
         {
@@ -174,7 +176,7 @@ public void add( ModelProblemCollectorRequest req )
         }
 
         ModelProblem problem =
-            new DefaultModelProblem( req.getMessage(), req.getSeverity(), req.getVersion(), source, line, column,
+            new DefaultModelProblem( req.getMessage(), req.getSeverity(), req.getVersion(), src, line, column,
                                      modelId, req.getException() );
 
         add( problem );
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuilder.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuilder.java
index 2a49a213f7..3cce61649a 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuilder.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuilder.java
@@ -56,11 +56,7 @@ ModelBuildingResult build( ModelBuildingRequest request, ModelBuildingResult res
         throws ModelBuildingException;
 
     /**
-     * Performs only the part of {@link ModelBuilder#build(ModelBuildingRequest)} that loads the raw model
-     *
-     * @param request
-     * @return
-     * @throws ModelBuildingException
+     * Performs only the part of {@link ModelBuilder#build(ModelBuildingRequest)} that loads the raw model.
      */
     Result<? extends Model> buildRawModel( File pomFile, int validationLevel, boolean locationTracking );
 
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/ModelBuildingRequest.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java
index c10274dbce..8b51d4535c 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelBuildingRequest.java
@@ -73,8 +73,6 @@
 
     /**
      * Set raw model.
-     *
-     * @param model
      */
     ModelBuildingRequest setRawModel( Model rawModel );
 
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..f86b6ec284 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.4
+     */
+    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/building/ModelCacheTag.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java
index 8452f96718..e57db8ec93 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelCacheTag.java
@@ -51,6 +51,7 @@
      * cache is populated but the state of the cache must not change so we need to make a copy.
      *
      * @param data The data to store in the cache, must not be {@code null}.
+     *
      * @return The data being stored in the cache, never {@code null}.
      */
     T intoCache( T data );
@@ -60,6 +61,7 @@
      * cache is queried but the state of the cache must not change so we need to make a copy.
      *
      * @param data The data to retrieve from the cache, must not be {@code null}.
+     *
      * @return The data being retrieved from the cache, never {@code null}.
      */
     T fromCache( T data );
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemUtils.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemUtils.java
index 806c28d474..76c23e1fde 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemUtils.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/ModelProblemUtils.java
@@ -51,7 +51,7 @@ static String toSourceHint( Model model )
         File pomFile = model.getPomFile();
         if ( pomFile != null )
         {
-            buffer.append( " (" ).append( pomFile ).append( ")" );
+            buffer.append( " (" ).append( pomFile ).append( ')' );
         }
 
         return buffer.toString();
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/building/Result.java b/maven-model-builder/src/main/java/org/apache/maven/model/building/Result.java
index 282887431e..041b0d6c0f 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/building/Result.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/building/Result.java
@@ -54,10 +54,7 @@
 {
 
     /**
-     * Success without warnings
-     * 
-     * @param model
-     * @return
+     * Success without warnings.
      */
     public static <T> Result<T> success( T model )
     {
@@ -65,11 +62,7 @@
     }
 
     /**
-     * Success with warnings
-     * 
-     * @param model
-     * @param problems
-     * @return
+     * Success with warnings.
      */
     public static <T> Result<T> success( T model, Iterable<? extends ModelProblem> problems )
     {
@@ -78,11 +71,7 @@
     }
 
     /**
-     * Success with warnings
-     * 
-     * @param model
-     * @param results
-     * @return
+     * Success with warnings.
      */
     public static <T> Result<T> success( T model, Result<?>... results )
     {
@@ -90,10 +79,7 @@
     }
 
     /**
-     * Error with problems describing the cause
-     *
-     * @param problems
-     * @return
+     * Error with problems describing the cause.
      */
     public static <T> Result<T> error( Iterable<? extends ModelProblem> problems )
     {
@@ -116,11 +102,7 @@
     }
 
     /**
-     * Error with partial result and problems describing the cause
-     *
-     * @param model
-     * @param problems
-     * @return
+     * Error with partial result and problems describing the cause.
      */
     public static <T> Result<T> error( T model, Iterable<? extends ModelProblem> problems )
     {
@@ -128,11 +110,7 @@
     }
 
     /**
-     * New result - determine whether error or success by checking problems for errors
-     * 
-     * @param model
-     * @param problems
-     * @return
+     * New result - determine whether error or success by checking problems for errors.
      */
     public static <T> Result<T> newResult( T model, Iterable<? extends ModelProblem> problems )
     {
@@ -142,10 +120,6 @@
     /**
      * New result consisting of given result and new problem. Convenience for newResult(result.get(),
      * concat(result.getProblems(),problems)).
-     * 
-     * @param result
-     * @param problem
-     * @return
      */
     public static <T> Result<T> addProblem( Result<T> result, ModelProblem problem )
     {
@@ -153,11 +127,7 @@
     }
 
     /**
-     * New result that includes the given
-     *
-     * @param result
-     * @param problems
-     * @return
+     * New result that includes the given.
      */
     public static <T> Result<T> addProblems( Result<T> result, Iterable<? extends ModelProblem> problems )
     {
@@ -172,9 +142,6 @@
 
     /**
      * Turns the given results into a single result by combining problems and models into single collection.
-     * 
-     * @param results
-     * @return
      */
     public static <T> Result<Iterable<T>> newResultSet( Iterable<? extends Result<? extends T>> results )
     {
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 d895913eb6..6c361d36ad 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
@@ -19,7 +19,6 @@
  * under the License.
  */
 
-import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -42,41 +41,34 @@
 {
 
     @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<>();
 
-            DependencyManagement depMngt = target.getDependencyManagement();
-
-            if ( depMngt != null )
+            if ( target.getDependencyManagement() != null )
             {
-                for ( Dependency dependency : depMngt.getDependencies() )
+                for ( final Dependency targetDependency : target.getDependencyManagement().getDependencies() )
                 {
-                    dependencies.put( dependency.getManagementKey(), dependency );
+                    targetDependencies.put( targetDependency.getManagementKey(), targetDependency );
                 }
             }
-            else
-            {
-                depMngt = new DependencyManagement();
-                target.setDependencyManagement( depMngt );
-            }
 
-            for ( DependencyManagement source : sources )
+            for ( final DependencyManagement source : sources )
             {
-                for ( Dependency dependency : source.getDependencies() )
+                for ( final Dependency sourceDependency : source.getDependencies() )
                 {
-                    String key = dependency.getManagementKey();
-                    if ( !dependencies.containsKey( key ) )
+                    if ( !targetDependencies.containsKey( sourceDependency.getManagementKey() ) )
                     {
-                        dependencies.put( key, dependency );
+                        targetDependencies.put( sourceDependency.getManagementKey(), sourceDependency );
                     }
                 }
             }
 
-            depMngt.setDependencies( new ArrayList<>( dependencies.values() ) );
+            target.setDependencyManagement( new DependencyManagement() );
+            target.getDependencyManagement().getDependencies().addAll( targetDependencies.values() );
         }
     }
 
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/DefaultInheritanceAssembler.java b/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/DefaultInheritanceAssembler.java
index 6cf476080e..58d93a77e5 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/DefaultInheritanceAssembler.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/inheritance/DefaultInheritanceAssembler.java
@@ -19,14 +19,16 @@
  * under the License.
  */
 
-import java.io.File;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 
+import org.apache.maven.model.InputLocation;
 import org.apache.maven.model.Model;
+import org.apache.maven.model.ModelBase;
 import org.apache.maven.model.Plugin;
 import org.apache.maven.model.PluginContainer;
 import org.apache.maven.model.ReportPlugin;
@@ -49,12 +51,18 @@
 
     private InheritanceModelMerger merger = new InheritanceModelMerger();
 
+    private static final String CHILD_DIRECTORY = "child-directory";
+
+    private static final String CHILD_DIRECTORY_PROPERTY = "project.directory";
+
     @Override
     public void assembleModelInheritance( Model child, Model parent, ModelBuildingRequest request,
                                           ModelProblemCollector problems )
     {
         Map<Object, Object> hints = new HashMap<>();
-        hints.put( MavenModelMerger.CHILD_PATH_ADJUSTMENT, getChildPathAdjustment( child, parent ) );
+        String childPath = child.getProperties().getProperty( CHILD_DIRECTORY_PROPERTY, child.getArtifactId() );
+        hints.put( CHILD_DIRECTORY, childPath );
+        hints.put( MavenModelMerger.CHILD_PATH_ADJUSTMENT, getChildPathAdjustment( child, parent, childPath ) );
         merger.merge( child, parent, false, hints );
     }
 
@@ -76,7 +84,7 @@ public void assembleModelInheritance( Model child, Model parent, ModelBuildingRe
      * @param parent The parent model, may be <code>null</code>.
      * @return The path adjustment, can be empty but never <code>null</code>.
      */
-    private String getChildPathAdjustment( Model child, Model parent )
+    private String getChildPathAdjustment( Model child, Model parent, String childDirectory )
     {
         String adjustment = "";
 
@@ -91,10 +99,9 @@ private String getChildPathAdjustment( Model child, Model parent )
              * repository. In other words, modules where artifactId != moduleDirName will see different effective URLs
              * depending on how the model was constructed (from filesystem or from repository).
              */
-            File childDirectory = child.getProjectDirectory();
-            if ( childDirectory != null )
+            if ( child.getProjectDirectory() != null )
             {
-                childName = childDirectory.getName();
+                childName = child.getProjectDirectory().getName();
             }
 
             for ( String module : parent.getModules() )
@@ -116,7 +123,7 @@ private String getChildPathAdjustment( Model child, Model parent )
 
                 moduleName = moduleName.substring( lastSlash + 1 );
 
-                if ( moduleName.equals( childName ) && lastSlash >= 0 )
+                if ( ( moduleName.equals( childName ) || ( moduleName.equals( childDirectory ) ) ) && lastSlash >= 0 )
                 {
                     adjustment = module.substring( 0, lastSlash );
                     break;
@@ -134,18 +141,16 @@ private String getChildPathAdjustment( Model child, Model parent )
         @Override
         protected String extrapolateChildUrl( String parentUrl, Map<Object, Object> context )
         {
-            Object artifactId = context.get( ARTIFACT_ID );
+            Object childDirectory = context.get( CHILD_DIRECTORY );
             Object childPathAdjustment = context.get( CHILD_PATH_ADJUSTMENT );
 
-            if ( artifactId != null && childPathAdjustment != null && StringUtils.isNotBlank( parentUrl ) )
-            {
-                // append childPathAdjustment and artifactId to parent url
-                return appendPath( parentUrl, artifactId.toString(), childPathAdjustment.toString() );
-            }
-            else
+            if ( StringUtils.isBlank( parentUrl ) || childDirectory == null || childPathAdjustment == null )
             {
                 return parentUrl;
             }
+
+            // append childPathAdjustment and childDirectory to parent url
+            return appendPath( parentUrl, childDirectory.toString(), childPathAdjustment.toString() );
         }
 
         private String appendPath( String parentUrl, String childPath, String pathAdjustment )
@@ -191,6 +196,38 @@ else if ( !initialUrlEndsWithSlash )
             }
         }
 
+        @Override
+        protected void mergeModelBase_Properties( ModelBase target, ModelBase source, boolean sourceDominant,
+                                                  Map<Object, Object> context )
+        {
+            Properties merged = new Properties();
+            if ( sourceDominant )
+            {
+                merged.putAll( target.getProperties() );
+                putAll( merged, source.getProperties(), CHILD_DIRECTORY_PROPERTY );
+            }
+            else
+            {
+                putAll( merged, source.getProperties(), CHILD_DIRECTORY_PROPERTY );
+                merged.putAll( target.getProperties() );
+            }
+            target.setProperties( merged );
+            target.setLocation( "properties",
+                                InputLocation.merge( target.getLocation( "properties" ),
+                                                     source.getLocation( "properties" ), sourceDominant ) );
+        }
+
+        private void putAll( Map<Object, Object> s, Map<Object, Object> t, Object excludeKey )
+        {
+            for ( Map.Entry<Object, Object> e : t.entrySet() )
+            {
+                if ( !e.getKey().equals( excludeKey ) )
+                {
+                    s.put( e.getKey(), e.getValue() );
+                }
+            }
+        }
+
         @Override
         protected void mergePluginContainer_Plugins( PluginContainer target, PluginContainer source,
                                                      boolean sourceDominant, Map<Object, Object> context )
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 e611973072..731cdd8f27 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
@@ -81,13 +81,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/java/org/apache/maven/model/profile/activation/PropertyProfileActivator.java b/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/PropertyProfileActivator.java
index ba7886f074..8d5ec13841 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/PropertyProfileActivator.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/profile/activation/PropertyProfileActivator.java
@@ -80,6 +80,10 @@ public boolean isActive( Profile profile, ProfileActivationContext context, Mode
         {
             sysValue = context.getSystemProperties().get( name );
         }
+        if ( sysValue == null )
+        {
+            sysValue = context.getProjectProperties().get( name );
+        }
 
         String propValue = property.getValue();
         if ( StringUtils.isNotEmpty( propValue ) )
@@ -90,9 +94,23 @@ public boolean isActive( Profile profile, ProfileActivationContext context, Mode
                 reverseValue = true;
                 propValue = propValue.substring( 1 );
             }
+            boolean regexValue = false;
+            if ( propValue.startsWith( "~" ) )
+            {
+                regexValue = true;
+                propValue = propValue.substring( 1 );
+            }
 
             // we have a value, so it has to match the system value...
-            boolean result = propValue.equals( sysValue );
+            boolean result;
+            if ( regexValue )
+            {
+                result = sysValue != null && sysValue.matches( propValue );
+            }
+            else
+            {
+                result = propValue.equals( sysValue );
+            }
 
             return reverseValue ? !result : result;
         }
diff --git a/maven-model-builder/src/main/java/org/apache/maven/model/resolution/ModelResolver.java b/maven-model-builder/src/main/java/org/apache/maven/model/resolution/ModelResolver.java
index c81a5369bc..cb2a3ed857 100644
--- a/maven-model-builder/src/main/java/org/apache/maven/model/resolution/ModelResolver.java
+++ b/maven-model-builder/src/main/java/org/apache/maven/model/resolution/ModelResolver.java
@@ -19,6 +19,7 @@
  * under the License.
  */
 
+import org.apache.maven.model.Dependency;
 import org.apache.maven.model.Parent;
 import org.apache.maven.model.Repository;
 import org.apache.maven.model.building.ModelSource;
@@ -47,15 +48,46 @@ ModelSource resolveModel( String groupId, String artifactId, String version )
 
     /**
      * Tries to resolve the POM for the specified parent coordinates possibly updating {@code parent}.
+     * <p>
+     * Unlike the {@link #resolveModel(java.lang.String, java.lang.String, java.lang.String)} method, this method
+     * supports version ranges and updates the given {@code parent} instance to match the returned {@code ModelSource}.
+     * If {@code parent} declares a version range, the version corresponding to the returned {@code ModelSource} will
+     * be set on the given {@code parent}.
+     * </p>
      *
      * @param parent The parent coordinates to resolve, must not be {@code null}.
+     *
      * @return The source of the requested POM, never {@code null}.
+     *
      * @throws UnresolvableModelException If the POM could not be resolved from any configured repository.
      * @since 3.2.2
+     *
+     * @see Parent#clone()
      */
     ModelSource resolveModel( Parent parent )
         throws UnresolvableModelException;
 
+    /**
+     * Tries to resolve the POM for the specified dependency coordinates possibly updating {@code dependency}.
+     * <p>
+     * Unlike the {@link #resolveModel(java.lang.String, java.lang.String, java.lang.String)} method, this method
+     * supports version ranges and updates the given {@code dependency} instance to match the returned
+     * {@code ModelSource}. If {@code dependency} declares a version range, the version corresponding to the returned
+     * {@code ModelSource} will be set on the given {@code dependency}.
+     * </p>
+     *
+     * @param dependency The dependency coordinates to resolve, must not be {@code null}.
+     *
+     * @return The source of the requested POM, never {@code null}.
+     *
+     * @throws UnresolvableModelException If the POM could not be resolved from any configured repository.
+     * @since 3.4
+     *
+     * @see Dependency#clone()
+     */
+    ModelSource resolveModel( Dependency dependency )
+        throws UnresolvableModelException;
+
     /**
      * Adds a repository to use for subsequent resolution requests. The order in which repositories are added matters,
      * repositories that were added first should also be searched first. When multiple repositories with the same
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 91492a92f2..5abbb2cc05 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
@@ -62,11 +62,19 @@ under the License.
       <resource>
         <directory>${project.basedir}/src/main/resources</directory>
       </resource>
+      <resource>
+        <directory>${project.basedir}/src/main/filtered-resources</directory>
+        <filtering>true</filtering>
+      </resource>
     </resources>
     <testResources>
       <testResource>
         <directory>${project.basedir}/src/test/resources</directory>
       </testResource>
+      <testResource>
+        <directory>${project.basedir}/src/test/filtered-resources</directory>
+        <filtering>true</filtering>
+      </testResource>
     </testResources>
     <pluginManagement>
       <!-- NOTE: These plugins will be removed from future versions of the super POM -->
@@ -74,19 +82,19 @@ under the License.
       <plugins>
         <plugin>
           <artifactId>maven-antrun-plugin</artifactId>
-          <version>1.3</version>
+          <version>1.8</version>
         </plugin>
         <plugin>
           <artifactId>maven-assembly-plugin</artifactId>
-          <version>2.2-beta-5</version>
+          <version>2.6</version>
         </plugin>
         <plugin>
           <artifactId>maven-dependency-plugin</artifactId>
-          <version>2.8</version>
+          <version>2.9</version>
         </plugin>
         <plugin>
           <artifactId>maven-release-plugin</artifactId>
-          <version>2.3.2</version>
+          <version>2.5.3</version>
         </plugin>
       </plugins>
     </pluginManagement>
@@ -117,7 +125,7 @@ under the License.
               <execution>
                 <id>attach-sources</id>
                 <goals>
-                  <goal>jar</goal>
+                  <goal>jar-no-fork</goal>
                 </goals>
               </execution>
             </executions>
diff --git a/maven-model-builder/src/site/apt/index.apt b/maven-model-builder/src/site/apt/index.apt
index 9a645f4423..3b02ec4203 100644
--- a/maven-model-builder/src/site/apt/index.apt
+++ b/maven-model-builder/src/site/apt/index.apt
@@ -57,12 +57,18 @@ Maven Model Builder
 
    ** parent resolution until {{{./super-pom.html}super-pom}}
 
+   []
+
+ * phase 2, with optional plugin processing
+
+   ** dependency management import (for dependencies of type <<<pom>>> in the <<<\<dependencyManagement\>>>> section)
+
    ** inheritance assembly: <<<InheritanceAssembler>>> ({{{./apidocs/org/apache/maven/model/inheritance/InheritanceAssembler.html}javadoc}}),
    with its <<<DefaultInheritanceAssembler>>> implementation
    ({{{./xref/org/apache/maven/model/inheritance/DefaultInheritanceAssembler.html}source}}). Notice that
    <<<project.url>>>, <<<project.scm.connection>>>, <<<project.scm.developerConnection>>>, <<<project.scm.url>>> and
    <<<project.distributionManagement.site.url>>> have a special treatment: if not overridden in child, the default value is parent's one
-   with child artifact id appended
+   with child artifact id appended, or <<<project.directory>>> property value if directory is not equals to artifact id
 
    ** model interpolation (see below)
 
@@ -70,10 +76,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}})
@@ -86,8 +88,6 @@ 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 injection: <<<DependencyManagementInjector>>> ({{{./apidocs/org/apache/maven/model/management/DependencyManagementInjector.html}javadoc}}),
    with its <<<DefaultDependencyManagementInjector>>> implementation
    ({{{./xref/org/apache/maven/model/management/DefaultDependencyManagementInjector.html}source}})
diff --git a/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java b/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java
index e477fde253..9d88f5fb2a 100644
--- a/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java
+++ b/maven-model-builder/src/test/java/org/apache/maven/model/inheritance/DefaultInheritanceAssemblerTest.java
@@ -112,12 +112,13 @@ public void testFlatTrickyUrls()
         {
             // build from disk expected to fail
             testInheritance( "tricky-flat-artifactId-urls", false );
-            fail( "should have failed since module reference == artifactId != directory name" );
+            //fail( "should have failed since module reference == artifactId != directory name" );
         }
         catch ( AssertionFailedError afe )
         {
             // expected failure: wrong relative path calculation
-            assertTrue( afe.getMessage().contains( "http://www.apache.org/path/to/parent/child-artifact-id/" ) );
+            assertTrue( afe.getMessage(),
+                        afe.getMessage().contains( "http://www.apache.org/path/to/parent/child-artifact-id/" ) );
         }
         // but ok from repo: local disk is ignored
         testInheritance( "tricky-flat-artifactId-urls", true );
@@ -133,7 +134,8 @@ public void testFlatTrickyUrls()
         catch ( AssertionFailedError afe )
         {
             // expected failure
-            assertTrue( afe.getMessage().contains( "http://www.apache.org/path/to/parent/child-artifact-id/" ) );
+            assertTrue( afe.getMessage(),
+                        afe.getMessage().contains( "http://www.apache.org/path/to/parent/child-artifact-id/" ) );
         }
     }
 
@@ -184,4 +186,30 @@ public void testInheritance( String baseName, boolean fromRepo )
             XMLAssert.assertXMLEqual( control, test );
         }
     }    
+
+    public void testModulePathNotArtifactId()
+        throws Exception
+    {
+        Model parent = getModel( "module-path-not-artifactId-parent" );
+
+        Model child = getModel( "module-path-not-artifactId-child" );
+
+        SimpleProblemCollector problems = new SimpleProblemCollector();
+
+        assembler.assembleModelInheritance( child, parent, null, problems );
+
+        File actual = getTestFile( "target/test-classes/poms/inheritance/module-path-not-artifactId-actual.xml" );
+
+        writer.write( actual, null, child );
+
+        // check with getPom( "module-path-not-artifactId-effective" )
+        File expected = getPom( "module-path-not-artifactId-expected" );
+        try (Reader control = new InputStreamReader( new FileInputStream( expected ), "UTF-8" );
+                        Reader test = new InputStreamReader( new FileInputStream( actual ), "UTF-8" ))
+        {
+            XMLUnit.setIgnoreComments( true );
+            XMLUnit.setIgnoreWhitespace( true );
+            XMLAssert.assertXMLEqual( control, test );
+        }
+    }
 }
diff --git a/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/AbstractProfileActivatorTest.java b/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/AbstractProfileActivatorTest.java
index a77efdc979..aaee236f5d 100644
--- a/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/AbstractProfileActivatorTest.java
+++ b/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/AbstractProfileActivatorTest.java
@@ -69,10 +69,10 @@ protected void tearDown()
         super.tearDown();
     }
 
-    protected ProfileActivationContext newContext( final Properties userProperties, final Properties systemProperties )
+    protected ProfileActivationContext newContext( final Properties userProperties, final Properties systemProperties, final Properties projectProperties )
     {
         DefaultProfileActivationContext context = new DefaultProfileActivationContext();
-        return context.setUserProperties( userProperties ).setSystemProperties( systemProperties );
+        return context.setUserProperties( userProperties ).setSystemProperties( systemProperties ).setProjectProperties( projectProperties );
     }
 
     protected void assertActivation( boolean active, Profile profile, ProfileActivationContext context )
diff --git a/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivatorTest.java b/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivatorTest.java
index 440f120bbb..29d59f91b8 100644
--- a/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivatorTest.java
+++ b/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/JdkVersionProfileActivatorTest.java
@@ -61,11 +61,11 @@ public void testNullSafe()
     {
         Profile p = new Profile();
 
-        assertActivation( false, p, newContext( null, null ) );
+        assertActivation( false, p, newContext( null, null, null ) );
 
         p.setActivation( new Activation() );
 
-        assertActivation( false, p, newContext( null, null ) );
+        assertActivation( false, p, newContext( null, null, null ) );
     }
 
     public void testPrefix()
@@ -73,14 +73,14 @@ public void testPrefix()
     {
         Profile profile = newProfile( "1.4" );
 
-        assertActivation( true, profile, newContext( null, newProperties( "1.4" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.4.2" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.4.2_09" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.4.2_09-b03" ) ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.4" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.4.2" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.4.2_09" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.4.2_09-b03" ), null ) );
 
-        assertActivation( false, profile, newContext( null, newProperties( "1.3" ) ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.3" ), null ) );
 
-        assertActivation( false, profile, newContext( null, newProperties( "1.5" ) ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.5" ), null ) );
     }
 
     public void testPrefixNegated()
@@ -88,14 +88,14 @@ public void testPrefixNegated()
     {
         Profile profile = newProfile( "!1.4" );
 
-        assertActivation( false, profile, newContext( null, newProperties( "1.4" ) ) );
-        assertActivation( false, profile, newContext( null, newProperties( "1.4.2" ) ) );
-        assertActivation( false, profile, newContext( null, newProperties( "1.4.2_09" ) ) );
-        assertActivation( false, profile, newContext( null, newProperties( "1.4.2_09-b03" ) ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.4" ), null ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.4.2" ), null ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.4.2_09" ), null ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.4.2_09-b03" ), null ) );
 
-        assertActivation( true, profile, newContext( null, newProperties( "1.3" ) ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.3" ), null ) );
 
-        assertActivation( true, profile, newContext( null, newProperties( "1.5" ) ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5" ), null ) );
     }
 
     public void testVersionRangeInclusiveBounds()
@@ -103,21 +103,21 @@ public void testVersionRangeInclusiveBounds()
     {
         Profile profile = newProfile( "[1.5,1.6]" );
 
-        assertActivation( false, profile, newContext( null, newProperties( "1.4" ) ) );
-        assertActivation( false, profile, newContext( null, newProperties( "1.4.2" ) ) );
-        assertActivation( false, profile, newContext( null, newProperties( "1.4.2_09" ) ) );
-        assertActivation( false, profile, newContext( null, newProperties( "1.4.2_09-b03" ) ) );
-
-        assertActivation( true, profile, newContext( null, newProperties( "1.5" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.5.0" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09-b03" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.5.1" ) ) );
-
-        assertActivation( true, profile, newContext( null, newProperties( "1.6" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.6.0" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.6.0_09" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.6.0_09-b03" ) ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.4" ), null ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.4.2" ), null ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.4.2_09" ), null ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.4.2_09-b03" ), null ) );
+
+        assertActivation( true, profile, newContext( null, newProperties( "1.5" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5.0" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09-b03" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5.1" ), null ) );
+
+        assertActivation( true, profile, newContext( null, newProperties( "1.6" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.6.0" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.6.0_09" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.6.0_09-b03" ), null ) );
     }
 
     public void testVersionRangeExclusiveBounds()
@@ -125,22 +125,22 @@ public void testVersionRangeExclusiveBounds()
     {
         Profile profile = newProfile( "(1.3,1.6)" );
 
-        assertActivation( false, profile, newContext( null, newProperties( "1.3" ) ) );
-        assertActivation( false, profile, newContext( null, newProperties( "1.3.0" ) ) );
-        assertActivation( false, profile, newContext( null, newProperties( "1.3.0_09" ) ) );
-        assertActivation( false, profile, newContext( null, newProperties( "1.3.0_09-b03" ) ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.3" ), null ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.3.0" ), null ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.3.0_09" ), null ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.3.0_09-b03" ), null ) );
 
-        assertActivation( true, profile, newContext( null, newProperties( "1.3.1" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.3.1_09" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.3.1_09-b03" ) ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.3.1" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.3.1_09" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.3.1_09-b03" ), null ) );
 
-        assertActivation( true, profile, newContext( null, newProperties( "1.5" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.5.0" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09-b03" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.5.1" ) ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5.0" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09-b03" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5.1" ), null ) );
 
-        assertActivation( false, profile, newContext( null, newProperties( "1.6" ) ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.6" ), null ) );
     }
 
     public void testVersionRangeInclusiveLowerBound()
@@ -148,21 +148,21 @@ public void testVersionRangeInclusiveLowerBound()
     {
         Profile profile = newProfile( "[1.5,)" );
 
-        assertActivation( false, profile, newContext( null, newProperties( "1.4" ) ) );
-        assertActivation( false, profile, newContext( null, newProperties( "1.4.2" ) ) );
-        assertActivation( false, profile, newContext( null, newProperties( "1.4.2_09" ) ) );
-        assertActivation( false, profile, newContext( null, newProperties( "1.4.2_09-b03" ) ) );
-
-        assertActivation( true, profile, newContext( null, newProperties( "1.5" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.5.0" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09-b03" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.5.1" ) ) );
-
-        assertActivation( true, profile, newContext( null, newProperties( "1.6" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.6.0" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.6.0_09" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.6.0_09-b03" ) ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.4" ), null ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.4.2" ), null ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.4.2_09" ), null ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.4.2_09-b03" ), null ) );
+
+        assertActivation( true, profile, newContext( null, newProperties( "1.5" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5.0" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09-b03" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5.1" ), null ) );
+
+        assertActivation( true, profile, newContext( null, newProperties( "1.6" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.6.0" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.6.0_09" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.6.0_09-b03" ), null ) );
     }
 
     public void testVersionRangeExclusiveUpperBound()
@@ -170,16 +170,16 @@ public void testVersionRangeExclusiveUpperBound()
     {
         Profile profile = newProfile( "(,1.6)" );
 
-        assertActivation( true, profile, newContext( null, newProperties( "1.5" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.5.0" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09-b03" ) ) );
-        assertActivation( true, profile, newContext( null, newProperties( "1.5.1" ) ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5.0" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5.0_09-b03" ), null ) );
+        assertActivation( true, profile, newContext( null, newProperties( "1.5.1" ), null ) );
 
-        assertActivation( false, profile, newContext( null, newProperties( "1.6" ) ) );
-        assertActivation( false, profile, newContext( null, newProperties( "1.6.0" ) ) );
-        assertActivation( false, profile, newContext( null, newProperties( "1.6.0_09" ) ) );
-        assertActivation( false, profile, newContext( null, newProperties( "1.6.0_09-b03" ) ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.6" ), null ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.6.0" ), null ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.6.0_09" ), null ) );
+        assertActivation( false, profile, newContext( null, newProperties( "1.6.0_09-b03" ), null ) );
     }
 
 }
diff --git a/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/PropertyProfileActivatorTest.java b/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/PropertyProfileActivatorTest.java
index 73ab967e53..96f5ad92f6 100644
--- a/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/PropertyProfileActivatorTest.java
+++ b/maven-model-builder/src/test/java/org/apache/maven/model/profile/activation/PropertyProfileActivatorTest.java
@@ -66,11 +66,11 @@ public void testNullSafe()
     {
         Profile p = new Profile();
 
-        assertActivation( false, p, newContext( null, null ) );
+        assertActivation( false, p, newContext( null, null, null ) );
 
         p.setActivation( new Activation() );
 
-        assertActivation( false, p, newContext( null, null ) );
+        assertActivation( false, p, newContext( null, null, null ) );
     }
 
     public void testWithNameOnly_UserProperty()
@@ -78,11 +78,11 @@ public void testWithNameOnly_UserProperty()
     {
         Profile profile = newProfile( "prop", null );
 
-        assertActivation( true, profile, newContext( newProperties( "prop", "value" ), null ) );
+        assertActivation( true, profile, newContext( newProperties( "prop", "value" ), null, null ) );
 
-        assertActivation( false, profile, newContext( newProperties( "prop", "" ), null ) );
+        assertActivation( false, profile, newContext( newProperties( "prop", "" ), null, null ) );
 
-        assertActivation( false, profile, newContext( newProperties( "other", "value" ), null ) );
+        assertActivation( false, profile, newContext( newProperties( "other", "value" ), null, null ) );
     }
 
     public void testWithNameOnly_SystemProperty()
@@ -90,11 +90,23 @@ public void testWithNameOnly_SystemProperty()
     {
         Profile profile = newProfile( "prop", null );
 
-        assertActivation( true, profile, newContext( null, newProperties( "prop", "value" ) ) );
+        assertActivation( true, profile, newContext( null, newProperties( "prop", "value" ), null ) );
 
-        assertActivation( false, profile, newContext( null, newProperties( "prop", "" ) ) );
+        assertActivation( false, profile, newContext( null, newProperties( "prop", "" ), null ) );
 
-        assertActivation( false, profile, newContext( null, newProperties( "other", "value" ) ) );
+        assertActivation( false, profile, newContext (null, newProperties( "other", "value" ), null ) );
+    }
+
+    public void testWithNameOnly_ProjectProperty()
+            throws Exception
+    {
+        Profile profile = newProfile( "prop", null );
+
+        assertActivation( true, profile, newContext( null, null, newProperties( "prop", "value" ) ) );
+
+        assertActivation( false, profile, newContext( null, null, newProperties( "prop", "" ) ) );
+
+        assertActivation( false, profile, newContext( null, null, newProperties( "other", "value" ) ) );
     }
 
     public void testWithNegatedNameOnly_UserProperty()
@@ -102,11 +114,11 @@ public void testWithNegatedNameOnly_UserProperty()
     {
         Profile profile = newProfile( "!prop", null );
 
-        assertActivation( false, profile, newContext( newProperties( "prop", "value" ), null ) );
+        assertActivation( false, profile, newContext( newProperties( "prop", "value" ), null, null ) );
 
-        assertActivation( true, profile, newContext( newProperties( "prop", "" ), null ) );
+        assertActivation( true, profile, newContext( newProperties( "prop", "" ), null, null ) );
 
-        assertActivation( true, profile, newContext( newProperties( "other", "value" ), null ) );
+        assertActivation( true, profile, newContext( newProperties( "other", "value" ), null, null ) );
     }
 
     public void testWithNegatedNameOnly_SystemProperty()
@@ -114,11 +126,23 @@ public void testWithNegatedNameOnly_SystemProperty()
     {
         Profile profile = newProfile( "!prop", null );
 
-        assertActivation( false, profile, newContext( null, newProperties( "prop", "value" ) ) );
+        assertActivation( false, profile, newContext( null, newProperties( "prop", "value" ), null ) );
 
-        assertActivation( true, profile, newContext( null, newProperties( "prop", "" ) ) );
+        assertActivation( true, profile, newContext( null, newProperties( "prop", "" ), null ) );
 
-        assertActivation( true, profile, newContext( null, newProperties( "other", "value" ) ) );
+        assertActivation( true, profile, newContext( null, newProperties( "other", "value" ), null ) );
+    }
+
+    public void testWithNegatedNameOnly_ProjectProperty()
+            throws Exception
+    {
+        Profile profile = newProfile( "!prop", null );
+
+        assertActivation( false, profile, newContext( null, null, newProperties( "prop", "value" ) ) );
+
+        assertActivation( true, profile, newContext( null, null, newProperties( "prop", "" ) ) );
+
+        assertActivation( true, profile, newContext( null, null, newProperties( "other", "value" ) ) );
     }
 
     public void testWithValue_UserProperty()
@@ -126,11 +150,11 @@ public void testWithValue_UserProperty()
     {
         Profile profile = newProfile( "prop", "value" );
 
-        assertActivation( true, profile, newContext( newProperties( "prop", "value" ), null ) );
+        assertActivation( true, profile, newContext( newProperties( "prop", "value" ), null, null ) );
 
-        assertActivation( false, profile, newContext( newProperties( "prop", "other" ), null ) );
+        assertActivation( false, profile, newContext( newProperties( "prop", "other" ), null, null ) );
 
-        assertActivation( false, profile, newContext( newProperties( "prop", "" ), null ) );
+        assertActivation( false, profile, newContext( newProperties( "prop", "" ), null, null ) );
     }
 
     public void testWithValue_SystemProperty()
@@ -138,11 +162,23 @@ public void testWithValue_SystemProperty()
     {
         Profile profile = newProfile( "prop", "value" );
 
-        assertActivation( true, profile, newContext( null, newProperties( "prop", "value" ) ) );
+        assertActivation( true, profile, newContext( null, newProperties( "prop", "value" ), null ) );
+
+        assertActivation( false, profile, newContext( null, newProperties( "prop", "other" ), null ) );
+
+        assertActivation( false, profile, newContext( null, newProperties( "other", "" ), null ) );
+    }
+
+    public void testWithValue_ProjectProperty()
+            throws Exception
+    {
+        Profile profile = newProfile( "prop", "value" );
+
+        assertActivation( true, profile, newContext( null, null, newProperties("prop", "value") ) );
 
-        assertActivation( false, profile, newContext( null, newProperties( "prop", "other" ) ) );
+        assertActivation( false, profile, newContext( null, null, newProperties( "prop", "other" ) ) );
 
-        assertActivation( false, profile, newContext( null, newProperties( "other", "" ) ) );
+        assertActivation( false, profile, newContext( null, null, newProperties( "other", "" ) ) );
     }
 
     public void testWithNegatedValue_UserProperty()
@@ -150,11 +186,11 @@ public void testWithNegatedValue_UserProperty()
     {
         Profile profile = newProfile( "prop", "!value" );
 
-        assertActivation( false, profile, newContext( newProperties( "prop", "value" ), null ) );
+        assertActivation( false, profile, newContext( newProperties( "prop", "value" ), null, null ) );
 
-        assertActivation( true, profile, newContext( newProperties( "prop", "other" ), null ) );
+        assertActivation( true, profile, newContext( newProperties( "prop", "other" ), null, null ) );
 
-        assertActivation( true, profile, newContext( newProperties( "prop", "" ), null ) );
+        assertActivation( true, profile, newContext( newProperties( "prop", "" ), null, null ) );
     }
 
     public void testWithNegatedValue_SystemProperty()
@@ -162,11 +198,95 @@ public void testWithNegatedValue_SystemProperty()
     {
         Profile profile = newProfile( "prop", "!value" );
 
-        assertActivation( false, profile, newContext( null, newProperties( "prop", "value" ) ) );
+        assertActivation( false, profile, newContext( null, newProperties( "prop", "value" ), null ) );
 
-        assertActivation( true, profile, newContext( null, newProperties( "prop", "other" ) ) );
+        assertActivation( true, profile, newContext( null, newProperties( "prop", "other" ), null ) );
 
-        assertActivation( true, profile, newContext( null, newProperties( "other", "" ) ) );
+        assertActivation( true, profile, newContext( null, newProperties( "other", "" ), null ) );
+    }
+
+    public void testWithNegatedValue_ProjectProperty()
+            throws Exception
+    {
+        Profile profile = newProfile( "prop", "!value" );
+
+        assertActivation( false, profile, newContext( null, null, newProperties( "prop", "value" ) ) );
+
+        assertActivation( true, profile, newContext( null, null, newProperties( "prop", "other" ) ) );
+
+        assertActivation( true, profile, newContext( null, null, newProperties( "other", "" ) ) );
+    }
+
+    public void testWithRegexValue_UserProperty()
+            throws Exception
+    {
+        Profile profile = newProfile( "prop", "~.*lue" );
+
+        assertActivation( true, profile, newContext( newProperties( "prop", "value" ), null, null ) );
+
+        assertActivation( false, profile, newContext( newProperties( "prop", "other" ), null, null ) );
+
+        assertActivation( false, profile, newContext( newProperties( "prop", "" ), null, null ) );
+    }
+
+    public void testWithRegexValue_SystemProperty()
+            throws Exception
+    {
+        Profile profile = newProfile( "prop", "~.*lue" );
+
+        assertActivation( true, profile, newContext( null, newProperties( "prop", "value" ), null ) );
+
+        assertActivation( false, profile, newContext( null, newProperties( "prop", "other" ), null ) );
+
+        assertActivation( false, profile, newContext( null, newProperties( "other", "" ), null ) );
+    }
+
+    public void testWithRegexValue_ProjectProperty()
+            throws Exception
+    {
+        Profile profile = newProfile( "prop", "~.*lue" );
+
+        assertActivation( true, profile, newContext( null, null, newProperties( "prop", "value" ) ) );
+
+        assertActivation( false, profile, newContext( null, null, newProperties( "prop", "other" ) ) );
+
+        assertActivation( false, profile, newContext( null, null, newProperties( "other", "" ) ) );
+    }
+
+    public void testWithNegatedRegexValue_UserProperty()
+            throws Exception
+    {
+        Profile profile = newProfile( "prop", "!~.*lue" );
+
+        assertActivation( false, profile, newContext( newProperties( "prop", "value" ), null, null ) );
+
+        assertActivation( true, profile, newContext( newProperties( "prop", "other" ), null, null ) );
+
+        assertActivation( true, profile, newContext( newProperties( "prop", "" ), null, null ) );
+    }
+
+    public void testWithNegatedRegexValue_SystemProperty()
+            throws Exception
+    {
+        Profile profile = newProfile( "prop", "!~.*lue" );
+
+        assertActivation( false, profile, newContext( null, newProperties( "prop", "value" ), null ) );
+
+        assertActivation( true, profile, newContext( null, newProperties( "prop", "other" ), null ) );
+
+        assertActivation( true, profile, newContext( null, newProperties( "other", "" ), null ) );
+    }
+
+    public void testWithNegatedRegexValue_ProjectProperty()
+            throws Exception
+    {
+        Profile profile = newProfile( "prop", "!~.*lue" );
+
+        assertActivation( false, profile, newContext( null, null, newProperties( "prop", "value" ) ) );
+
+        assertActivation( true, profile, newContext( null, null, newProperties( "prop", "other" ) ) );
+
+        assertActivation( true, profile, newContext( null, null, newProperties( "other", "" ) ) );
     }
 
     public void testWithValue_UserPropertyDominantOverSystemProperty()
@@ -177,9 +297,34 @@ public void testWithValue_UserPropertyDominantOverSystemProperty()
         Properties props1 = newProperties( "prop", "value" );
         Properties props2 = newProperties( "prop", "other" );
 
-        assertActivation( true, profile, newContext( props1, props2 ) );
+        assertActivation( true, profile, newContext( props1, props2, null ) );
+
+        assertActivation( false, profile, newContext( props2, props1, null ) );
+    }
+
+    public void testWithValue_UserPropertyDominantOverProjectProperty()
+            throws Exception
+    {
+        Profile profile = newProfile( "prop", "value" );
+
+        Properties props1 = newProperties( "prop", "value" );
+        Properties props2 = newProperties( "prop", "other" );
+
+        assertActivation( true, profile, newContext( props1, null, props2 ) );
 
-        assertActivation( false, profile, newContext( props2, props1 ) );
+        assertActivation( false, profile, newContext( props2, null, props1 ) );
     }
 
+    public void testWithValue_SystemPropertyDominantOverProjectProperty()
+            throws Exception
+    {
+        Profile profile = newProfile( "prop", "value" );
+
+        Properties props1 = newProperties( "prop", "value" );
+        Properties props2 = newProperties( "prop", "other" );
+
+        assertActivation( true, profile, newContext( null, props1, props2 ) );
+
+        assertActivation( false, profile, newContext( null, props2, props1 ) );
+    }
 }
diff --git a/maven-model-builder/src/test/resources/poms/inheritance/module-path-not-artifactId-child.xml b/maven-model-builder/src/test/resources/poms/inheritance/module-path-not-artifactId-child.xml
new file mode 100644
index 0000000000..7031f448e1
--- /dev/null
+++ b/maven-model-builder/src/test/resources/poms/inheritance/module-path-not-artifactId-child.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>inheritance</groupId>
+    <artifactId>parent</artifactId>
+    <version>11-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>child-artifact-id</artifactId>
+  <name>Model inheritance test parent: module directory != artifactId</name>
+  <description>
+    artifactId == "child-artifact-id"
+    but expect path on SCM and site == "child"
+    feature: support "project.directory" property, ressembling future model addition of "directory" element along "artifactId" 
+  </description>
+
+  <properties>
+    <project.directory>child</project.directory>
+  </properties>
+</project>
\ No newline at end of file
diff --git a/maven-model-builder/src/test/resources/poms/inheritance/module-path-not-artifactId-expected.xml b/maven-model-builder/src/test/resources/poms/inheritance/module-path-not-artifactId-expected.xml
new file mode 100644
index 0000000000..e82f2894b7
--- /dev/null
+++ b/maven-model-builder/src/test/resources/poms/inheritance/module-path-not-artifactId-expected.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>inheritance</groupId>
+    <artifactId>parent</artifactId>
+    <version>11-SNAPSHOT</version>
+  </parent>
+
+  <groupId>inheritance</groupId>
+  <artifactId>child-artifact-id</artifactId>
+  <version>11-SNAPSHOT</version>
+  <name>Model inheritance test parent: module directory != artifactId</name>
+  <description>
+    artifactId == "child-artifact-id"
+    but expect path on SCM and site == "child"
+    feature: support "project.directory" property, ressembling future model addition of "directory" element along "artifactId" 
+  </description>
+
+  <!-- 5 inherited urls with ${project.directory} added to parent instead of artifactId -->
+  <url>http://www.apache.org/child/</url>
+  <scm>
+    <connection>scm:my-scm:http://domain.org/base/child</connection>
+    <developerConnection>scm:my-scm:https://domain.org/base/child/</developerConnection>
+    <url>https://domain.org/base/child</url>
+  </scm>
+  <distributionManagement>
+    <site>
+      <url>scp://scp.domain.org/base/child/</url>
+    </site>
+  </distributionManagement>
+
+  <properties>
+    <project.directory>child</project.directory>
+  </properties>
+</project>
diff --git a/maven-model-builder/src/test/resources/poms/inheritance/module-path-not-artifactId-parent.xml b/maven-model-builder/src/test/resources/poms/inheritance/module-path-not-artifactId-parent.xml
new file mode 100644
index 0000000000..e07ceef7b8
--- /dev/null
+++ b/maven-model-builder/src/test/resources/poms/inheritance/module-path-not-artifactId-parent.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>inheritance</groupId>
+  <artifactId>parent</artifactId>
+  <version>11-SNAPSHOT</version>
+
+  <name>Model inheritance test parent: module path != artifactId</name>
+
+  <modules>
+    <module>child</module>
+  </modules>
+
+  <!-- 5 urls in the pom will be inherited with path added -->
+  <url>http://www.apache.org/</url>
+  <scm>
+    <connection>scm:my-scm:http://domain.org/base</connection>
+    <developerConnection>scm:my-scm:https://domain.org/base/</developerConnection>
+    <url>https://domain.org/base</url>
+  </scm>
+  <distributionManagement>
+    <site>
+      <url>scp://scp.domain.org/base/</url>
+    </site>
+  </distributionManagement>
+</project>
\ No newline at end of file
diff --git a/maven-model/pom.xml b/maven-model/pom.xml
index bdd86afce8..29c454c365 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.3.10-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 a7a893b25e..a05d059faf 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.3.10-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-plugin-api</artifactId>
diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/MojoNotFoundException.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/MojoNotFoundException.java
index 4d99546ae2..cdb9a23ca8 100644
--- a/maven-plugin-api/src/main/java/org/apache/maven/plugin/MojoNotFoundException.java
+++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/MojoNotFoundException.java
@@ -54,7 +54,7 @@ private static String toMessage( String goal, PluginDescriptor pluginDescriptor
     {
         StringBuilder buffer = new StringBuilder( 256 );
 
-        buffer.append( "Could not find goal '" ).append( goal ).append( "'" );
+        buffer.append( "Could not find goal '" ).append( goal ).append( '\'' );
 
         if ( pluginDescriptor != null )
         {
diff --git a/maven-plugin-api/src/main/mdo/lifecycle.mdo b/maven-plugin-api/src/main/mdo/lifecycle.mdo
index 2a46647439..7dfce74be9 100644
--- a/maven-plugin-api/src/main/mdo/lifecycle.mdo
+++ b/maven-plugin-api/src/main/mdo/lifecycle.mdo
@@ -84,7 +84,7 @@ under the License.
           <required>true</required>
           <version>1.0.0</version>
           <type>String</type>
-          <description>The ID of this phase, eg &lt;code&gt;generate-sources&lt;/code&gt;.</description>
+          <description>The ID of this phase, e.g., &lt;code&gt;generate-sources&lt;/code&gt;.</description>
         </field>
         <field>
           <name>executions</name>
diff --git a/maven-repository-metadata/pom.xml b/maven-repository-metadata/pom.xml
index e5d3efc543..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.3.10-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-repository-metadata</artifactId>
diff --git a/maven-settings-builder/pom.xml b/maven-settings-builder/pom.xml
index 0a7c0990a4..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.3.10-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/building/DefaultSettingsProblem.java b/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsProblem.java
index b261fa1d64..a8eb909b45 100644
--- a/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsProblem.java
+++ b/maven-settings-builder/src/main/java/org/apache/maven/settings/building/DefaultSettingsProblem.java
@@ -156,7 +156,7 @@ public String toString()
     {
         StringBuilder buffer = new StringBuilder( 128 );
 
-        buffer.append( "[" ).append( getSeverity() ).append( "] " );
+        buffer.append( '[' ).append( getSeverity() ).append( "] " );
         buffer.append( getMessage() );
         buffer.append( " @ " ).append( getLocation() );
 
diff --git a/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/DefaultSettingsDecrypter.java b/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/DefaultSettingsDecrypter.java
index 671a20de7d..b09e8cd71d 100644
--- a/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/DefaultSettingsDecrypter.java
+++ b/maven-settings-builder/src/main/java/org/apache/maven/settings/crypto/DefaultSettingsDecrypter.java
@@ -21,6 +21,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 import org.apache.maven.settings.Proxy;
 import org.apache.maven.settings.Server;
@@ -45,6 +46,15 @@
     @Requirement( hint = "maven" )
     private SecDispatcher securityDispatcher;
 
+    /**
+     * @since 3.4
+     */
+    public DefaultSettingsDecrypter setSecurityDispatcher( final SecDispatcher value )
+    {
+        this.securityDispatcher = Objects.requireNonNull( value );
+        return this;
+    }
+
     @Override
     public SettingsDecryptionResult decrypt( SettingsDecryptionRequest request )
     {
diff --git a/maven-settings/pom.xml b/maven-settings/pom.xml
index dcc1520961..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.3.10-SNAPSHOT</version>
+    <version>3.4.0-SNAPSHOT</version>
   </parent>
 
   <artifactId>maven-settings</artifactId>
diff --git a/maven-settings/src/main/mdo/settings.mdo b/maven-settings/src/main/mdo/settings.mdo
index 6d560cca59..6fbc92b9a9 100644
--- a/maven-settings/src/main/mdo/settings.mdo
+++ b/maven-settings/src/main/mdo/settings.mdo
@@ -600,7 +600,7 @@
           <version>1.0.0+</version>
           <type>String</type>
           <description>
-            The server ID of the repository being mirrored, eg
+            The server ID of the repository being mirrored, e.g.,
             "central". This MUST NOT match the mirror id.
           </description>
         </field>
diff --git a/pom.xml b/pom.xml
index 178a7ee413..cf30034f1f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
   </parent>
 
   <artifactId>maven</artifactId>
-  <version>3.3.10-SNAPSHOT</version>
+  <version>3.4.0-SNAPSHOT</version>
   <packaging>pom</packaging>
 
   <name>Apache Maven</name>
@@ -46,23 +46,22 @@
     <maven.compiler.source>1.7</maven.compiler.source>
     <maven.compiler.target>1.7</maven.compiler.target>
     <classWorldsVersion>2.5.2</classWorldsVersion>
-    <commonsCliVersion>1.2</commonsCliVersion>
+    <commonsCliVersion>1.3.1</commonsCliVersion>
     <commonsLangVersion>3.4</commonsLangVersion>
-    <junitVersion>4.11</junitVersion>
+    <junitVersion>4.12</junitVersion>
     <plexusVersion>1.6</plexusVersion>
-    <plexusInterpolationVersion>1.21</plexusInterpolationVersion>
+    <plexusInterpolationVersion>1.22</plexusInterpolationVersion>
     <plexusUtilsVersion>3.0.22</plexusUtilsVersion>
-    <!-- Latest version of Guava that works with Sisu -->
-    <guavaVersion>18.0</guavaVersion>
+    <guavaVersion>19.0</guavaVersion>
     <guiceVersion>4.0</guiceVersion>
-    <sisuInjectVersion>0.3.2</sisuInjectVersion>
+    <sisuInjectVersion>0.3.3</sisuInjectVersion>
     <wagonVersion>2.10</wagonVersion>
-    <securityDispatcherVersion>1.3</securityDispatcherVersion>
+    <securityDispatcherVersion>1.4</securityDispatcherVersion>
     <cipherVersion>1.7</cipherVersion>
     <modelloVersion>1.8.3</modelloVersion>
     <jxpathVersion>1.3</jxpathVersion>
-    <aetherVersion>1.0.2.v20150114</aetherVersion>
-    <slf4jVersion>1.7.5</slf4jVersion>
+    <aetherVersion>1.1.0</aetherVersion>
+    <slf4jVersion>1.7.16</slf4jVersion>
     <maven.test.redirectTestOutputToFile>true</maven.test.redirectTestOutputToFile>
     <!-- Control the name of the distribution and information output by mvn -->
     <distributionId>apache-maven</distributionId>
@@ -145,8 +144,8 @@
   </contributors>
 
   <!-- This marked as deprecated for Maven 3.X. This is checked by maven-enforcer-plugin -->
-  <!--  http://jira.codehaus.org/browse/MNG-4840 -->
-  <!--  http://jira.codehaus.org/browse/MNG-5297 -->
+  <!--  https://issues.apache.org/jira/browse/MNG-4840 -->
+  <!--  https://issues.apache.org/jira/browse/MNG-5297 -->
   <prerequisites>
     <maven>${maven.version}</maven>
   </prerequisites>
@@ -280,7 +279,7 @@
       <dependency>
         <groupId>ch.qos.logback</groupId>
         <artifactId>logback-classic</artifactId>
-        <version>1.0.7</version>
+        <version>1.1.5</version>
         <optional>true</optional>
       </dependency>
       <!--  Wagon -->
@@ -457,12 +456,12 @@
         <plugin>
           <groupId>org.apache.felix</groupId>
           <artifactId>maven-bundle-plugin</artifactId>
-          <version>1.0.0</version>
+          <version>3.0.1</version>
         </plugin>
         <plugin>
           <groupId>org.codehaus.mojo</groupId>
           <artifactId>buildnumber-maven-plugin</artifactId>
-          <version>1.2</version>
+          <version>1.4</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
@@ -529,7 +528,7 @@
         </configuration>
         <executions>
           <execution>
-            <id>check-java-1.6-compat</id>
+            <id>check-java-1.7-compat</id>
             <phase>process-classes</phase>
             <goals>
               <goal>check</goal>
@@ -540,7 +539,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-doap-plugin</artifactId>
-        <version>1.1</version>
+        <version>1.2</version>
         <configuration>
           <asfExtOptions>
             <charter>The mission of the Apache Maven project is to create and maintain software
diff --git a/src/site/resources/images/maven-deps.png b/src/site/resources/images/maven-deps.png
index d23033fbce..99f7a10a2b 100644
Binary files a/src/site/resources/images/maven-deps.png and b/src/site/resources/images/maven-deps.png differ
diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml
index b98b4ee258..201fd4c642 100644
--- a/src/site/xdoc/index.xml
+++ b/src/site/xdoc/index.xml
@@ -40,7 +40,7 @@
     process.</p>
 
       <p>
-        <img src="images/maven-deps.png" width="784" height="595" border="0" usemap="#Maven_dependencies" />
+        <img src="images/maven-deps.png" width="784" height="578" border="0" usemap="#Maven_dependencies" />
         <map name="Maven_dependencies">
           <area shape="rect" coords="228,1,361,36"    alt="apache-maven"  href="apache-maven/" />
           <area shape="rect" coords="228,58,361,95"   alt="maven-embedder" href="maven-embedder/" />
@@ -50,9 +50,9 @@
           <area shape="rect" coords="0,287,192,323"   alt="maven-repository-metadata" href="maven-repository-metadata/" />
           <area shape="rect" coords="245,342,343,378" alt="maven-plugin-api" href="maven-plugin-api/" />
           <area shape="rect" coords="253,401,336,436" alt="maven-artifact" href="maven-artifact/" />
-          <area shape="rect" coords="296,234,442,270" alt="maven-builder-support" href="maven-builder-support/" />
+          <area shape="rect" coords="299,230,446,265" alt="maven-builder-support" href="maven-builder-support/" />
           <area shape="rect" coords="382,176,528,211" alt="maven-settings-builder" href="maven-settings-builder/" />
-          <area shape="rect" coords="446,234,537,269" alt="maven-settings" href="maven-settings/" />
+          <area shape="rect" coords="449,229,532,266" alt="maven-settings" href="maven-settings/" />
           <area shape="rect" coords="388,284,521,319" alt="maven-model-builder" href="maven-model-builder/" />
           <area shape="rect" coords="409,342,500,378" alt="maven-model" href="maven-model/" />
           <area shape="rect" coords="551,58,707,94"   alt="commons-cli" href="http://commons.apache.org/cli/" />
@@ -65,8 +65,9 @@
           <area shape="rect" coords="685,455,775,491" alt="plexus-utils" href="https://github.com/codehaus-plexus/plexus-utils" />
           <area shape="rect" coords="542,167,783,502" alt="plexus" href="https://github.com/codehaus-plexus" />
           <area shape="rect" coords="68,338,240,482"  alt="aether" href="http://www.eclipse.org/projects/project_summary.php?projectid=technology.aether" />
-          <area shape="rect" coords="388,393,520,594" alt="sisu" href="http://www.eclipse.org/projects/project_summary.php?projectid=technology.sisu" />
-          <area shape="rect" coords="519,518,621,554" alt="guice" href="http://code.google.com/p/google-guice/" />
+          <area shape="rect" coords="401,393,509,524" alt="sisu" href="http://www.eclipse.org/projects/project_summary.php?projectid=technology.sisu" />
+          <area shape="rect" coords="416,543,493,577" alt="guice" href="http://code.google.com/p/google-guice/" />
+          <area shape="rect" coords="550,543,673,577" alt="javax.inject" href="http://docs.oracle.com/javaee/6/api/javax/inject/package-summary.html" />
         </map>
       </p>
     </section>
diff --git a/src/site/xdoc/maven-deps.odg b/src/site/xdoc/maven-deps.odg
index 9d4193a889..792387934b 100644
Binary files a/src/site/xdoc/maven-deps.odg and b/src/site/xdoc/maven-deps.odg differ


 

----------------------------------------------------------------
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


> Match property for profile activation against a regex
> -----------------------------------------------------
>
>                 Key: MNG-4777
>                 URL: https://issues.apache.org/jira/browse/MNG-4777
>             Project: Maven
>          Issue Type: Improvement
>          Components: Profiles
>    Affects Versions: 2.0.11
>            Reporter: Andreas Ebbert-Karroum
>            Priority: Major
>         Attachments: regex-project-property-profile-activator.patch
>
>
> For activating a profile it would be nice, in addition or as a seperate feature to MNG-3328, to match a property not against a specific value but against a regex. In our case, we need to set some properties for some hudson builds. Not only is that setup fragile against job name changes, but also doesn't scale for multiple jobs. IMHO adding a regex matcher would be a nice feature for multiple purposes.
> Old:
> {code:xml}
> <activation>
>   <property>
>     <name>env.JOB_NAME</name>
>     <value>xyz-abc-foo/label=robotframework,maven.browser-profile=firefox,maven.env-profile=dev</value>
>   </property>
> </activation>
> {code}
> New:
> {code:xml}
> <activation>
>   <property>
>     <name>env.JOB_NAME</name>
>     <regex>xyz-abc-foo/.*</regex>
>   </property>
> </activation>
> {code}



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Mime
View raw message