You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by cs...@apache.org on 2021/04/28 15:36:14 UTC

[maven-artifact-transfer] branch MSHARED-987 created (now 6d2a3d2)

This is an automated email from the ASF dual-hosted git repository.

cstamas pushed a change to branch MSHARED-987
in repository https://gitbox.apache.org/repos/asf/maven-artifact-transfer.git.


      at 6d2a3d2  [MSHARED-987] Drop legacy, prepare for future

This branch includes the following new commits:

     new 6d2a3d2  [MSHARED-987] Drop legacy, prepare for future

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[maven-artifact-transfer] 01/01: [MSHARED-987] Drop legacy, prepare for future

Posted by cs...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

cstamas pushed a commit to branch MSHARED-987
in repository https://gitbox.apache.org/repos/asf/maven-artifact-transfer.git

commit 6d2a3d24324c860649ce491ee5a760b8d196fc59
Author: Tamas Cservenak <ta...@cservenak.net>
AuthorDate: Wed Apr 28 17:35:20 2021 +0200

    [MSHARED-987] Drop legacy, prepare for future
    
    In general, support Maven 3.1+ only (drop Maven 3.0 support).
    
    https://issues.apache.org/jira/browse/MSHARED-987
---
 pom.xml                                            |  80 ++++---
 .../deploy/internal/ArtifactDeployerDelegate.java  |  60 +++++
 .../deploy/internal/DefaultArtifactDeployer.java   | 111 ++-------
 .../transfer/artifact/deploy/internal/Invoker.java |  66 -----
 .../deploy/internal/Maven30ArtifactDeployer.java   | 150 ------------
 .../deploy/internal/Maven31ArtifactDeployer.java   |  50 ++--
 ...staller.java => ArtifactInstallerDelegate.java} |  11 +-
 .../install/internal/DefaultArtifactInstaller.java | 125 +++-------
 .../artifact/install/internal/Invoker.java         |  65 -----
 .../install/internal/Maven30ArtifactInstaller.java | 105 --------
 .../install/internal/Maven31ArtifactInstaller.java |  45 +++-
 ...Resolver.java => ArtifactResolverDelegate.java} |  13 +-
 .../resolve/internal/DefaultArtifactResolver.java  | 122 +++-------
 .../artifact/resolve/internal/Invoker.java         |  67 ------
 .../resolve/internal/Maven30ArtifactResolver.java  | 107 ---------
 .../resolve/internal/Maven30ArtifactResult.java    |  57 -----
 .../resolve/internal/Maven31ArtifactResolver.java  |  50 ++--
 .../resolve/internal/Maven31ArtifactResult.java    |  12 +-
 .../internal/DefaultDependencyCollector.java       | 187 ++++-----------
 ...ector.java => DependencyCollectorDelegate.java} |  20 +-
 .../transfer/collection/internal/Invoker.java      |  96 --------
 .../internal/Maven30ArtifactRepositoryAdapter.java | 265 --------------------
 .../collection/internal/Maven30CollectResult.java  |  68 ------
 .../internal/Maven30DependencyCollector.java       | 167 -------------
 .../internal/Maven30DependencyNodeAdapter.java     | 163 -------------
 .../internal/Maven31ArtifactRepositoryAdapter.java |  12 +
 .../internal/Maven31DependencyCollector.java       |  57 +++--
 .../internal/Maven31DependencyNodeAdapter.java     |  11 +-
 .../internal/DefaultDependencyCollector.java       | 139 +++--------
 ...ector.java => DependencyCollectorDelegate.java} |  21 +-
 .../dependencies/collect/internal/Invoker.java     |  93 -------
 .../internal/Maven30ArtifactRepositoryAdapter.java | 266 ---------------------
 .../collect/internal/Maven30CollectorResult.java   |  85 -------
 .../internal/Maven30DependencyCollector.java       | 160 -------------
 .../internal/Maven30DependencyNodeAdapter.java     | 163 -------------
 .../internal/Maven31ArtifactRepositoryAdapter.java |  12 +
 .../internal/Maven31DependencyCollector.java       |  54 +++--
 .../internal/Maven31DependencyNodeAdapter.java     |  10 +-
 .../internal/DefaultDependencyResolver.java        | 143 +++--------
 .../internal/DependencyResolverDelegate.java}      |  19 +-
 .../dependencies/resolve/internal/Invoker.java     |  95 --------
 .../resolve/internal/Maven30ArtifactResult.java    |  57 -----
 .../internal/Maven30DependencyResolver.java        | 247 -------------------
 .../Maven30DependencyResolverException.java        |  61 -----
 .../resolve/internal/Maven31ArtifactResult.java    |  12 +-
 .../internal/Maven31DependencyResolver.java        |  71 +++---
 .../resolve/internal/MavenDependencyResolver.java  |  51 ----
 .../ComponentSupport.java}                         |  34 ++-
 .../Delegator.java}                                |  28 ++-
 .../Selector.java}                                 |  39 ++-
 .../metadata/internal/Maven30MetadataBridge.java   | 107 ---------
 .../shared/transfer/project/MavenAetherUtils.java  | 100 --------
 .../deploy/internal/DefaultProjectDeployer.java    |  30 ++-
 .../install/internal/DefaultProjectInstaller.java  |  33 ++-
 .../internal/DefaultRepositoryManager.java         | 206 ++++------------
 .../transfer/repository/internal/Invoker.java      |  79 ------
 .../internal/Maven30RepositoryManager.java         | 172 -------------
 .../internal/Maven31RepositoryManager.java         |  94 +++-----
 .../internal/MavenRepositoryManager.java           |  67 ------
 .../internal/RepositoryManagerDelegate.java}       |  13 +-
 .../internal/Maven30ArtifactInstallerTest.java     |   1 -
 .../internal/Maven30RepositoryManagerTest.java     |   1 -
 62 files changed, 727 insertions(+), 4378 deletions(-)

diff --git a/pom.xml b/pom.xml
index 2e3aba6..ce63777 100644
--- a/pom.xml
+++ b/pom.xml
@@ -31,7 +31,7 @@
   <version>0.13.2-SNAPSHOT</version>
 
   <name>Apache Maven Artifact Transfer</name>
-  <description>An API to install, deploy and resolving artifacts with Maven 3</description>
+  <description>An API to install, deploy and resolving artifacts with Maven 3.1+</description>
 
   <scm>
     <connection>scm:git:https://gitbox.apache.org/repos/asf/maven-artifact-transfer.git</connection>
@@ -57,6 +57,9 @@
   <properties>
     <javaVersion>7</javaVersion>
     <project.build.outputTimestamp>2020-12-22T10:32:11Z</project.build.outputTimestamp>
+    <mavenVersion>3.1.0</mavenVersion>
+    <sisuVersion>0.3.4</sisuVersion>
+    <guiceVersion>3.2.6</guiceVersion>
   </properties>
 
   <build>
@@ -76,20 +79,23 @@
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
             <configuration>
-            <showDeprecation>true</showDeprecation>
-            <compilerArgs>
-              <arg>-Xlint:deprecation</arg>
-              <arg>-Xlint:unchecked</arg>
-            </compilerArgs>
+              <forceJavacCompilerUse>true</forceJavacCompilerUse>
+              <showDeprecation>true</showDeprecation>
+              <compilerArgs>
+                <arg>-Xlint:deprecation</arg>
+                <arg>-Xlint:unchecked</arg>
+              </compilerArgs>
           </configuration>
       </plugin>
       <plugin>
-        <groupId>org.codehaus.plexus</groupId>
-        <artifactId>plexus-component-metadata</artifactId>
+        <groupId>org.eclipse.sisu</groupId>
+        <artifactId>sisu-maven-plugin</artifactId>
+        <version>0.3.4</version>
         <executions>
           <execution>
             <goals>
-              <goal>generate-metadata</goal>
+              <goal>main-index</goal>
+              <goal>test-index</goal>
             </goals>
           </execution>
         </executions>
@@ -165,17 +171,24 @@
     <dependency>
       <groupId>org.apache.maven</groupId>
       <artifactId>maven-core</artifactId>
-      <version>3.0</version>
+      <version>${mavenVersion}</version>
+      <scope>provided</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>org.eclipse.sisu</groupId>
+          <artifactId>org.eclipse.sisu.plexus</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.codehause.plexus</groupId>
+          <artifactId>*</artifactId>
+        </exclusion>
+      </exclusions>
     </dependency>
     <dependency>
       <groupId>org.apache.maven</groupId>
       <artifactId>maven-artifact</artifactId>
-      <version>3.0</version>
-    </dependency>
-
-    <dependency>
-      <groupId>org.codehaus.plexus</groupId>
-      <artifactId>plexus-component-annotations</artifactId>
+      <version>${mavenVersion}</version>
+      <scope>provided</scope>
     </dependency>
 
     <dependency>
@@ -189,24 +202,29 @@
       <version>3.3.0</version>
     </dependency>
 
-    <!-- Maven 3.0.x -->
-    <dependency>
-      <groupId>org.sonatype.aether</groupId>
-      <artifactId>aether-api</artifactId>
-      <version>1.7</version>
-      <scope>provided</scope>
-    </dependency>
+    <!-- DI -->
     <dependency>
-      <groupId>org.sonatype.aether</groupId>
-      <artifactId>aether-util</artifactId>
-      <version>1.7</version>
+      <groupId>javax.inject</groupId>
+      <artifactId>javax.inject</artifactId>
+      <version>1</version>
       <scope>provided</scope>
     </dependency>
+
     <dependency>
-      <groupId>org.sonatype.aether</groupId>
-      <artifactId>aether-impl</artifactId>
-      <version>1.7</version>
-      <scope>test</scope>
+      <groupId>org.sonatype.sisu</groupId>
+      <artifactId>sisu-guice</artifactId>
+      <version>${guiceVersion}</version>
+      <classifier>no_aop</classifier>
+      <exclusions>
+        <exclusion>
+          <groupId>aopalliance</groupId>
+          <artifactId>aopalliance</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.google.code.findbugs</groupId>
+          <artifactId>jsr305</artifactId>
+        </exclusion>
+      </exclusions>
     </dependency>
 
     <!-- Maven 3.1.x and above -->
@@ -239,7 +257,7 @@
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
-      <version>4.13.1</version>
+      <version>4.13.2</version>
       <scope>test</scope>
     </dependency>
 
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/ArtifactDeployerDelegate.java b/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/ArtifactDeployerDelegate.java
new file mode 100644
index 0000000..50d0d14
--- /dev/null
+++ b/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/ArtifactDeployerDelegate.java
@@ -0,0 +1,60 @@
+package org.apache.maven.shared.transfer.artifact.deploy.internal;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.Collection;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.project.ProjectBuildingRequest;
+import org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployerException;
+
+/**
+ * 
+ */
+public interface ArtifactDeployerDelegate
+{
+
+    /**
+     * @param request {@link ProjectBuildingRequest}
+     * @param mavenArtifacts {@link Artifact}
+     * @throws ArtifactDeployerException in case of an error.
+     * @throws IllegalArgumentException in case of parameter <code>request</code> is <code>null</code> or parameter
+     *             <code>mavenArtifacts</code> is <code>null</code> or <code>mavenArtifacts.isEmpty()</code> is
+     *             <code>true</code>.
+     */
+    void deploy(ProjectBuildingRequest request, Collection<Artifact> mavenArtifacts)
+        throws ArtifactDeployerException;
+
+    /**
+     * @param request the building request
+     * @param remoteRepository the repository to deploy to. If {@code null} the {@code mavenArtifact.getRepository()} is
+     *            used.
+     * @param mavenArtifacts the artifacts to deploy
+     * @throws ArtifactDeployerException in case of an error.
+     * @throws IllegalArgumentException in case of parameter <code>request</code> is <code>null</code> or parameter
+     *             <code>mavenArtifacts</code> is <code>null</code> or <code>mavenArtifacts.isEmpty()</code> is
+     *             <code>true</code>.
+     */
+    void deploy(ProjectBuildingRequest request, ArtifactRepository remoteRepository,
+                Collection<Artifact> mavenArtifacts)
+        throws ArtifactDeployerException;
+
+}
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/DefaultArtifactDeployer.java b/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/DefaultArtifactDeployer.java
index 11a268c..cd125b9 100644
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/DefaultArtifactDeployer.java
+++ b/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/DefaultArtifactDeployer.java
@@ -20,58 +20,52 @@ package org.apache.maven.shared.transfer.artifact.deploy.internal;
  */
 
 import java.util.Collection;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
 
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployer;
 import org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployerException;
-import org.codehaus.plexus.PlexusConstants;
-import org.codehaus.plexus.PlexusContainer;
-import org.codehaus.plexus.component.annotations.Component;
-import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
-import org.codehaus.plexus.context.Context;
-import org.codehaus.plexus.context.ContextException;
-import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
+import org.apache.maven.shared.transfer.internal.Delegator;
 
 /**
  *
  */
-@Component( role = ArtifactDeployer.class )
-class DefaultArtifactDeployer implements ArtifactDeployer, Contextualizable
+@Singleton
+@Named
+public class DefaultArtifactDeployer
+    extends Delegator<ArtifactDeployerDelegate>
+    implements ArtifactDeployer
 {
+    private final ArtifactDeployerDelegate delegate;
 
-    private PlexusContainer container;
+    @Inject
+    public DefaultArtifactDeployer(final Map<String, ArtifactDeployerDelegate> delegates)
+    {
+        super(delegates);
+        this.delegate = selectDelegate();
+    }
 
     @Override
-    public void deploy( ProjectBuildingRequest request, Collection<Artifact> mavenArtifacts )
-            throws ArtifactDeployerException
+    public void deploy(final ProjectBuildingRequest request,
+                       final Collection<Artifact> mavenArtifacts) throws ArtifactDeployerException
     {
-        validateParameters( request, mavenArtifacts );
-
-        try
-        {
-            getMavenArtifactDeployer( request ).deploy( mavenArtifacts );
-        }
-        catch ( ComponentLookupException e )
-        {
-            throw new ArtifactDeployerException( e.getMessage(), e );
-        }
+        validateParameters(request, mavenArtifacts);
+        delegate.deploy(request, mavenArtifacts);
     }
 
     @Override
-    public void deploy( ProjectBuildingRequest request, ArtifactRepository remoteRepository,
-            Collection<Artifact> mavenArtifacts ) throws ArtifactDeployerException
+    public void deploy(final ProjectBuildingRequest request,
+                       final ArtifactRepository remoteRepository,
+                       final Collection<Artifact> mavenArtifacts) throws ArtifactDeployerException
     {
         validateParameters( request, mavenArtifacts );
-        try
-        {
-            getMavenArtifactDeployer( request ).deploy( remoteRepository, mavenArtifacts );
-        }
-        catch ( ComponentLookupException e )
-        {
-            throw new ArtifactDeployerException( e.getMessage(), e );
-        }
+        delegate.deploy(request, remoteRepository, mavenArtifacts);
     }
 
     private void validateParameters( ProjectBuildingRequest request, Collection<Artifact> mavenArtifacts )
@@ -89,57 +83,4 @@ class DefaultArtifactDeployer implements ArtifactDeployer, Contextualizable
             throw new IllegalArgumentException( "The collection mavenArtifacts is not allowed to be empty." );
         }
     }
-
-    /**
-     * @return true if the current Maven version is Maven 3.1.
-     */
-    private boolean isMaven31()
-    {
-        try
-        {
-            // Maven 3.1 specific
-            Thread.currentThread().getContextClassLoader().loadClass( "org.eclipse.aether.artifact.Artifact" );
-            return true;
-        }
-        catch ( ClassNotFoundException e )
-        {
-            return false;
-        }
-    }
-
-    /**
-     * Injects the Plexus content.
-     *
-     * @param context Plexus context to inject.
-     * @throws ContextException if the PlexusContainer could not be located.
-     */
-    public void contextualize( Context context ) throws ContextException
-    {
-        container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
-    }
-
-    private MavenArtifactDeployer getMavenArtifactDeployer( ProjectBuildingRequest buildingRequest )
-            throws ComponentLookupException, ArtifactDeployerException
-    {
-        if ( isMaven31() )
-        {
-            org.eclipse.aether.RepositorySystem repositorySystem = container.lookup(
-                    org.eclipse.aether.RepositorySystem.class );
-
-            org.eclipse.aether.RepositorySystemSession session = Invoker.invoke( buildingRequest,
-                    "getRepositorySession" );
-
-            return new Maven31ArtifactDeployer( repositorySystem, session );
-        }
-        else
-        {
-            org.sonatype.aether.RepositorySystem repositorySystem = container.lookup(
-                    org.sonatype.aether.RepositorySystem.class );
-
-            org.sonatype.aether.RepositorySystemSession session = Invoker.invoke( buildingRequest,
-                    "getRepositorySession" );
-
-            return new Maven30ArtifactDeployer( repositorySystem, session );
-        }
-    }
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/Invoker.java b/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/Invoker.java
deleted file mode 100644
index 485e58d..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/Invoker.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package org.apache.maven.shared.transfer.artifact.deploy.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.lang.reflect.InvocationTargetException;
-
-import org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployerException;
-
-/**
- * Invokes method on objects using reflection.
- */
-final class Invoker
-{
-    private Invoker()
-    {
-        // do not instantiate
-    }
-
-    public static <T> T invoke( Object object, String method )
-        throws ArtifactDeployerException
-    {
-        try
-        {
-            @SuppressWarnings( "unchecked" )
-            T invoke = (T) object.getClass().getMethod( method ).invoke( object );
-            return invoke;
-        }
-        catch ( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
-        {
-            throw new ArtifactDeployerException( e.getMessage(), e );
-        }
-    }
-
-    public static <T> T invoke( Class<?> objectClazz, String staticMethod, Class<?> argClazz, Object arg )
-                    throws ArtifactDeployerException
-    {
-        try
-        {
-            @SuppressWarnings( "unchecked" )
-            T invoke = (T) objectClazz.getMethod( staticMethod, argClazz ).invoke( null, arg );
-            return invoke;
-        }
-        catch ( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
-        {
-            throw new ArtifactDeployerException( e.getMessage(), e );
-        }
-    }
-
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/Maven30ArtifactDeployer.java b/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/Maven30ArtifactDeployer.java
deleted file mode 100644
index 611eb4c..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/Maven30ArtifactDeployer.java
+++ /dev/null
@@ -1,150 +0,0 @@
-package org.apache.maven.shared.transfer.artifact.deploy.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.Collection;
-
-import org.apache.maven.RepositoryUtils;
-import org.apache.maven.artifact.metadata.ArtifactMetadata;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;
-import org.apache.maven.project.artifact.ProjectArtifactMetadata;
-import org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployerException;
-import org.apache.maven.shared.transfer.metadata.internal.Maven30MetadataBridge;
-import org.sonatype.aether.RepositorySystem;
-import org.sonatype.aether.RepositorySystemSession;
-import org.sonatype.aether.artifact.Artifact;
-import org.sonatype.aether.deployment.DeployRequest;
-import org.sonatype.aether.deployment.DeploymentException;
-import org.sonatype.aether.repository.RemoteRepository;
-import org.sonatype.aether.util.artifact.SubArtifact;
-
-/**
- * 
- */
-class Maven30ArtifactDeployer
-    implements MavenArtifactDeployer
-{
-
-    private final RepositorySystem repositorySystem;
-    
-    private final RepositorySystemSession session;
-    
-    Maven30ArtifactDeployer( RepositorySystem repositorySystem, RepositorySystemSession session )
-    {
-        this.repositorySystem = repositorySystem;
-        this.session = session;
-    }
-
-    @Override
-    public void deploy( Collection<org.apache.maven.artifact.Artifact> mavenArtifacts )
-                            throws ArtifactDeployerException
-    {
-        deploy( null, mavenArtifacts );
-    }
-
-    @Override
-    public void deploy( ArtifactRepository remoteRepository,
-                        Collection<org.apache.maven.artifact.Artifact> mavenArtifacts )
-                            throws ArtifactDeployerException
-    {
-        // prepare request
-        DeployRequest request = new DeployRequest();
-
-        RemoteRepository defaultRepository = null;
-
-        if ( remoteRepository != null )
-        {
-            defaultRepository = getRemoteRepository( session, remoteRepository );
-        }
-
-        // transform artifacts
-        for ( org.apache.maven.artifact.Artifact mavenArtifact : mavenArtifacts )
-        {
-            Artifact aetherArtifact = Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                                       org.apache.maven.artifact.Artifact.class, mavenArtifact );
-            request.addArtifact( aetherArtifact );
-
-            RemoteRepository aetherRepository;
-            if ( remoteRepository == null )
-            {
-                aetherRepository = getRemoteRepository( session, mavenArtifact.getRepository() );
-            }
-            else
-            {
-                aetherRepository = defaultRepository;
-            }
-
-            request.setRepository( aetherRepository );
-
-            for ( ArtifactMetadata metadata : mavenArtifact.getMetadataList() )
-            {
-                if ( metadata instanceof ProjectArtifactMetadata )
-                {
-                    Artifact pomArtifact = new SubArtifact( aetherArtifact, "", "pom" );
-                    pomArtifact = pomArtifact.setFile( ( (ProjectArtifactMetadata) metadata ).getFile() );
-                    request.addArtifact( pomArtifact );
-                }
-                else if ( // metadata instanceof SnapshotArtifactRepositoryMetadata ||
-                metadata instanceof ArtifactRepositoryMetadata )
-                {
-                    // eaten, handled by repo system
-                }
-                else if ( metadata instanceof org.apache.maven.shared.transfer.metadata.ArtifactMetadata )
-                {
-                    org.apache.maven.shared.transfer.metadata.ArtifactMetadata transferMedata =
-                                    ( org.apache.maven.shared.transfer.metadata.ArtifactMetadata ) metadata;
-                    
-                    request.addMetadata( new Maven30MetadataBridge( metadata ).setFile( transferMedata.getFile() ) );
-                }
-            }
-        }
-
-        // deploy
-        try
-        {
-            repositorySystem.deploy( session, request );
-        }
-        catch ( DeploymentException e )
-        {
-            throw new ArtifactDeployerException( e.getMessage(), e );
-        }
-    }
-
-    private RemoteRepository getRemoteRepository( RepositorySystemSession session, ArtifactRepository remoteRepository )
-        throws ArtifactDeployerException
-    {
-        RemoteRepository aetherRepo = Invoker.invoke( RepositoryUtils.class, "toRepo",
-                                                                         ArtifactRepository.class,
-                                                                         remoteRepository );
-
-        if ( aetherRepo.getAuthentication() == null )
-        {
-            aetherRepo.setAuthentication( session.getAuthenticationSelector().getAuthentication( aetherRepo ) );
-        }
-
-        if ( aetherRepo.getProxy() == null )
-        {
-            aetherRepo.setProxy( session.getProxySelector().getProxy( aetherRepo ) );
-        }
-
-        return aetherRepo;
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/Maven31ArtifactDeployer.java b/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/Maven31ArtifactDeployer.java
index ed61b12..aa8c6a1 100644
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/Maven31ArtifactDeployer.java
+++ b/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/Maven31ArtifactDeployer.java
@@ -20,13 +20,22 @@ package org.apache.maven.shared.transfer.artifact.deploy.internal;
  */
 
 import java.util.Collection;
+import java.util.Objects;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
 
 import org.apache.maven.RepositoryUtils;
 import org.apache.maven.artifact.metadata.ArtifactMetadata;
 import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;
+import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.project.artifact.ProjectArtifactMetadata;
+import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException;
 import org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployerException;
+import org.apache.maven.shared.transfer.internal.ComponentSupport;
+import org.apache.maven.shared.transfer.internal.Selector;
 import org.apache.maven.shared.transfer.metadata.internal.Maven31MetadataBridge;
 import org.eclipse.aether.RepositorySystem;
 import org.eclipse.aether.RepositorySystemSession;
@@ -39,29 +48,31 @@ import org.eclipse.aether.util.artifact.SubArtifact;
 /**
  *
  */
-class Maven31ArtifactDeployer implements MavenArtifactDeployer
+@Singleton
+@Named(Selector.MAVEN_3_1)
+public class Maven31ArtifactDeployer
+    extends ComponentSupport
+    implements ArtifactDeployerDelegate
 {
-
     private final RepositorySystem repositorySystem;
 
-    private final RepositorySystemSession session;
-
-    Maven31ArtifactDeployer( RepositorySystem repositorySystem, RepositorySystemSession session )
+    @Inject
+    public Maven31ArtifactDeployer( RepositorySystem repositorySystem )
     {
-        super();
-        this.repositorySystem = repositorySystem;
-        this.session = session;
+        this.repositorySystem = Objects.requireNonNull( repositorySystem );
     }
 
     @Override
-    public void deploy( Collection<org.apache.maven.artifact.Artifact> mavenArtifacts ) throws ArtifactDeployerException
+    public void deploy(ProjectBuildingRequest buildingRequest,
+                       Collection<org.apache.maven.artifact.Artifact> mavenArtifacts ) throws ArtifactDeployerException
     {
-        deploy( null, mavenArtifacts );
+        deploy( buildingRequest, null, mavenArtifacts );
     }
 
     @Override
-    public void deploy( ArtifactRepository remoteRepository,
-            Collection<org.apache.maven.artifact.Artifact> mavenArtifacts ) throws ArtifactDeployerException
+    public void deploy( ProjectBuildingRequest buildingRequest,
+                        ArtifactRepository remoteRepository,
+                        Collection<org.apache.maven.artifact.Artifact> mavenArtifacts ) throws ArtifactDeployerException
     {
         // prepare request
         DeployRequest request = new DeployRequest();
@@ -70,20 +81,21 @@ class Maven31ArtifactDeployer implements MavenArtifactDeployer
 
         if ( remoteRepository != null )
         {
-            defaultRepository = getRemoteRepository( session, remoteRepository );
+            defaultRepository = getRemoteRepository( buildingRequest.getRepositorySession(), remoteRepository );
         }
 
         // transform artifacts
         for ( org.apache.maven.artifact.Artifact mavenArtifact : mavenArtifacts )
         {
-            Artifact aetherArtifact = Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                    org.apache.maven.artifact.Artifact.class, mavenArtifact );
+            Artifact aetherArtifact = RepositoryUtils.toArtifact(mavenArtifact);
             request.addArtifact( aetherArtifact );
 
             RemoteRepository aetherRepository;
             if ( remoteRepository == null )
             {
-                aetherRepository = getRemoteRepository( session, mavenArtifact.getRepository() );
+                aetherRepository = getRemoteRepository(
+                    buildingRequest.getRepositorySession(), mavenArtifact.getRepository()
+                );
             }
             else
             {
@@ -118,7 +130,7 @@ class Maven31ArtifactDeployer implements MavenArtifactDeployer
         // deploy
         try
         {
-            repositorySystem.deploy( session, request );
+            repositorySystem.deploy( buildingRequest.getRepositorySession(), request );
         }
         catch ( DeploymentException e )
         {
@@ -127,10 +139,8 @@ class Maven31ArtifactDeployer implements MavenArtifactDeployer
     }
 
     private RemoteRepository getRemoteRepository( RepositorySystemSession session, ArtifactRepository remoteRepository )
-            throws ArtifactDeployerException
     {
-        RemoteRepository aetherRepo = Invoker.invoke( RepositoryUtils.class, "toRepo", ArtifactRepository.class,
-                remoteRepository );
+        RemoteRepository aetherRepo = RepositoryUtils.toRepo(remoteRepository);
 
         if ( aetherRepo.getAuthentication() == null || aetherRepo.getProxy() == null )
         {
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/MavenArtifactInstaller.java b/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/ArtifactInstallerDelegate.java
similarity index 78%
copy from src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/MavenArtifactInstaller.java
copy to src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/ArtifactInstallerDelegate.java
index 6d6509d..cbcacf9 100644
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/MavenArtifactInstaller.java
+++ b/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/ArtifactInstallerDelegate.java
@@ -19,18 +19,11 @@ package org.apache.maven.shared.transfer.artifact.install.internal;
  * under the License.
  */
 
-import java.util.Collection;
-
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.shared.transfer.artifact.install.ArtifactInstallerException;
+import org.apache.maven.shared.transfer.artifact.install.ArtifactInstaller;
 
 /**
- * 
- * @author Robert Scholte
  *
  */
-interface MavenArtifactInstaller
+public interface ArtifactInstallerDelegate extends ArtifactInstaller
 {
-    void install( Collection<Artifact> mavenArtifacts )
-        throws ArtifactInstallerException;
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/DefaultArtifactInstaller.java b/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/DefaultArtifactInstaller.java
index 238e814..212e0c9 100644
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/DefaultArtifactInstaller.java
+++ b/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/DefaultArtifactInstaller.java
@@ -21,74 +21,72 @@ package org.apache.maven.shared.transfer.artifact.install.internal;
 
 import java.io.File;
 import java.util.Collection;
+import java.util.Map;
+import java.util.Objects;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
 
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.shared.transfer.artifact.install.ArtifactInstaller;
 import org.apache.maven.shared.transfer.artifact.install.ArtifactInstallerException;
+import org.apache.maven.shared.transfer.internal.Delegator;
 import org.apache.maven.shared.transfer.repository.RepositoryManager;
-import org.codehaus.plexus.PlexusConstants;
-import org.codehaus.plexus.PlexusContainer;
-import org.codehaus.plexus.component.annotations.Component;
-import org.codehaus.plexus.component.annotations.Requirement;
-import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
-import org.codehaus.plexus.context.Context;
-import org.codehaus.plexus.context.ContextException;
-import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
 
 /**
  *
  */
-@Component( role = ArtifactInstaller.class )
-class DefaultArtifactInstaller implements ArtifactInstaller, Contextualizable
+@Singleton
+@Named
+public class DefaultArtifactInstaller
+    extends Delegator<ArtifactInstallerDelegate>
+    implements ArtifactInstaller
 {
-    private PlexusContainer container;
+    private final ArtifactInstallerDelegate delegate;
 
-    @Requirement
-    private RepositoryManager repositoryManager;
+    private final RepositoryManager repositoryManager;
+
+    @Inject
+    public DefaultArtifactInstaller(final Map<String, ArtifactInstallerDelegate> delegates,
+                                    final RepositoryManager repositoryManager)
+    {
+        super(delegates);
+        this.delegate = selectDelegate();
+        this.repositoryManager = Objects.requireNonNull( repositoryManager );
+    }
 
     @Override
-    public void install( ProjectBuildingRequest request, Collection<Artifact> mavenArtifacts )
-            throws ArtifactInstallerException, IllegalArgumentException
+    public void install(final ProjectBuildingRequest request,
+                        final Collection<Artifact> mavenArtifacts)
+        throws ArtifactInstallerException, IllegalArgumentException
     {
         validateParameters( request, mavenArtifacts );
-        try
-        {
-            getMavenArtifactInstaller( request ).install( mavenArtifacts );
-        }
-        catch ( ComponentLookupException e )
-        {
-            throw new ArtifactInstallerException( e.getMessage(), e );
-        }
+        delegate.install(request, mavenArtifacts);
     }
 
     @Override
-    public void install( ProjectBuildingRequest request, File localRepositry, Collection<Artifact> mavenArtifacts )
-            throws ArtifactInstallerException
+    public void install(final ProjectBuildingRequest request,
+                        final File localRepository,
+                        final Collection<Artifact> mavenArtifacts) throws ArtifactInstallerException
     {
         validateParameters( request, mavenArtifacts );
-        if ( localRepositry == null )
+        if ( localRepository == null )
         {
             throw new IllegalArgumentException( "The parameter localRepository is not allowed to be null." );
         }
-        if ( !localRepositry.isDirectory() )
+        if ( !localRepository.isDirectory() )
         {
             throw new IllegalArgumentException( "The parameter localRepository must be a directory." );
         }
 
         // TODO: Should we check for exists() ?
 
-        // update local repo in request 
-        ProjectBuildingRequest newRequest = repositoryManager.setLocalRepositoryBasedir( request, localRepositry );
+        // update local repo in request
+        ProjectBuildingRequest newRequest = repositoryManager.setLocalRepositoryBasedir( request, localRepository );
 
-        try
-        {
-            getMavenArtifactInstaller( newRequest ).install( mavenArtifacts );
-        }
-        catch ( ComponentLookupException e )
-        {
-            throw new ArtifactInstallerException( e.getMessage(), e );
-        }
+        delegate.install(newRequest, mavenArtifacts);
     }
 
     private void validateParameters( ProjectBuildingRequest request, Collection<Artifact> mavenArtifacts )
@@ -106,57 +104,4 @@ class DefaultArtifactInstaller implements ArtifactInstaller, Contextualizable
             throw new IllegalArgumentException( "The collection mavenArtifacts is not allowed to be empty." );
         }
     }
-
-    /**
-     * @return true if the current Maven version is Maven 3.1.
-     */
-    private boolean isMaven31()
-    {
-        try
-        {
-            // Maven 3.1 specific
-            Thread.currentThread().getContextClassLoader().loadClass( "org.eclipse.aether.artifact.Artifact" );
-            return true;
-        }
-        catch ( ClassNotFoundException e )
-        {
-            return false;
-        }
-    }
-
-    /**
-     * Injects the Plexus content.
-     *
-     * @param context Plexus context to inject.
-     * @throws ContextException if the PlexusContainer could not be located.
-     */
-    public void contextualize( Context context ) throws ContextException
-    {
-        container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
-    }
-
-    private MavenArtifactInstaller getMavenArtifactInstaller( ProjectBuildingRequest buildingRequest )
-            throws ComponentLookupException, ArtifactInstallerException
-    {
-        if ( isMaven31() )
-        {
-            org.eclipse.aether.RepositorySystem repositorySystem = container.lookup(
-                    org.eclipse.aether.RepositorySystem.class );
-
-            org.eclipse.aether.RepositorySystemSession session = Invoker.invoke( buildingRequest,
-                    "getRepositorySession" );
-
-            return new Maven31ArtifactInstaller( repositorySystem, session );
-        }
-        else
-        {
-            org.sonatype.aether.RepositorySystem repositorySystem = container.lookup(
-                    org.sonatype.aether.RepositorySystem.class );
-
-            org.sonatype.aether.RepositorySystemSession session = Invoker.invoke( buildingRequest,
-                    "getRepositorySession" );
-
-            return new Maven30ArtifactInstaller( repositorySystem, session );
-        }
-    }
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/Invoker.java b/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/Invoker.java
deleted file mode 100644
index eb8c69e..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/Invoker.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package org.apache.maven.shared.transfer.artifact.install.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.lang.reflect.InvocationTargetException;
-
-import org.apache.maven.shared.transfer.artifact.install.ArtifactInstallerException;
-
-/**
- * Invokes method on objects using reflection.
- */
-final class Invoker
-{
-    private Invoker()
-    {
-        // do not instantiate
-    }
-
-    public static <T> T invoke( Object object, String method )
-        throws ArtifactInstallerException
-    {
-        try
-        {
-            @SuppressWarnings( "unchecked" )
-            T invoke = (T) object.getClass().getMethod( method ).invoke( object );
-            return invoke;
-        }
-        catch ( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
-        {
-            throw new ArtifactInstallerException( e.getMessage(), e );
-        }
-    }
-
-    public static <T> T invoke( Class<?> objectClazz, String staticMethod, Class<?> argClazz, Object arg )
-        throws ArtifactInstallerException
-    {
-        try
-        {
-            @SuppressWarnings( "unchecked" )
-            T invoke = (T) objectClazz.getMethod( staticMethod, argClazz ).invoke( null, arg );
-            return invoke;
-        }
-        catch ( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
-        {
-            throw new ArtifactInstallerException( e.getMessage(), e );
-        }
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven30ArtifactInstaller.java b/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven30ArtifactInstaller.java
deleted file mode 100644
index fbff698..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven30ArtifactInstaller.java
+++ /dev/null
@@ -1,105 +0,0 @@
-package org.apache.maven.shared.transfer.artifact.install.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.Collection;
-
-import org.apache.maven.RepositoryUtils;
-import org.apache.maven.artifact.metadata.ArtifactMetadata;
-import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;
-import org.apache.maven.project.artifact.ProjectArtifactMetadata;
-import org.apache.maven.shared.transfer.artifact.install.ArtifactInstallerException;
-import org.apache.maven.shared.transfer.metadata.internal.Maven30MetadataBridge;
-import org.sonatype.aether.RepositorySystem;
-import org.sonatype.aether.RepositorySystemSession;
-import org.sonatype.aether.artifact.Artifact;
-import org.sonatype.aether.installation.InstallRequest;
-import org.sonatype.aether.installation.InstallationException;
-import org.sonatype.aether.util.artifact.SubArtifact;
-
-/**
- * 
- */
-class Maven30ArtifactInstaller
-    implements MavenArtifactInstaller
-{
-    private final RepositorySystem repositorySystem;
-    
-    private final RepositorySystemSession session; 
-    
-    Maven30ArtifactInstaller( RepositorySystem repositorySystem, RepositorySystemSession session )
-    {
-        this.repositorySystem = repositorySystem;
-        this.session = session;
-    }
-
-    @Override
-    public void install( Collection<org.apache.maven.artifact.Artifact> mavenArtifacts )
-        throws ArtifactInstallerException
-    {
-        // prepare installRequest
-        InstallRequest request = new InstallRequest();
-
-        // transform artifacts
-        for ( org.apache.maven.artifact.Artifact mavenArtifact : mavenArtifacts )
-        {
-            Artifact mainArtifact = Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                                       org.apache.maven.artifact.Artifact.class, mavenArtifact );
-            request.addArtifact( mainArtifact );
-
-            for ( ArtifactMetadata metadata : mavenArtifact.getMetadataList() )
-            {
-                if ( metadata instanceof ProjectArtifactMetadata )
-                {
-                    Artifact pomArtifact = new SubArtifact( mainArtifact, "", "pom" );
-                    pomArtifact = pomArtifact.setFile( ( (ProjectArtifactMetadata) metadata ).getFile() );
-                    request.addArtifact( pomArtifact );
-                }
-                else if ( // metadata instanceof SnapshotArtifactRepositoryMetadata ||
-                metadata instanceof ArtifactRepositoryMetadata )
-                {
-                    // eaten, handled by repo system
-                }
-                else if ( metadata instanceof org.apache.maven.shared.transfer.metadata.ArtifactMetadata )
-                {
-                    org.apache.maven.shared.transfer.metadata.ArtifactMetadata transferMedata =
-                                    ( org.apache.maven.shared.transfer.metadata.ArtifactMetadata ) metadata;
-                    
-                    request.addMetadata( new Maven30MetadataBridge( metadata ).setFile( transferMedata.getFile() ) );
-                }
-            }
-        }
-
-//        if ( localRepository != null )
-//        {
-//            buildingRequest = repositoryManager.setLocalRepositoryBasedir( buildingRequest, localRepository );
-//        }
-        
-        // install
-        try
-        {
-            repositorySystem.install( session, request );
-        }
-        catch ( InstallationException e )
-        {
-            throw new ArtifactInstallerException( e.getMessage(), e );
-        }
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven31ArtifactInstaller.java b/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven31ArtifactInstaller.java
index aa15504..5ff1003 100644
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven31ArtifactInstaller.java
+++ b/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven31ArtifactInstaller.java
@@ -19,13 +19,22 @@ package org.apache.maven.shared.transfer.artifact.install.internal;
  * under the License.
  */
 
+import java.io.File;
 import java.util.Collection;
+import java.util.Objects;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
 
 import org.apache.maven.RepositoryUtils;
 import org.apache.maven.artifact.metadata.ArtifactMetadata;
 import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;
+import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.project.artifact.ProjectArtifactMetadata;
 import org.apache.maven.shared.transfer.artifact.install.ArtifactInstallerException;
+import org.apache.maven.shared.transfer.internal.ComponentSupport;
+import org.apache.maven.shared.transfer.internal.Selector;
 import org.apache.maven.shared.transfer.metadata.internal.Maven31MetadataBridge;
 import org.eclipse.aether.RepositorySystem;
 import org.eclipse.aether.RepositorySystemSession;
@@ -37,23 +46,25 @@ import org.eclipse.aether.util.artifact.SubArtifact;
 /**
  * 
  */
-class Maven31ArtifactInstaller
-    implements MavenArtifactInstaller
+@Singleton
+@Named(Selector.MAVEN_3_1)
+public class Maven31ArtifactInstaller
+    extends ComponentSupport
+    implements ArtifactInstallerDelegate
 {
     private final RepositorySystem repositorySystem;
 
-    private final RepositorySystemSession session;
-    
-    Maven31ArtifactInstaller( RepositorySystem repositorySystem,
-                                     RepositorySystemSession session )
+    @Inject
+    public Maven31ArtifactInstaller( RepositorySystem repositorySystem )
     {
-        this.repositorySystem = repositorySystem;
-        this.session = session;
+        this.repositorySystem = Objects.requireNonNull( repositorySystem );
     }
 
+
     @Override
-    public void install( Collection<org.apache.maven.artifact.Artifact> mavenArtifacts )
-                             throws ArtifactInstallerException
+    public void install(ProjectBuildingRequest buildingRequest,
+                        Collection<org.apache.maven.artifact.Artifact> mavenArtifacts )
+        throws ArtifactInstallerException
     {
         // prepare installRequest
         InstallRequest request = new InstallRequest();
@@ -61,8 +72,7 @@ class Maven31ArtifactInstaller
         // transform artifacts
         for ( org.apache.maven.artifact.Artifact mavenArtifact : mavenArtifacts )
         {
-            Artifact mainArtifact = Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                                       org.apache.maven.artifact.Artifact.class, mavenArtifact );
+            Artifact mainArtifact = RepositoryUtils.toArtifact(mavenArtifact);
             request.addArtifact( mainArtifact );
 
             for ( ArtifactMetadata metadata : mavenArtifact.getMetadataList() )
@@ -91,11 +101,20 @@ class Maven31ArtifactInstaller
         // install
         try
         {
-            repositorySystem.install( session, request );
+            repositorySystem.install( buildingRequest.getRepositorySession(), request );
         }
         catch ( InstallationException e )
         {
             throw new ArtifactInstallerException( e.getMessage(), e );
         }
     }
+
+    @Override
+    public void install(final ProjectBuildingRequest request,
+                        final File localRepository,
+                        final Collection<org.apache.maven.artifact.Artifact> mavenArtifacts)
+        throws ArtifactInstallerException
+    {
+        throw new UnsupportedOperationException("how did we get here?");
+    }
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/MavenArtifactResolver.java b/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/ArtifactResolverDelegate.java
similarity index 67%
rename from src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/MavenArtifactResolver.java
rename to src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/ArtifactResolverDelegate.java
index 2413968..69e29e6 100644
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/MavenArtifactResolver.java
+++ b/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/ArtifactResolverDelegate.java
@@ -19,20 +19,11 @@ package org.apache.maven.shared.transfer.artifact.resolve.internal;
  * under the License.
  */
 
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate;
-import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException;
-import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult;
+import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver;
 
 /**
- * 
- * @author Robert Scholte
  *
  */
-interface MavenArtifactResolver
+public interface ArtifactResolverDelegate extends ArtifactResolver
 {
-    ArtifactResult resolveArtifact( Artifact mavenArtifact ) throws ArtifactResolverException;
-
-    ArtifactResult resolveArtifact( ArtifactCoordinate coordinate ) throws ArtifactResolverException;
-
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/DefaultArtifactResolver.java b/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/DefaultArtifactResolver.java
index 83d7517..6ac1bbf 100644
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/DefaultArtifactResolver.java
+++ b/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/DefaultArtifactResolver.java
@@ -19,60 +19,54 @@ package org.apache.maven.shared.transfer.artifact.resolve.internal;
  * under the License.
  */
 
-import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
 
-import org.apache.maven.RepositoryUtils;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate;
 import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver;
 import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException;
 import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult;
-import org.codehaus.plexus.PlexusConstants;
-import org.codehaus.plexus.PlexusContainer;
-import org.codehaus.plexus.component.annotations.Component;
-import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
-import org.codehaus.plexus.context.Context;
-import org.codehaus.plexus.context.ContextException;
-import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
-
+import org.apache.maven.shared.transfer.internal.Delegator;
 
 /**
  *
  */
-@Component( role = ArtifactResolver.class, hint = "default" )
-class DefaultArtifactResolver implements ArtifactResolver, Contextualizable
+@Singleton
+@Named
+public class DefaultArtifactResolver
+    extends Delegator<ArtifactResolverDelegate>
+    implements ArtifactResolver
 {
-    private PlexusContainer container;
+    private ArtifactResolverDelegate delegate;
+
+    @Inject
+    public DefaultArtifactResolver(final Map<String, ArtifactResolverDelegate> delegates)
+    {
+        super(delegates);
+        this.delegate = selectDelegate();
+    }
 
     @Override
-    public ArtifactResult resolveArtifact( ProjectBuildingRequest buildingRequest, Artifact mavenArtifact )
-            throws ArtifactResolverException, IllegalArgumentException
+    public ArtifactResult resolveArtifact(final ProjectBuildingRequest buildingRequest,
+                                          final Artifact mavenArtifact)
+        throws ArtifactResolverException, IllegalArgumentException
     {
         validateParameters( buildingRequest, mavenArtifact );
-        try
-        {
-            return getMavenArtifactResolver( buildingRequest ).resolveArtifact( mavenArtifact );
-        }
-        catch ( ComponentLookupException e )
-        {
-            throw new ArtifactResolverException( e.getMessage(), e );
-        }
+        return delegate.resolveArtifact(buildingRequest, mavenArtifact);
     }
 
     @Override
-    public ArtifactResult resolveArtifact( ProjectBuildingRequest buildingRequest, ArtifactCoordinate coordinate )
-            throws ArtifactResolverException, IllegalArgumentException
+    public ArtifactResult resolveArtifact(final ProjectBuildingRequest buildingRequest,
+                                          final ArtifactCoordinate coordinate)
+        throws ArtifactResolverException, IllegalArgumentException
     {
         validateParameters( buildingRequest, coordinate );
-        try
-        {
-            return getMavenArtifactResolver( buildingRequest ).resolveArtifact( coordinate );
-        }
-        catch ( ComponentLookupException e )
-        {
-            throw new ArtifactResolverException( e.getMessage(), e );
-        }
+        return delegate.resolveArtifact(buildingRequest, coordinate);
     }
 
     private void validateParameters( ProjectBuildingRequest buildingRequest, Artifact mavenArtifact )
@@ -98,66 +92,4 @@ class DefaultArtifactResolver implements ArtifactResolver, Contextualizable
             throw new IllegalArgumentException( "The parameter coordinate is not allowed to be null." );
         }
     }
-
-    /**
-     * @return true if the current Maven version is Maven 3.1.
-     */
-    private boolean isMaven31()
-    {
-        try
-        {
-            // Maven 3.1 specific
-            Thread.currentThread().getContextClassLoader().loadClass( "org.eclipse.aether.artifact.Artifact" );
-            return true;
-        }
-        catch ( ClassNotFoundException e )
-        {
-            return false;
-        }
-    }
-
-    /**
-     * Injects the Plexus content.
-     *
-     * @param context Plexus context to inject.
-     * @throws ContextException if the PlexusContainer could not be located.
-     */
-    public void contextualize( Context context ) throws ContextException
-    {
-        container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
-    }
-
-    private MavenArtifactResolver getMavenArtifactResolver( ProjectBuildingRequest buildingRequest )
-            throws ComponentLookupException, ArtifactResolverException
-    {
-        if ( isMaven31() )
-        {
-            org.eclipse.aether.RepositorySystem repositorySystem = container.lookup(
-                    org.eclipse.aether.RepositorySystem.class );
-
-            List<org.eclipse.aether.repository.RemoteRepository> aetherRepositories = Invoker.invoke(
-                    RepositoryUtils.class, "toRepos", List.class, buildingRequest.getRemoteRepositories() );
-
-            org.eclipse.aether.RepositorySystemSession session = Invoker.invoke( buildingRequest,
-                    "getRepositorySession" );
-
-            return new Maven31ArtifactResolver( repositorySystem, aetherRepositories, session );
-
-        }
-        else
-        {
-            org.sonatype.aether.RepositorySystem repositorySystem = container.lookup(
-                    org.sonatype.aether.RepositorySystem.class );
-
-            List<org.sonatype.aether.repository.RemoteRepository> aetherRepositories = Invoker.invoke(
-                    RepositoryUtils.class, "toRepos", List.class, buildingRequest.getRemoteRepositories() );
-
-            org.sonatype.aether.RepositorySystemSession session = Invoker.invoke( buildingRequest,
-                    "getRepositorySession" );
-
-            return new Maven30ArtifactResolver( repositorySystem, aetherRepositories, session );
-        }
-
-
-    }
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/Invoker.java b/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/Invoker.java
deleted file mode 100644
index 329e2c6..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/Invoker.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package org.apache.maven.shared.transfer.artifact.resolve.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.lang.reflect.InvocationTargetException;
-
-import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException;
-
-/**
- * Invokes method on objects using reflection.
- */
-final class Invoker
-{
-
-    private Invoker()
-    {
-        // do not instantiate
-    }
-
-    public static <T> T invoke( Object object, String method )
-        throws ArtifactResolverException
-    {
-        try
-        {
-            @SuppressWarnings( "unchecked" )
-            T invoke = (T) object.getClass().getMethod( method ).invoke( object );
-            return invoke;
-        }
-        catch ( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
-        {
-            throw new ArtifactResolverException( e.getMessage(), e );
-        }
-    }
-
-    public static <T> T invoke( Class<?> objectClazz, String staticMethod, Class<?> argClazz, Object arg )
-        throws ArtifactResolverException
-    {
-        try
-        {
-            @SuppressWarnings( "unchecked" )
-            T invoke = (T) objectClazz.getMethod( staticMethod, argClazz ).invoke( null, arg );
-            return invoke;
-        }
-        catch ( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
-        {
-            throw new ArtifactResolverException( e.getMessage(), e );
-        }
-    }
-
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/Maven30ArtifactResolver.java b/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/Maven30ArtifactResolver.java
deleted file mode 100644
index 95a6dc5..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/Maven30ArtifactResolver.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package org.apache.maven.shared.transfer.artifact.resolve.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.List;
-
-import org.apache.maven.RepositoryUtils;
-import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate;
-import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException;
-import org.sonatype.aether.RepositorySystem;
-import org.sonatype.aether.RepositorySystemSession;
-import org.sonatype.aether.artifact.Artifact;
-import org.sonatype.aether.repository.RemoteRepository;
-import org.sonatype.aether.resolution.ArtifactDescriptorException;
-import org.sonatype.aether.resolution.ArtifactDescriptorRequest;
-import org.sonatype.aether.resolution.ArtifactDescriptorResult;
-import org.sonatype.aether.resolution.ArtifactRequest;
-import org.sonatype.aether.resolution.ArtifactResolutionException;
-import org.sonatype.aether.util.artifact.DefaultArtifact;
-
-/**
- * 
- */
-class Maven30ArtifactResolver
-    implements MavenArtifactResolver
-{
-    private final RepositorySystem repositorySystem;
-
-    private final List<RemoteRepository> aetherRepositories;
-    
-    private final RepositorySystemSession session;
-
-    Maven30ArtifactResolver( RepositorySystem repositorySystem, List<RemoteRepository> aetherRepositories,
-                                    RepositorySystemSession session )
-    {
-        this.repositorySystem = repositorySystem;
-        this.aetherRepositories = aetherRepositories;
-        this.session = session;
-    }
-
-    @Override
-    // CHECKSTYLE_OFF: LineLength
-    public org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult resolveArtifact( org.apache.maven.artifact.Artifact mavenArtifact )
-                                                                                        throws ArtifactResolverException
-    // CHECKSTYLE_ON: LineLength
-    {
-        Artifact aetherArtifact = Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                                                             org.apache.maven.artifact.Artifact.class, mavenArtifact );
-
-        return resolveArtifact( aetherArtifact );
-    }
-
-    @Override
-    // CHECKSTYLE_OFF: LineLength
-    public org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult resolveArtifact( ArtifactCoordinate coordinate )
-                                                                                        throws ArtifactResolverException
-    // CHECKSTYLE_ON: LineLength
-    {
-        Artifact aetherArtifact =
-            new DefaultArtifact( coordinate.getGroupId(), coordinate.getArtifactId(), coordinate.getClassifier(),
-                                 coordinate.getExtension(), coordinate.getVersion() );
-
-        return resolveArtifact( aetherArtifact );
-    }
-
-    // CHECKSTYLE_OFF: LineLength
-    private org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult resolveArtifact( Artifact aetherArtifact )
-                                                                                         throws ArtifactResolverException
-    // CHECKSTYLE_ON: LineLength
-    {
-        try
-        {
-            // use descriptor to respect relocation
-            ArtifactDescriptorRequest descriptorRequest =
-                new ArtifactDescriptorRequest( aetherArtifact, aetherRepositories, null );
-
-            ArtifactDescriptorResult descriptorResult =
-                repositorySystem.readArtifactDescriptor( session, descriptorRequest );
-
-            ArtifactRequest request = new ArtifactRequest( descriptorResult.getArtifact(), aetherRepositories, null );
-
-            return new Maven30ArtifactResult( repositorySystem.resolveArtifact( session, request ) );
-        }
-        catch ( ArtifactDescriptorException | ArtifactResolutionException e )
-        {
-            throw new ArtifactResolverException( e.getMessage(), e );
-        }
-    }
-
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/Maven30ArtifactResult.java b/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/Maven30ArtifactResult.java
deleted file mode 100644
index 3bbea28..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/Maven30ArtifactResult.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.apache.maven.shared.transfer.artifact.resolve.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import org.apache.maven.RepositoryUtils;
-import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException;
-import org.sonatype.aether.artifact.Artifact;
-import org.sonatype.aether.resolution.ArtifactResult;
-
-/**
- * {@link org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult} wrapper for {@link ArtifactResult}
- *
- * @author Robert Scholte
- * @since 3.0
- */
-class Maven30ArtifactResult implements org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult
-{
-    private final ArtifactResult artifactResult;
-
-    /**
-     * @param artifactResult {@link ArtifactResult}
-     */
-    Maven30ArtifactResult( ArtifactResult artifactResult )
-    {
-        this.artifactResult = artifactResult;
-    }
-
-    @Override
-    public org.apache.maven.artifact.Artifact getArtifact()
-    {
-        try
-        {
-            return Invoker.invoke( RepositoryUtils.class, "toArtifact", Artifact.class, artifactResult.getArtifact() );
-        }
-        catch ( ArtifactResolverException e )
-        {
-            throw new RuntimeException( e );
-        }
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/Maven31ArtifactResolver.java b/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/Maven31ArtifactResolver.java
index 9ef5658..9ffb69e 100644
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/Maven31ArtifactResolver.java
+++ b/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/Maven31ArtifactResolver.java
@@ -20,10 +20,18 @@ package org.apache.maven.shared.transfer.artifact.resolve.internal;
  */
 
 import java.util.List;
+import java.util.Objects;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
 
 import org.apache.maven.RepositoryUtils;
+import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate;
 import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException;
+import org.apache.maven.shared.transfer.internal.ComponentSupport;
+import org.apache.maven.shared.transfer.internal.Selector;
 import org.eclipse.aether.RepositorySystem;
 import org.eclipse.aether.RepositorySystemSession;
 import org.eclipse.aether.artifact.Artifact;
@@ -38,50 +46,48 @@ import org.eclipse.aether.resolution.ArtifactResolutionException;
 /**
  * 
  */
-class Maven31ArtifactResolver
-    implements MavenArtifactResolver
+@Singleton
+@Named(Selector.MAVEN_3_1)
+public class Maven31ArtifactResolver
+    extends ComponentSupport
+    implements ArtifactResolverDelegate
 {
     private final RepositorySystem repositorySystem;
     
     private final List<RemoteRepository> aetherRepositories;
-    
-    private final RepositorySystemSession session;
 
-    Maven31ArtifactResolver( RepositorySystem repositorySystem, List<RemoteRepository> aetherRepositories,
-                                    RepositorySystemSession session )
+    @Inject
+    public Maven31ArtifactResolver( RepositorySystem repositorySystem,
+                                    List<RemoteRepository> aetherRepositories )
     {
-        this.repositorySystem = repositorySystem;
-        this.aetherRepositories = aetherRepositories;
-        this.session = session;
+        this.repositorySystem = Objects.requireNonNull( repositorySystem );
+        this.aetherRepositories = Objects.requireNonNull( aetherRepositories );
     }
 
     @Override
     public org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult resolveArtifact(
+            ProjectBuildingRequest buildingRequest,
             org.apache.maven.artifact.Artifact mavenArtifact ) throws ArtifactResolverException
     {
-        Artifact aetherArtifact = Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                org.apache.maven.artifact.Artifact.class, mavenArtifact );
-
-        return resolveArtifact( aetherArtifact );
+        Artifact aetherArtifact = RepositoryUtils.toArtifact(mavenArtifact);
+        return resolveArtifact( buildingRequest.getRepositorySession(), aetherArtifact );
     }
 
     @Override
-    // CHECKSTYLE_OFF: LineLength
-    public org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult resolveArtifact( ArtifactCoordinate coordinate )
-                                                                                        throws ArtifactResolverException
-    // CHECKSTYLE_ON: LineLength
+    public org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult resolveArtifact(
+        ProjectBuildingRequest buildingRequest,
+        ArtifactCoordinate coordinate ) throws ArtifactResolverException
     {
         Artifact aetherArtifact =
             new DefaultArtifact( coordinate.getGroupId(), coordinate.getArtifactId(), coordinate.getClassifier(),
                                  coordinate.getExtension(), coordinate.getVersion() );
 
-        return resolveArtifact( aetherArtifact );
+        return resolveArtifact( buildingRequest.getRepositorySession(), aetherArtifact );
     }
 
-    // CHECKSTYLE_OFF: LineLength
-    private org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult resolveArtifact( Artifact aetherArtifact )
-                                                                                         throws ArtifactResolverException
-    // CHECKSTYLE_ON: LineLength
+    private org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult resolveArtifact(
+        RepositorySystemSession session,
+        Artifact aetherArtifact ) throws ArtifactResolverException
     {
         try
         {
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/Maven31ArtifactResult.java b/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/Maven31ArtifactResult.java
index 7b56826..7a47f07 100644
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/Maven31ArtifactResult.java
+++ b/src/main/java/org/apache/maven/shared/transfer/artifact/resolve/internal/Maven31ArtifactResult.java
@@ -20,9 +20,7 @@ package org.apache.maven.shared.transfer.artifact.resolve.internal;
  */
 
 import org.apache.maven.RepositoryUtils;
-import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException;
 import org.eclipse.aether.resolution.ArtifactResult;
-import org.eclipse.aether.artifact.Artifact;
 
 /**
  * {@link org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult} wrapper for {@link ArtifactResult}
@@ -46,14 +44,6 @@ class Maven31ArtifactResult
     @Override
     public org.apache.maven.artifact.Artifact getArtifact()
     {
-        try
-        {
-            return Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                                                                        Artifact.class, artifactResult.getArtifact() );
-        }
-        catch ( ArtifactResolverException e )
-        {
-            throw new RuntimeException( e );
-        }
+        return RepositoryUtils.toArtifact(artifactResult.getArtifact());
     }
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/collection/internal/DefaultDependencyCollector.java b/src/main/java/org/apache/maven/shared/transfer/collection/internal/DefaultDependencyCollector.java
index e6ce50e..ebc0ccf 100644
--- a/src/main/java/org/apache/maven/shared/transfer/collection/internal/DefaultDependencyCollector.java
+++ b/src/main/java/org/apache/maven/shared/transfer/collection/internal/DefaultDependencyCollector.java
@@ -19,11 +19,13 @@ package org.apache.maven.shared.transfer.collection.internal;
  * under the License.
  */
 
-import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 
-import org.apache.maven.RepositoryUtils;
-import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
 import org.apache.maven.model.Dependency;
 import org.apache.maven.model.Model;
 import org.apache.maven.project.ProjectBuildingRequest;
@@ -31,165 +33,80 @@ import org.apache.maven.shared.transfer.collection.CollectResult;
 import org.apache.maven.shared.transfer.collection.DependencyCollectionException;
 import org.apache.maven.shared.transfer.collection.DependencyCollector;
 import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
-import org.codehaus.plexus.PlexusConstants;
-import org.codehaus.plexus.PlexusContainer;
-import org.codehaus.plexus.component.annotations.Component;
-import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
-import org.codehaus.plexus.context.Context;
-import org.codehaus.plexus.context.ContextException;
-import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
+import org.apache.maven.shared.transfer.internal.Delegator;
 
 /**
  * This DependencyCollector passes the request to the proper Maven 3.x implementation
  *
  * @author Robert Scholte
  */
-@Component( role = DependencyCollector.class, hint = "default" )
-class DefaultDependencyCollector implements DependencyCollector, Contextualizable
+@Singleton
+@Named
+class DefaultDependencyCollector
+    extends Delegator<DependencyCollectorDelegate>
+    implements DependencyCollector
 {
-    private PlexusContainer container;
+    private final DependencyCollectorDelegate delegate;
 
-    @Override
-    public CollectResult collectDependencies( ProjectBuildingRequest buildingRequest, Dependency root )
-            throws DependencyCollectionException
+    @Inject
+    public DefaultDependencyCollector(final Map<String, DependencyCollectorDelegate> delegates)
     {
-        validateParameters( buildingRequest, root );
-
-        try
-        {
-            return getMavenDependencyCollector( buildingRequest ).collectDependencies( root );
-        }
-        catch ( ComponentLookupException e )
-        {
-            throw new DependencyCollectionException( e.getMessage(), e );
-        }
+      super(delegates);
+      this.delegate = selectDelegate();
     }
 
     @Override
-    public CollectResult collectDependencies( ProjectBuildingRequest buildingRequest, DependableCoordinate root )
-            throws DependencyCollectionException
+    public CollectResult collectDependencies(final ProjectBuildingRequest buildingRequest, final Dependency root)
+        throws DependencyCollectionException
     {
-        validateParameters( buildingRequest, root );
-
-        try
-        {
-            return getMavenDependencyCollector( buildingRequest ).collectDependencies( root );
-        }
-        catch ( ComponentLookupException e )
-        {
-            throw new DependencyCollectionException( e.getMessage(), e );
-        }
+      validateParameters( buildingRequest, root );
+      return delegate.collectDependencies(buildingRequest, root);
     }
 
     @Override
-    public CollectResult collectDependencies( ProjectBuildingRequest buildingRequest, Model root )
-            throws DependencyCollectionException
+    public CollectResult collectDependencies(final ProjectBuildingRequest buildingRequest,
+                                             final DependableCoordinate root) throws DependencyCollectionException
     {
-        validateParameters( buildingRequest, root );
-
-        try
-        {
-            return getMavenDependencyCollector( buildingRequest ).collectDependencies( root );
-        }
-        catch ( ComponentLookupException e )
-        {
-            throw new DependencyCollectionException( e.getMessage(), e );
-        }
+      validateParameters( buildingRequest, root );
+      return delegate.collectDependencies(buildingRequest, root);
     }
 
-  private void validateParameters( ProjectBuildingRequest buildingRequest, DependableCoordinate root )
-  {
-    validateBuildingRequestAndRoot( buildingRequest, root );
-  }
-
-  private void validateParameters( ProjectBuildingRequest buildingRequest, Dependency root )
-  {
-    validateBuildingRequestAndRoot( buildingRequest, root );
-  }
-
-  private void validateParameters( ProjectBuildingRequest buildingRequest, Model root )
-  {
-    validateBuildingRequestAndRoot( buildingRequest, root );
-  }
-
-  private void validateBuildingRequestAndRoot( ProjectBuildingRequest buildingRequest, Object root )
-  {
-    validateBuildingRequest( buildingRequest );
-    validateRoot( root );
-  }
-
-  private void validateBuildingRequest( ProjectBuildingRequest buildingRequest )
-  {
-    Objects.requireNonNull( buildingRequest, "The parameter buildingRequest is not allowed to be null." );
-  }
-
-  private void validateRoot( Object root )
-  {
-    Objects.requireNonNull( root, "The parameter root is not allowed to be null." );
-  }
-
-  /**
-   * @return true if the current Maven version is Maven 3.1.
-   */
-  private boolean isMaven31()
-  {
-      try
-      {
-          // Maven 3.1 specific
-          Thread.currentThread().getContextClassLoader().loadClass( "org.eclipse.aether.artifact.Artifact" );
-          return true;
-      }
-      catch ( ClassNotFoundException e )
-      {
-          return false;
-      }
-  }
-
-    /**
-     * Injects the Plexus content.
-     *
-     * @param context Plexus context to inject.
-     * @throws ContextException if the PlexusContainer could not be located.
-     */
-    public void contextualize( Context context ) throws ContextException
+    @Override
+    public CollectResult collectDependencies(final ProjectBuildingRequest buildingRequest, final Model root)
+        throws DependencyCollectionException
     {
-        container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
+      validateParameters( buildingRequest, root );
+      return delegate.collectDependencies(buildingRequest, root);
     }
 
-    private MavenDependencyCollector getMavenDependencyCollector( ProjectBuildingRequest buildingRequest )
-            throws ComponentLookupException, DependencyCollectionException
+    private void validateParameters( ProjectBuildingRequest buildingRequest, DependableCoordinate root )
     {
-        ArtifactHandlerManager artifactHandlerManager = container.lookup( ArtifactHandlerManager.class );
-
-        if ( isMaven31() )
-        {
-            org.eclipse.aether.RepositorySystem m31RepositorySystem = container.lookup(
-                    org.eclipse.aether.RepositorySystem.class );
-
-            org.eclipse.aether.RepositorySystemSession session = Invoker.invoke( buildingRequest,
-                    "getRepositorySession" );
-
-            List<org.eclipse.aether.repository.RemoteRepository> aetherRepositories = Invoker.invoke(
-                    RepositoryUtils.class, "toRepos", List.class, buildingRequest.getRemoteRepositories() );
-
-            return new Maven31DependencyCollector( m31RepositorySystem, artifactHandlerManager, session,
-                    aetherRepositories );
-        }
-        else
-        {
-            org.sonatype.aether.RepositorySystem m30RepositorySystem = container.lookup(
-                    org.sonatype.aether.RepositorySystem.class );
+      validateBuildingRequestAndRoot( buildingRequest, root );
+    }
 
-            org.sonatype.aether.RepositorySystemSession session = Invoker.invoke( buildingRequest,
-                    "getRepositorySession" );
+    private void validateParameters( ProjectBuildingRequest buildingRequest, Dependency root )
+    {
+      validateBuildingRequestAndRoot( buildingRequest, root );
+    }
 
-            List<org.sonatype.aether.repository.RemoteRepository> aetherRepositories = Invoker.invoke(
-                    RepositoryUtils.class, "toRepos", List.class, buildingRequest.getRemoteRepositories() );
+    private void validateParameters( ProjectBuildingRequest buildingRequest, Model root )
+    {
+      validateBuildingRequestAndRoot( buildingRequest, root );
+    }
 
-            return new Maven30DependencyCollector( m30RepositorySystem, artifactHandlerManager, session,
-                    aetherRepositories );
-        }
+    private void validateBuildingRequestAndRoot( ProjectBuildingRequest buildingRequest, Object root )
+    {
+      validateBuildingRequest( buildingRequest );
+      validateRoot( root );
+    }
 
+    private void validateBuildingRequest( ProjectBuildingRequest buildingRequest )
+    {
+      Objects.requireNonNull( buildingRequest, "The parameter buildingRequest is not allowed to be null." );
     }
 
+    private void validateRoot( Object root )
+    {
+      Objects.requireNonNull( root, "The parameter root is not allowed to be null." );
+    }
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/collection/internal/MavenDependencyCollector.java b/src/main/java/org/apache/maven/shared/transfer/collection/internal/DependencyCollectorDelegate.java
similarity index 61%
rename from src/main/java/org/apache/maven/shared/transfer/collection/internal/MavenDependencyCollector.java
rename to src/main/java/org/apache/maven/shared/transfer/collection/internal/DependencyCollectorDelegate.java
index fc7edb8..d159da6 100644
--- a/src/main/java/org/apache/maven/shared/transfer/collection/internal/MavenDependencyCollector.java
+++ b/src/main/java/org/apache/maven/shared/transfer/collection/internal/DependencyCollectorDelegate.java
@@ -19,25 +19,11 @@ package org.apache.maven.shared.transfer.collection.internal;
  * under the License.
  */
 
-import org.apache.maven.model.Dependency;
-import org.apache.maven.model.Model;
-import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
-import org.apache.maven.shared.transfer.collection.CollectResult;
-import org.apache.maven.shared.transfer.collection.DependencyCollectionException;
+import org.apache.maven.shared.transfer.collection.DependencyCollector;
 
 /**
- * @author Robert Scholte
+ *
  */
-interface MavenDependencyCollector
+public interface DependencyCollectorDelegate extends DependencyCollector
 {
-
-  CollectResult collectDependencies( Dependency root )
-      throws DependencyCollectionException;
-
-  CollectResult collectDependencies( DependableCoordinate root )
-      throws DependencyCollectionException;
-
-  CollectResult collectDependencies( Model root )
-      throws DependencyCollectionException;
-
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/collection/internal/Invoker.java b/src/main/java/org/apache/maven/shared/transfer/collection/internal/Invoker.java
deleted file mode 100644
index 642c4b6..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/collection/internal/Invoker.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package org.apache.maven.shared.transfer.collection.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.lang.reflect.InvocationTargetException;
-
-import org.apache.maven.shared.transfer.collection.DependencyCollectionException;
-
-/**
- * Invokes method on objects using reflection.
- */
-final class Invoker
-{
-    private Invoker()
-    {
-        // do not instantiate
-    }
-
-    public static <T> T invoke( Object object, String method )
-        throws DependencyCollectionException
-    {
-        try
-        {
-            @SuppressWarnings( "unchecked" )
-            T invoke = (T) object.getClass().getMethod( method ).invoke( object );
-            return invoke;
-        }
-        catch ( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
-        {
-            throw new DependencyCollectionException( e.getMessage(), e );
-        }
-    }
-
-    public static <T> T invoke( Class<?> objectClazz, String staticMethod, Class<?> argClazz, Object arg )
-                    throws DependencyCollectionException
-    {
-        try
-        {
-            @SuppressWarnings( "unchecked" )
-            T invoke = (T) objectClazz.getMethod( staticMethod, argClazz ).invoke( null, arg );
-            return invoke;
-        }
-        catch ( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
-        {
-            throw new DependencyCollectionException( e.getMessage(), e );
-        }
-    }
-    
-    /**
-     * <strong>Note:</strong> Ensure that argClasses and args have the same number of elements 
-     * 
-     * @param objectClazz the class of the static method
-     * @param staticMethod the static method to call
-     * @param argClasses the classes of the argument, used to select the right static method
-     * @param args the actual arguments to be passed
-     * @return the result of the method invocation
-     * @throws DependencyCollectionException if any checked exception occurs
-     */
-    public static <T> T invoke( Class<?> objectClazz, String staticMethod, Class<?>[] argClasses, Object[] args )
-                    throws DependencyCollectionException
-    {
-        if ( args.length != argClasses.length )
-        {
-            throw new IllegalArgumentException( "The number of elements in argClasses and args are not the same." );
-        }
-
-        try
-        {
-            @SuppressWarnings( "unchecked" )
-            T invoke = (T) objectClazz.getMethod( staticMethod, argClasses ).invoke( null, args );
-            return invoke;
-        }
-        catch ( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
-        {
-            throw new DependencyCollectionException( e.getMessage(), e );
-        }
-    }
-
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven30ArtifactRepositoryAdapter.java b/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven30ArtifactRepositoryAdapter.java
deleted file mode 100644
index 40d9143..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven30ArtifactRepositoryAdapter.java
+++ /dev/null
@@ -1,265 +0,0 @@
-package org.apache.maven.shared.transfer.collection.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.List;
-
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.metadata.ArtifactMetadata;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
-import org.apache.maven.artifact.repository.Authentication;
-import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
-import org.apache.maven.repository.Proxy;
-import org.sonatype.aether.repository.RemoteRepository;
-import org.sonatype.aether.repository.RepositoryPolicy;
-
-/**
- * ArtifactRepository wrapper around {@link RemoteRepository}
- * 
- * @author Robert Scholte
- *
- */
-class Maven30ArtifactRepositoryAdapter implements ArtifactRepository
-{
-    private static final String LS = System.lineSeparator();
-    private RemoteRepository remoteRepository;
-
-    /**
-     * @param remoteRepository {@link RemoteRepository}
-     */
-    Maven30ArtifactRepositoryAdapter( RemoteRepository remoteRepository )
-    {
-        this.remoteRepository = remoteRepository;
-    }
-
-    @Override
-    public String pathOf( Artifact artifact )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String pathOfRemoteRepositoryMetadata( ArtifactMetadata artifactMetadata )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getUrl()
-    {
-        return remoteRepository.getUrl();
-    }
-
-    @Override
-    public void setUrl( String url )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getBasedir()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getProtocol()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getId()
-    {
-        return remoteRepository.getId();
-    }
-
-    @Override
-    public void setId( String id )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ArtifactRepositoryPolicy getSnapshots()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setSnapshotUpdatePolicy( ArtifactRepositoryPolicy policy )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ArtifactRepositoryPolicy getReleases()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setReleaseUpdatePolicy( ArtifactRepositoryPolicy policy )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ArtifactRepositoryLayout getLayout()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setLayout( ArtifactRepositoryLayout layout )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getKey()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isUniqueVersion()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isBlacklisted()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setBlacklisted( boolean blackListed )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Artifact find( Artifact artifact )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public List<String> findVersions( Artifact artifact )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isProjectAware()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setAuthentication( Authentication authentication )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Authentication getAuthentication()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setProxy( Proxy proxy )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Proxy getProxy()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String toString()
-    {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append( "       id: " ).append( getId() ).append( LS );
-        sb.append( "      url: " ).append( getUrl() ).append( LS );
-        sb.append( "   layout: " ).append( "default" ).append( LS );
-
-        RepositoryPolicy snapshotPolicy = remoteRepository.getPolicy( true ); 
-        sb.append( "snapshots: [enabled => " ).append( snapshotPolicy.isEnabled() );
-        sb.append( ", update => " ).append( snapshotPolicy.getUpdatePolicy() ).append( "]" ).append( LS );
-
-        RepositoryPolicy releasePolicy = remoteRepository.getPolicy( false ); 
-        sb.append( " releases: [enabled => " ).append( releasePolicy.isEnabled() );
-        sb.append( ", update => " ).append( releasePolicy.getUpdatePolicy() ).append( "]" ).append( LS );
-
-        return sb.toString();
-    }
-    
-    @Override
-    public int hashCode()
-    {
-        return remoteRepository.hashCode();
-    }
-
-    @Override
-    public boolean equals( Object obj )
-    {
-        if ( this == obj )
-        {
-            return true;
-        }
-        if ( obj == null )
-        {
-            return false;
-        }
-        if ( getClass() != obj.getClass() )
-        {
-            return false;
-        }
-        
-        Maven30ArtifactRepositoryAdapter other = (Maven30ArtifactRepositoryAdapter) obj;
-        if ( remoteRepository == null )
-        {
-            if ( other.remoteRepository != null )
-            {
-                return false;
-            }
-        }
-        else if ( !remoteRepository.equals( other.remoteRepository ) )
-        {
-            return false;
-        }
-        return true;
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven30CollectResult.java b/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven30CollectResult.java
deleted file mode 100644
index c5e6c90..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven30CollectResult.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package org.apache.maven.shared.transfer.collection.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.List;
-
-import org.apache.maven.shared.transfer.collection.CollectResult;
-import org.apache.maven.shared.transfer.graph.DependencyNode;
-
-
-/**
- * CollectResult wrapper around {@link CollectResult}
- * 
- * @author Pim Moerenhout
- *
- */
-class Maven30CollectResult implements CollectResult
-{
-    private final org.sonatype.aether.collection.CollectResult collectResult;
-
-    /**
-     * @param collectResult {@link CollectResult}
-     */
-    Maven30CollectResult( org.sonatype.aether.collection.CollectResult collectResult )
-    {
-        this.collectResult = collectResult;
-    }
-
-    @Override
-    public List<Exception> getExceptions()
-    {
-        return collectResult.getExceptions();
-    }
-
-    /**
-     * Gets the root node of the dependency graph.
-     *
-     * @return The root node of the dependency graph or {@code null} if none.
-     */
-    @Override
-    public DependencyNode getRoot()
-    {
-        return new Maven30DependencyNodeAdapter( collectResult.getRoot() );
-    }
-
-    @Override
-    public String toString()
-    {
-        return String.valueOf( getRoot() );
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven30DependencyCollector.java b/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven30DependencyCollector.java
deleted file mode 100644
index 108db21..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven30DependencyCollector.java
+++ /dev/null
@@ -1,167 +0,0 @@
-package org.apache.maven.shared.transfer.collection.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.maven.RepositoryUtils;
-import org.apache.maven.artifact.handler.ArtifactHandler;
-import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
-import org.apache.maven.model.Model;
-import org.apache.maven.shared.transfer.collection.CollectResult;
-import org.apache.maven.shared.transfer.collection.DependencyCollectionException;
-import org.apache.maven.shared.transfer.collection.DependencyCollector;
-import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
-import org.sonatype.aether.RepositorySystem;
-import org.sonatype.aether.RepositorySystemSession;
-import org.sonatype.aether.artifact.Artifact;
-import org.sonatype.aether.artifact.ArtifactTypeRegistry;
-import org.sonatype.aether.collection.CollectRequest;
-import org.sonatype.aether.graph.Dependency;
-import org.sonatype.aether.repository.RemoteRepository;
-import org.sonatype.aether.util.artifact.DefaultArtifact;
-
-/**
- * Maven 3.0 implementation of the {@link DependencyCollector}
- * 
- * @author Robert Scholte
- *
- */
-class Maven30DependencyCollector
-    implements MavenDependencyCollector
-{
-    private final RepositorySystem repositorySystem;
-
-    private final ArtifactHandlerManager artifactHandlerManager;
-
-    private final RepositorySystemSession session;
-    
-    private final List<RemoteRepository> aetherRepositories;
-    
-    Maven30DependencyCollector( RepositorySystem repositorySystem, ArtifactHandlerManager artifactHandlerManager,
-                                RepositorySystemSession session, List<RemoteRepository> aetherRepositories )
-    {
-        super();
-        this.repositorySystem = repositorySystem;
-        this.artifactHandlerManager = artifactHandlerManager;
-        this.session = session;
-        this.aetherRepositories = aetherRepositories;
-    }
-
-    @Override
-    public CollectResult collectDependencies( org.apache.maven.model.Dependency root )
-        throws DependencyCollectionException
-    {
-        ArtifactTypeRegistry typeRegistry = Invoker
-            .invoke( RepositoryUtils.class, "newArtifactTypeRegistry",
-                                               ArtifactHandlerManager.class, artifactHandlerManager );
-
-        CollectRequest request = new CollectRequest();
-        request.setRoot( toDependency( root, typeRegistry ) );
-
-        return collectDependencies( request );
-    }
-
-    @Override
-    public CollectResult collectDependencies( DependableCoordinate root )
-        throws DependencyCollectionException
-    {
-        ArtifactHandler artifactHandler = artifactHandlerManager.getArtifactHandler( root.getType() );
-
-        String extension = artifactHandler != null ? artifactHandler.getExtension() : null;
-
-        Artifact aetherArtifact = new DefaultArtifact( root.getGroupId(), root.getArtifactId(), root.getClassifier(),
-                                                       extension, root.getVersion() );
-
-        CollectRequest request = new CollectRequest();
-        request.setRoot( new Dependency( aetherArtifact, null ) );
-
-        return collectDependencies( request );
-    }
-
-    @Override
-    public CollectResult collectDependencies( Model root )
-        throws DependencyCollectionException
-    {
-        // Are there examples where packaging and type are NOT in sync
-        ArtifactHandler artifactHandler = artifactHandlerManager.getArtifactHandler( root.getPackaging() );
-
-        String extension = artifactHandler != null ? artifactHandler.getExtension() : null;
-
-        Artifact aetherArtifact =
-            new DefaultArtifact( root.getGroupId(), root.getArtifactId(), extension, root.getVersion() );
-
-        CollectRequest request = new CollectRequest();
-        request.setRoot( new Dependency( aetherArtifact, null ) );
-
-        ArtifactTypeRegistry typeRegistry = Invoker
-            .invoke( RepositoryUtils.class, "newArtifactTypeRegistry",
-                                               ArtifactHandlerManager.class, artifactHandlerManager );
-
-        List<Dependency> aetherDependencies = new ArrayList<>( root.getDependencies().size() );
-        for ( org.apache.maven.model.Dependency mavenDependency : root.getDependencies() )
-        {
-            aetherDependencies.add( toDependency( mavenDependency, typeRegistry ) );
-        }
-        request.setDependencies( aetherDependencies );
-
-        if ( root.getDependencyManagement() != null )
-        {
-            List<Dependency> aetherManagerDependencies = new ArrayList<>(
-                    root.getDependencyManagement().getDependencies().size() );
-
-            for ( org.apache.maven.model.Dependency mavenDependency : root.getDependencyManagement().getDependencies() )
-            {
-                aetherManagerDependencies.add( toDependency( mavenDependency, typeRegistry ) );
-            }
-
-            request.setManagedDependencies( aetherManagerDependencies );
-        }
-
-        return collectDependencies( request );
-    }
-
-    private CollectResult collectDependencies( CollectRequest request )
-        throws DependencyCollectionException
-    {
-        request.setRepositories( aetherRepositories );
-
-        try
-        {
-            return new Maven30CollectResult( repositorySystem.collectDependencies( session, request ) );
-        }
-        catch ( org.sonatype.aether.collection.DependencyCollectionException e )
-        {
-            throw new DependencyCollectionException( e.getMessage(), e );
-        }
-    }
-
-    private static Dependency toDependency( org.apache.maven.model.Dependency mavenDependency,
-                                            ArtifactTypeRegistry typeRegistry )
-        throws DependencyCollectionException
-    {
-        Class<?>[] argClasses = new Class<?>[] { org.apache.maven.model.Dependency.class, ArtifactTypeRegistry.class };
-
-        Object[] args = new Object[] { mavenDependency, typeRegistry };
-
-        return Invoker.invoke( RepositoryUtils.class, "toDependency", argClasses, args );
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven30DependencyNodeAdapter.java b/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven30DependencyNodeAdapter.java
deleted file mode 100644
index fa96b35..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven30DependencyNodeAdapter.java
+++ /dev/null
@@ -1,163 +0,0 @@
-package org.apache.maven.shared.transfer.collection.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.maven.RepositoryUtils;
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.shared.transfer.collection.DependencyCollectionException;
-import org.apache.maven.shared.transfer.graph.DependencyNode;
-import org.apache.maven.shared.transfer.graph.DependencyVisitor;
-import org.sonatype.aether.repository.RemoteRepository;
-
-/**
- * DependencyCollectorNode wrapper around {@link org.sonatype.aether.graph.DependencyNode}
- * 
- * @author Pim Moerenhout
- *
- */
-class Maven30DependencyNodeAdapter implements DependencyNode
-{
-
-    private org.sonatype.aether.graph.DependencyNode dependencyNode;
-
-    /**
-     * @param dependencyNode {@link org.sonatype.aether.graph.DependencyNode}
-     */
-    Maven30DependencyNodeAdapter( org.sonatype.aether.graph.DependencyNode dependencyNode )
-    {
-        this.dependencyNode = dependencyNode;
-    }
-
-    @Override
-    public Artifact getArtifact()
-    {
-        return getArtifact( dependencyNode.getDependency().getArtifact() );
-    }
-
-    @Override
-    public List<DependencyNode> getChildren()
-    {
-        List<org.sonatype.aether.graph.DependencyNode> aetherChildren = dependencyNode.getChildren();
-        List<DependencyNode> children = new ArrayList<>( aetherChildren.size() );
-        for ( org.sonatype.aether.graph.DependencyNode aetherChild : aetherChildren )
-        {
-            children.add( new Maven30DependencyNodeAdapter( aetherChild ) );
-        }
-        return children;
-    }
-
-    @Override
-    public List<ArtifactRepository> getRemoteRepositories()
-    {
-        List<RemoteRepository> aetherRepositories = dependencyNode.getRepositories();
-        List<ArtifactRepository> mavenRepositories = new ArrayList<>( aetherRepositories.size() );
-
-        for ( RemoteRepository aetherRepository : aetherRepositories )
-        {
-            mavenRepositories.add( new Maven30ArtifactRepositoryAdapter( aetherRepository ) );
-        }
-
-        return mavenRepositories;
-    }
-
-    @Override
-    public Boolean getOptional()
-    {
-        return dependencyNode.getDependency().isOptional();
-    }
-
-    @Override
-    public String getScope()
-    {
-        return dependencyNode.getDependency().getScope();
-    }
-
-    @Override
-    public boolean accept( DependencyVisitor visitor )
-    {
-        if ( visitor.visitEnter( this ) )
-        {
-            for ( org.sonatype.aether.graph.DependencyNode aetherNode : dependencyNode.getChildren() )
-            {
-                DependencyNode child = new Maven30DependencyNodeAdapter( aetherNode );
-                if ( !child.accept( visitor ) )
-                {
-                    break;
-                }
-            }
-        }
-
-        return visitor.visitLeave( this );
-    }
-
-    @Override
-    public int hashCode()
-    {
-        return dependencyNode.hashCode();
-    }
-
-    @Override
-    public boolean equals( Object obj )
-    {
-        if ( this == obj )
-        {
-            return true;
-        }
-        if ( obj == null )
-        {
-            return false;
-        }
-        if ( getClass() != obj.getClass() )
-        {
-            return false;
-        }
-
-        Maven30DependencyNodeAdapter other = (Maven30DependencyNodeAdapter) obj;
-        if ( dependencyNode == null )
-        {
-            if ( other.dependencyNode != null )
-            {
-                return false;
-            }
-        }
-        else if ( !dependencyNode.equals( other.dependencyNode ) )
-        {
-            return false;
-        }
-        return true;
-    }
-
-    private Artifact getArtifact( org.sonatype.aether.artifact.Artifact aetherArtifact )
-    {
-        try
-        {
-            return Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                org.sonatype.aether.artifact.Artifact.class, aetherArtifact );
-        }
-        catch ( DependencyCollectionException e )
-        {
-            throw new RuntimeException( e );
-        }
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven31ArtifactRepositoryAdapter.java b/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven31ArtifactRepositoryAdapter.java
index d53a452..953ae7a 100644
--- a/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven31ArtifactRepositoryAdapter.java
+++ b/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven31ArtifactRepositoryAdapter.java
@@ -207,6 +207,18 @@ class Maven31ArtifactRepositoryAdapter implements ArtifactRepository
     }
 
     @Override
+    public List<ArtifactRepository> getMirroredRepositories()
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setMirroredRepositories(final List<ArtifactRepository> mirroredRepositories)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public String toString()
     {
         StringBuilder sb = new StringBuilder();
diff --git a/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven31DependencyCollector.java b/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven31DependencyCollector.java
index 43846ab..b77ce2b 100644
--- a/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven31DependencyCollector.java
+++ b/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven31DependencyCollector.java
@@ -22,14 +22,21 @@ package org.apache.maven.shared.transfer.collection.internal;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
 import org.apache.maven.RepositoryUtils;
 import org.apache.maven.artifact.handler.ArtifactHandler;
 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
 import org.apache.maven.model.Model;
+import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
 import org.apache.maven.shared.transfer.collection.CollectResult;
 import org.apache.maven.shared.transfer.collection.DependencyCollectionException;
 import org.apache.maven.shared.transfer.collection.DependencyCollector;
+import org.apache.maven.shared.transfer.internal.ComponentSupport;
+import org.apache.maven.shared.transfer.internal.Selector;
 import org.eclipse.aether.RepositorySystem;
 import org.eclipse.aether.RepositorySystemSession;
 import org.eclipse.aether.artifact.Artifact;
@@ -45,43 +52,42 @@ import org.eclipse.aether.repository.RemoteRepository;
  * @author Robert Scholte
  *
  */
-class Maven31DependencyCollector
-    implements MavenDependencyCollector
+@Singleton
+@Named(Selector.MAVEN_3_1)
+public class Maven31DependencyCollector
+    extends ComponentSupport
+    implements DependencyCollectorDelegate
 {
     private final RepositorySystem repositorySystem;
 
     private final ArtifactHandlerManager artifactHandlerManager;
     
-    private final RepositorySystemSession session;
-    
     private final List<RemoteRepository> aetherRepositories;
-    
-    Maven31DependencyCollector( RepositorySystem repositorySystem, ArtifactHandlerManager artifactHandlerManager,
-                                RepositorySystemSession session, List<RemoteRepository> aetherRepositories )
+
+    @Inject
+    public Maven31DependencyCollector( final RepositorySystem repositorySystem,
+                                       final ArtifactHandlerManager artifactHandlerManager,
+                                       final List<RemoteRepository> aetherRepositories )
     {
-        super();
         this.repositorySystem = repositorySystem;
         this.artifactHandlerManager = artifactHandlerManager;
-        this.session = session;
         this.aetherRepositories = aetherRepositories;
     }
 
     @Override
-    public CollectResult collectDependencies( org.apache.maven.model.Dependency root )
+    public CollectResult collectDependencies( ProjectBuildingRequest buildingRequest, org.apache.maven.model.Dependency root )
         throws DependencyCollectionException
     {
-        ArtifactTypeRegistry typeRegistry = Invoker
-            .invoke( RepositoryUtils.class, "newArtifactTypeRegistry",
-                                               ArtifactHandlerManager.class, artifactHandlerManager );
+        ArtifactTypeRegistry typeRegistry = RepositoryUtils.newArtifactTypeRegistry(artifactHandlerManager);
 
         CollectRequest request = new CollectRequest();
         request.setRoot( toDependency( root, typeRegistry ) );
 
-        return collectDependencies( request );
+        return collectDependencies( buildingRequest.getRepositorySession(), request );
     }
 
     @Override
-    public CollectResult collectDependencies( DependableCoordinate root )
+    public CollectResult collectDependencies( ProjectBuildingRequest buildingRequest, DependableCoordinate root )
         throws DependencyCollectionException
     {
         ArtifactHandler artifactHandler = artifactHandlerManager.getArtifactHandler( root.getType() );
@@ -94,11 +100,11 @@ class Maven31DependencyCollector
         CollectRequest request = new CollectRequest();
         request.setRoot( new Dependency( aetherArtifact, null ) );
 
-        return collectDependencies( request );
+        return collectDependencies( buildingRequest.getRepositorySession(), request );
     }
 
     @Override
-    public CollectResult collectDependencies( Model root )
+    public CollectResult collectDependencies( ProjectBuildingRequest buildingRequest, Model root )
         throws DependencyCollectionException
     {
         // Are there examples where packaging and type are NOT in sync
@@ -112,9 +118,7 @@ class Maven31DependencyCollector
         CollectRequest request = new CollectRequest();
         request.setRoot( new Dependency( aetherArtifact, null ) );
 
-        ArtifactTypeRegistry typeRegistry = Invoker
-            .invoke( RepositoryUtils.class, "newArtifactTypeRegistry",
-                                               ArtifactHandlerManager.class, artifactHandlerManager );
+        ArtifactTypeRegistry typeRegistry = RepositoryUtils.newArtifactTypeRegistry(artifactHandlerManager);
 
         List<Dependency> aetherDependencies = new ArrayList<>( root.getDependencies().size() );
         for ( org.apache.maven.model.Dependency mavenDependency : root.getDependencies() )
@@ -136,10 +140,10 @@ class Maven31DependencyCollector
             request.setManagedDependencies( aetherManagerDependencies );
         }
 
-        return collectDependencies( request );
+        return collectDependencies( buildingRequest.getRepositorySession(), request );
     }
 
-    private CollectResult collectDependencies( CollectRequest request )
+    private CollectResult collectDependencies( RepositorySystemSession session, CollectRequest request )
         throws DependencyCollectionException
     {
         request.setRepositories( aetherRepositories );
@@ -155,14 +159,7 @@ class Maven31DependencyCollector
     }
 
     private static Dependency toDependency( org.apache.maven.model.Dependency root, ArtifactTypeRegistry typeRegistry )
-                    throws DependencyCollectionException
     {
-        Class<?>[] argClasses = new Class<?>[] { org.apache.maven.model.Dependency.class, ArtifactTypeRegistry.class };
-
-        Object[] args = new Object[] { root, typeRegistry };
-
-        return Invoker
-            .invoke( RepositoryUtils.class, "toDependency", argClasses, args );
+        return RepositoryUtils.toDependency(root, typeRegistry);
     }
-
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven31DependencyNodeAdapter.java b/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven31DependencyNodeAdapter.java
index eae1542..449fc16 100644
--- a/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven31DependencyNodeAdapter.java
+++ b/src/main/java/org/apache/maven/shared/transfer/collection/internal/Maven31DependencyNodeAdapter.java
@@ -25,7 +25,6 @@ import java.util.List;
 import org.apache.maven.RepositoryUtils;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.shared.transfer.collection.DependencyCollectionException;
 import org.apache.maven.shared.transfer.graph.DependencyNode;
 import org.apache.maven.shared.transfer.graph.DependencyVisitor;
 import org.eclipse.aether.repository.RemoteRepository;
@@ -150,14 +149,6 @@ class Maven31DependencyNodeAdapter implements DependencyNode
 
     private Artifact getArtifact( org.eclipse.aether.artifact.Artifact aetherArtifact )
     {
-        try
-        {
-            return Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                org.eclipse.aether.artifact.Artifact.class, aetherArtifact );
-        }
-        catch ( DependencyCollectionException e )
-        {
-            throw new RuntimeException( e );
-        }
+        return RepositoryUtils.toArtifact(aetherArtifact);
     }
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/DefaultDependencyCollector.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/DefaultDependencyCollector.java
index fb1e498..45d03c5 100644
--- a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/DefaultDependencyCollector.java
+++ b/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/DefaultDependencyCollector.java
@@ -20,9 +20,12 @@ package org.apache.maven.shared.transfer.dependencies.collect.internal;
  */
 
 import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
 
-import org.apache.maven.RepositoryUtils;
-import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
 import org.apache.maven.model.Dependency;
 import org.apache.maven.model.Model;
 import org.apache.maven.project.ProjectBuildingRequest;
@@ -30,70 +33,50 @@ import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
 import org.apache.maven.shared.transfer.dependencies.collect.CollectorResult;
 import org.apache.maven.shared.transfer.dependencies.collect.DependencyCollector;
 import org.apache.maven.shared.transfer.dependencies.collect.DependencyCollectorException;
-import org.codehaus.plexus.PlexusConstants;
-import org.codehaus.plexus.PlexusContainer;
-import org.codehaus.plexus.component.annotations.Component;
-import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
-import org.codehaus.plexus.context.Context;
-import org.codehaus.plexus.context.ContextException;
-import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
+import org.apache.maven.shared.transfer.internal.Delegator;
 
 /**
  * This DependencyCollector passes the request to the proper Maven 3.x implementation
  *
  * @author Robert Scholte
  */
-@Component( role = DependencyCollector.class, hint = "default" )
-class DefaultDependencyCollector implements DependencyCollector, Contextualizable
+@Singleton
+@Named
+public class DefaultDependencyCollector
+    extends Delegator<DependencyCollectorDelegate>
+    implements DependencyCollector
 {
-    private PlexusContainer container;
+    private final DependencyCollectorDelegate delegate;
+
+    @Inject
+    public DefaultDependencyCollector(final Map<String, DependencyCollectorDelegate> delegates)
+    {
+        super(delegates);
+        this.delegate = selectDelegate();
+    }
 
     @Override
-    public CollectorResult collectDependencies( ProjectBuildingRequest buildingRequest, Dependency root )
-            throws DependencyCollectorException
+    public CollectorResult collectDependencies(final ProjectBuildingRequest buildingRequest,
+                                               final Dependency root) throws DependencyCollectorException
     {
         validateParameters( buildingRequest, root );
-
-        try
-        {
-            return getMavenDependencyCollector( buildingRequest ).collectDependencies( root );
-        }
-        catch ( ComponentLookupException e )
-        {
-            throw new DependencyCollectorException( e.getMessage(), e );
-        }
+        return delegate.collectDependencies(buildingRequest, root);
     }
 
     @Override
-    public CollectorResult collectDependencies( ProjectBuildingRequest buildingRequest, DependableCoordinate root )
-            throws DependencyCollectorException
+    public CollectorResult collectDependencies(final ProjectBuildingRequest buildingRequest,
+                                               final DependableCoordinate root) throws DependencyCollectorException
     {
         validateParameters( buildingRequest, root );
-
-        try
-        {
-            return getMavenDependencyCollector( buildingRequest ).collectDependencies( root );
-        }
-        catch ( ComponentLookupException e )
-        {
-            throw new DependencyCollectorException( e.getMessage(), e );
-        }
+        return delegate.collectDependencies(buildingRequest, root);
     }
 
     @Override
-    public CollectorResult collectDependencies( ProjectBuildingRequest buildingRequest, Model root )
-            throws DependencyCollectorException
+    public CollectorResult collectDependencies(final ProjectBuildingRequest buildingRequest, final Model root)
+        throws DependencyCollectorException
     {
         validateParameters( buildingRequest, root );
-
-        try
-        {
-            return getMavenDependencyCollector( buildingRequest ).collectDependencies( root );
-        }
-        catch ( ComponentLookupException e )
-        {
-            throw new DependencyCollectorException( e.getMessage(), e );
-        }
+        return delegate.collectDependencies(buildingRequest, root);
     }
 
     private void validateParameters( ProjectBuildingRequest buildingRequest, DependableCoordinate root )
@@ -129,70 +112,4 @@ class DefaultDependencyCollector implements DependencyCollector, Contextualizabl
             throw new IllegalArgumentException( "The parameter root is not allowed to be null." );
         }
     }
-
-    /**
-     * @return true if the current Maven version is Maven 3.1.
-     */
-    private boolean isMaven31()
-    {
-        try
-        {
-            // Maven 3.1 specific
-            Thread.currentThread().getContextClassLoader().loadClass( "org.eclipse.aether.artifact.Artifact" );
-            return true;
-        }
-        catch ( ClassNotFoundException e )
-        {
-            return false;
-        }
-    }
-
-    /**
-     * Injects the Plexus content.
-     *
-     * @param context Plexus context to inject.
-     * @throws ContextException if the PlexusContainer could not be located.
-     */
-    public void contextualize( Context context ) throws ContextException
-    {
-        container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
-    }
-
-    private MavenDependencyCollector getMavenDependencyCollector( ProjectBuildingRequest buildingRequest )
-            throws ComponentLookupException, DependencyCollectorException
-    {
-        ArtifactHandlerManager artifactHandlerManager = container.lookup( ArtifactHandlerManager.class );
-
-        if ( isMaven31() )
-        {
-            org.eclipse.aether.RepositorySystem m31RepositorySystem = container.lookup(
-                    org.eclipse.aether.RepositorySystem.class );
-
-            org.eclipse.aether.RepositorySystemSession session = Invoker.invoke( buildingRequest,
-                    "getRepositorySession" );
-
-            List<org.eclipse.aether.repository.RemoteRepository> aetherRepositories = Invoker.invoke(
-                    RepositoryUtils.class, "toRepos", List.class, buildingRequest.getRemoteRepositories() );
-
-            return new Maven31DependencyCollector( m31RepositorySystem, artifactHandlerManager, session,
-                    aetherRepositories );
-        }
-        else
-        {
-
-            org.sonatype.aether.RepositorySystem m30RepositorySystem = container.lookup(
-                    org.sonatype.aether.RepositorySystem.class );
-
-            org.sonatype.aether.RepositorySystemSession session = Invoker.invoke( buildingRequest,
-                    "getRepositorySession" );
-
-            List<org.sonatype.aether.repository.RemoteRepository> aetherRepositories = Invoker.invoke(
-                    RepositoryUtils.class, "toRepos", List.class, buildingRequest.getRemoteRepositories() );
-
-            return new Maven30DependencyCollector( m30RepositorySystem, artifactHandlerManager, session,
-                    aetherRepositories );
-        }
-
-    }
-
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/MavenDependencyCollector.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/DependencyCollectorDelegate.java
similarity index 59%
rename from src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/MavenDependencyCollector.java
rename to src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/DependencyCollectorDelegate.java
index ce647f5..fdd6b39 100644
--- a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/MavenDependencyCollector.java
+++ b/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/DependencyCollectorDelegate.java
@@ -19,26 +19,11 @@ package org.apache.maven.shared.transfer.dependencies.collect.internal;
  * under the License.
  */
 
-import org.apache.maven.model.Dependency;
-import org.apache.maven.model.Model;
-import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
-import org.apache.maven.shared.transfer.dependencies.collect.CollectorResult;
-import org.apache.maven.shared.transfer.dependencies.collect.DependencyCollectorException;
+import org.apache.maven.shared.transfer.dependencies.collect.DependencyCollector;
 
 /**
- * 
- * @author Robert Scholte
+ *
  */
-interface MavenDependencyCollector
+public interface DependencyCollectorDelegate extends DependencyCollector
 {
-
-    CollectorResult collectDependencies( Dependency root )
-        throws DependencyCollectorException;
-
-    CollectorResult collectDependencies( DependableCoordinate root )
-        throws DependencyCollectorException;
-
-    CollectorResult collectDependencies( Model root )
-        throws DependencyCollectorException;
-
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Invoker.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Invoker.java
deleted file mode 100644
index 45872e9..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Invoker.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package org.apache.maven.shared.transfer.dependencies.collect.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import org.apache.maven.shared.transfer.dependencies.collect.DependencyCollectorException;
-
-import java.lang.reflect.InvocationTargetException;
-
-/**
- * Invokes method on objects using reflection.
- */
-final class Invoker
-{
-    private Invoker()
-    {
-        // do not instantiate
-    }
-
-    public static <T> T invoke( Object object, String method ) throws DependencyCollectorException
-    {
-        try
-        {
-            @SuppressWarnings( "unchecked" )
-            T invoke = (T) object.getClass().getMethod( method ).invoke( object );
-            return invoke;
-        }
-        catch ( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
-        {
-            throw new DependencyCollectorException( e.getMessage(), e );
-        }
-    }
-
-    public static <T> T invoke( Class<?> objectClazz, String staticMethod, Class<?> argClazz, Object arg )
-            throws DependencyCollectorException
-    {
-        try
-        {
-            @SuppressWarnings( "unchecked" )
-            T invoke = (T) objectClazz.getMethod( staticMethod, argClazz ).invoke( null, arg );
-            return invoke;
-        }
-        catch ( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
-        {
-            throw new DependencyCollectorException( e.getMessage(), e );
-        }
-    }
-
-    /**
-     * @param objectClazz  the class of the static method
-     * @param staticMethod the static method to call
-     * @param argClasses   the classes of the argument, used to select the right static method
-     * @param args         the actual arguments to be passed
-     * @return the result of the method invocation
-     * @throws DependencyCollectorException if any checked exception occurs
-     */
-    public static <T> T invoke( Class<?> objectClazz, String staticMethod, Class<?>[] argClasses, Object[] args )
-            throws DependencyCollectorException
-    {
-        if ( args.length != argClasses.length )
-        {
-            throw new IllegalArgumentException( "The number of elements in argClasses and args are not the same." );
-        }
-
-        try
-        {
-            @SuppressWarnings( "unchecked" )
-            T invoke = (T) objectClazz.getMethod( staticMethod, argClasses ).invoke( null, args );
-            return invoke;
-        }
-        catch ( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
-        {
-            throw new DependencyCollectorException( e.getMessage(), e );
-        }
-    }
-
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven30ArtifactRepositoryAdapter.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven30ArtifactRepositoryAdapter.java
deleted file mode 100644
index b09ccd4..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven30ArtifactRepositoryAdapter.java
+++ /dev/null
@@ -1,266 +0,0 @@
-package org.apache.maven.shared.transfer.dependencies.collect.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.List;
-
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.metadata.ArtifactMetadata;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
-import org.apache.maven.artifact.repository.Authentication;
-import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
-import org.apache.maven.repository.Proxy;
-import org.sonatype.aether.repository.RemoteRepository;
-import org.sonatype.aether.repository.RepositoryPolicy;
-
-/**
- * ArtifactRepository wrapper around {@link RemoteRepository}
- * 
- * @author Robert Scholte
- *
- */
-class Maven30ArtifactRepositoryAdapter implements ArtifactRepository
-{
-    
-    private RemoteRepository remoteRepository;
-
-    /**
-     * @param remoteRepository {@link RemoteRepository}
-     */
-    Maven30ArtifactRepositoryAdapter( RemoteRepository remoteRepository )
-    {
-        this.remoteRepository = remoteRepository;
-    }
-
-    @Override
-    public String pathOf( Artifact artifact )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String pathOfRemoteRepositoryMetadata( ArtifactMetadata artifactMetadata )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String pathOfLocalRepositoryMetadata( ArtifactMetadata metadata, ArtifactRepository repository )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getUrl()
-    {
-        return remoteRepository.getUrl();
-    }
-
-    @Override
-    public void setUrl( String url )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getBasedir()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getProtocol()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getId()
-    {
-        return remoteRepository.getId();
-    }
-
-    @Override
-    public void setId( String id )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ArtifactRepositoryPolicy getSnapshots()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setSnapshotUpdatePolicy( ArtifactRepositoryPolicy policy )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ArtifactRepositoryPolicy getReleases()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setReleaseUpdatePolicy( ArtifactRepositoryPolicy policy )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public ArtifactRepositoryLayout getLayout()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setLayout( ArtifactRepositoryLayout layout )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String getKey()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isUniqueVersion()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isBlacklisted()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setBlacklisted( boolean blackListed )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Artifact find( Artifact artifact )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public List<String> findVersions( Artifact artifact )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isProjectAware()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setAuthentication( Authentication authentication )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Authentication getAuthentication()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setProxy( Proxy proxy )
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Proxy getProxy()
-    {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public String toString()
-    {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append( "       id: " ).append( getId() ).append( "\n" );
-        sb.append( "      url: " ).append( getUrl() ).append( "\n" );
-        sb.append( "   layout: " ).append( "default" ).append( "\n" );
-
-        RepositoryPolicy snapshotPolicy = remoteRepository.getPolicy( true ); 
-        sb.append( "snapshots: [enabled => " ).append( snapshotPolicy.isEnabled() );
-        sb.append( ", update => " ).append( snapshotPolicy.getUpdatePolicy() ).append( "]\n" );
-
-        RepositoryPolicy releasePolicy = remoteRepository.getPolicy( false ); 
-        sb.append( " releases: [enabled => " ).append( releasePolicy.isEnabled() );
-        sb.append( ", update => " ).append( releasePolicy.getUpdatePolicy() ).append( "]\n" );
-
-        return sb.toString();
-    }
-    
-    
-    @Override
-    public int hashCode()
-    {
-        return remoteRepository.hashCode();
-    }
-
-    @Override
-    public boolean equals( Object obj )
-    {
-        if ( this == obj )
-        {
-            return true;
-        }
-        if ( obj == null )
-        {
-            return false;
-        }
-        if ( getClass() != obj.getClass() )
-        {
-            return false;
-        }
-        
-        Maven30ArtifactRepositoryAdapter other = (Maven30ArtifactRepositoryAdapter) obj;
-        if ( remoteRepository == null )
-        {
-            if ( other.remoteRepository != null )
-            {
-                return false;
-            }
-        }
-        else if ( !remoteRepository.equals( other.remoteRepository ) )
-        {
-            return false;
-        }
-        return true;
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven30CollectorResult.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven30CollectorResult.java
deleted file mode 100644
index 081dd66..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven30CollectorResult.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package org.apache.maven.shared.transfer.dependencies.collect.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.shared.transfer.dependencies.collect.CollectorResult;
-import org.sonatype.aether.collection.CollectResult;
-import org.sonatype.aether.graph.DependencyNode;
-import org.sonatype.aether.graph.DependencyVisitor;
-import org.sonatype.aether.repository.RemoteRepository;
-
-/**
- * CollectorResult wrapper around {@link CollectResult} 
- * 
- * @author Robert Scholte
- *
- */
-class Maven30CollectorResult implements CollectorResult
-{
-    private final CollectResult collectResult;
-    
-    /**
-     * @param collectResult {@link CollectorResult}
-     */
-    Maven30CollectorResult( CollectResult collectResult )
-    {
-        this.collectResult = collectResult;
-    }
-
-    @Override
-    public List<ArtifactRepository> getRemoteRepositories()
-    {
-        final Set<RemoteRepository> aetherRepositories = new HashSet<>();
-        
-        DependencyVisitor visitor = new DependencyVisitor()
-        {
-            @Override
-            public boolean visitEnter( DependencyNode node )
-            {
-                aetherRepositories.addAll( node.getRepositories() );
-                return true;
-            }
-            
-            @Override
-            public boolean visitLeave( DependencyNode node )
-            {
-                return true;
-            }
-        };
-        
-        collectResult.getRoot().accept( visitor );
-        
-        List<ArtifactRepository> mavenRepositories = new ArrayList<>( aetherRepositories.size() );
-        
-        for ( RemoteRepository aetherRepository : aetherRepositories )
-        {
-            mavenRepositories.add( new Maven30ArtifactRepositoryAdapter( aetherRepository ) );
-        }
-        
-        return mavenRepositories;
-    }
-
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven30DependencyCollector.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven30DependencyCollector.java
deleted file mode 100644
index 8a85003..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven30DependencyCollector.java
+++ /dev/null
@@ -1,160 +0,0 @@
-package org.apache.maven.shared.transfer.dependencies.collect.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.maven.RepositoryUtils;
-import org.apache.maven.artifact.handler.ArtifactHandler;
-import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
-import org.apache.maven.model.Model;
-import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
-import org.apache.maven.shared.transfer.dependencies.collect.CollectorResult;
-import org.apache.maven.shared.transfer.dependencies.collect.DependencyCollector;
-import org.apache.maven.shared.transfer.dependencies.collect.DependencyCollectorException;
-import org.sonatype.aether.RepositorySystem;
-import org.sonatype.aether.RepositorySystemSession;
-import org.sonatype.aether.artifact.Artifact;
-import org.sonatype.aether.artifact.ArtifactTypeRegistry;
-import org.sonatype.aether.collection.CollectRequest;
-import org.sonatype.aether.collection.DependencyCollectionException;
-import org.sonatype.aether.graph.Dependency;
-import org.sonatype.aether.repository.RemoteRepository;
-import org.sonatype.aether.util.artifact.DefaultArtifact;
-
-/**
- * Maven 3.0 implementation of the {@link DependencyCollector}
- *
- * @author Robert Scholte
- */
-class Maven30DependencyCollector implements MavenDependencyCollector
-{
-    private final RepositorySystem repositorySystem;
-
-    private final ArtifactHandlerManager artifactHandlerManager;
-
-    private final RepositorySystemSession session;
-
-    private final List<RemoteRepository> aetherRepositories;
-
-    Maven30DependencyCollector( RepositorySystem repositorySystem, ArtifactHandlerManager artifactHandlerManager,
-            RepositorySystemSession session, List<RemoteRepository> aetherRepositories )
-    {
-        super();
-        this.repositorySystem = repositorySystem;
-        this.artifactHandlerManager = artifactHandlerManager;
-        this.session = session;
-        this.aetherRepositories = aetherRepositories;
-    }
-
-    private static Dependency toDependency( org.apache.maven.model.Dependency mavenDependency,
-            ArtifactTypeRegistry typeRegistry ) throws DependencyCollectorException
-    {
-        Class<?>[] argClasses = new Class<?>[] {org.apache.maven.model.Dependency.class, ArtifactTypeRegistry.class};
-
-        Object[] args = new Object[] {mavenDependency, typeRegistry};
-
-        return Invoker.invoke( RepositoryUtils.class, "toDependency", argClasses, args );
-    }
-
-    @Override
-    public CollectorResult collectDependencies( org.apache.maven.model.Dependency root )
-            throws DependencyCollectorException
-    {
-        ArtifactTypeRegistry typeRegistry = Invoker.invoke( RepositoryUtils.class, "newArtifactTypeRegistry",
-                ArtifactHandlerManager.class, artifactHandlerManager );
-
-        CollectRequest request = new CollectRequest();
-        request.setRoot( toDependency( root, typeRegistry ) );
-
-        return collectDependencies( request );
-    }
-
-    @Override
-    public CollectorResult collectDependencies( DependableCoordinate root ) throws DependencyCollectorException
-    {
-        ArtifactHandler artifactHandler = artifactHandlerManager.getArtifactHandler( root.getType() );
-
-        String extension = artifactHandler != null ? artifactHandler.getExtension() : null;
-
-        Artifact aetherArtifact = new DefaultArtifact( root.getGroupId(), root.getArtifactId(), root.getClassifier(),
-                extension, root.getVersion() );
-
-        CollectRequest request = new CollectRequest();
-        request.setRoot( new Dependency( aetherArtifact, null ) );
-
-        return collectDependencies( request );
-    }
-
-    @Override
-    public CollectorResult collectDependencies( Model root ) throws DependencyCollectorException
-    {
-        // Are there examples where packaging and type are NOT in sync
-        ArtifactHandler artifactHandler = artifactHandlerManager.getArtifactHandler( root.getPackaging() );
-
-        String extension = artifactHandler != null ? artifactHandler.getExtension() : null;
-
-        Artifact aetherArtifact = new DefaultArtifact( root.getGroupId(), root.getArtifactId(), extension,
-                root.getVersion() );
-
-        CollectRequest request = new CollectRequest();
-        request.setRoot( new Dependency( aetherArtifact, null ) );
-
-        ArtifactTypeRegistry typeRegistry = Invoker.invoke( RepositoryUtils.class, "newArtifactTypeRegistry",
-                ArtifactHandlerManager.class, artifactHandlerManager );
-
-        List<Dependency> aetherDependencies = new ArrayList<>( root.getDependencies().size() );
-        for ( org.apache.maven.model.Dependency mavenDependency : root.getDependencies() )
-        {
-            aetherDependencies.add( toDependency( mavenDependency, typeRegistry ) );
-        }
-        request.setDependencies( aetherDependencies );
-
-        if ( root.getDependencyManagement() != null )
-        {
-            List<Dependency> aetherManagerDependencies = new ArrayList<>(
-                    root.getDependencyManagement().getDependencies().size() );
-
-            for ( org.apache.maven.model.Dependency mavenDependency : root.getDependencyManagement().getDependencies() )
-            {
-                aetherManagerDependencies.add( toDependency( mavenDependency, typeRegistry ) );
-            }
-
-            request.setManagedDependencies( aetherManagerDependencies );
-        }
-
-        return collectDependencies( request );
-    }
-
-    private CollectorResult collectDependencies( CollectRequest request ) throws DependencyCollectorException
-    {
-        request.setRepositories( aetherRepositories );
-
-        try
-        {
-            return new Maven30CollectorResult( repositorySystem.collectDependencies( session, request ) );
-        }
-        catch ( DependencyCollectionException e )
-        {
-            throw new DependencyCollectorException( e.getMessage(), e );
-        }
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven30DependencyNodeAdapter.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven30DependencyNodeAdapter.java
deleted file mode 100644
index 87a10f8..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven30DependencyNodeAdapter.java
+++ /dev/null
@@ -1,163 +0,0 @@
-package org.apache.maven.shared.transfer.dependencies.collect.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.maven.RepositoryUtils;
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.shared.transfer.dependencies.collect.DependencyCollectorException;
-import org.apache.maven.shared.transfer.graph.DependencyNode;
-import org.apache.maven.shared.transfer.graph.DependencyVisitor;
-import org.sonatype.aether.repository.RemoteRepository;
-
-/**
- * DependencyCollectorNode wrapper around {@link org.sonatype.aether.graph.DependencyNode}
- * 
- * @author Pim Moerenhout
- *
- */
-class Maven30DependencyNodeAdapter implements DependencyNode
-{
-
-    private org.sonatype.aether.graph.DependencyNode dependencyNode;
-
-    /**
-     * @param dependencyNode {@link org.sonatype.aether.graph.DependencyNode}
-     */
-    Maven30DependencyNodeAdapter( org.sonatype.aether.graph.DependencyNode dependencyNode )
-    {
-        this.dependencyNode = dependencyNode;
-    }
-
-    @Override
-    public Artifact getArtifact()
-    {
-        return getArtifact( dependencyNode.getDependency().getArtifact() );
-    }
-
-    @Override
-    public List<DependencyNode> getChildren()
-    {
-        List<org.sonatype.aether.graph.DependencyNode> aetherChildren = dependencyNode.getChildren();
-        List<DependencyNode> children = new ArrayList<>( aetherChildren.size() );
-        for ( org.sonatype.aether.graph.DependencyNode aetherChild : aetherChildren )
-        {
-            children.add( new Maven30DependencyNodeAdapter( aetherChild ) );
-        }
-        return children;
-    }
-
-    @Override
-    public List<ArtifactRepository> getRemoteRepositories()
-    {
-        List<RemoteRepository> aetherRepositories = dependencyNode.getRepositories();
-        List<ArtifactRepository> mavenRepositories = new ArrayList<>( aetherRepositories.size() );
-
-        for ( RemoteRepository aetherRepository : aetherRepositories )
-        {
-            mavenRepositories.add( new Maven30ArtifactRepositoryAdapter( aetherRepository ) );
-        }
-
-        return mavenRepositories;
-    }
-
-    @Override
-    public Boolean getOptional()
-    {
-        return dependencyNode.getDependency().isOptional();
-    }
-
-    @Override
-    public String getScope()
-    {
-        return dependencyNode.getDependency().getScope();
-    }
-
-    @Override
-    public boolean accept( DependencyVisitor visitor )
-    {
-        if ( visitor.visitEnter( this ) )
-        {
-            for ( org.sonatype.aether.graph.DependencyNode child : dependencyNode.getChildren() )
-            {
-                DependencyNode node = new Maven30DependencyNodeAdapter( child );
-                if ( !node.accept( visitor ) )
-                {
-                    break;
-                }
-            }
-        }
-
-        return visitor.visitLeave( this );
-    }
-
-    @Override
-    public int hashCode()
-    {
-        return dependencyNode.hashCode();
-    }
-
-    @Override
-    public boolean equals( Object obj )
-    {
-        if ( this == obj )
-        {
-            return true;
-        }
-        if ( obj == null )
-        {
-            return false;
-        }
-        if ( getClass() != obj.getClass() )
-        {
-            return false;
-        }
-
-        Maven30DependencyNodeAdapter other = (Maven30DependencyNodeAdapter) obj;
-        if ( dependencyNode == null )
-        {
-            if ( other.dependencyNode != null )
-            {
-                return false;
-            }
-        }
-        else if ( !dependencyNode.equals( other.dependencyNode ) )
-        {
-            return false;
-        }
-        return true;
-    }
-
-    private Artifact getArtifact( org.sonatype.aether.artifact.Artifact aetherArtifact )
-    {
-        try
-        {
-            return Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                org.sonatype.aether.artifact.Artifact.class, aetherArtifact );
-        }
-        catch ( DependencyCollectorException e )
-        {
-            throw new RuntimeException( e );
-        }
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven31ArtifactRepositoryAdapter.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven31ArtifactRepositoryAdapter.java
index 854cf4a..6669f41 100644
--- a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven31ArtifactRepositoryAdapter.java
+++ b/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven31ArtifactRepositoryAdapter.java
@@ -207,6 +207,18 @@ class Maven31ArtifactRepositoryAdapter implements ArtifactRepository
     }
 
     @Override
+    public List<ArtifactRepository> getMirroredRepositories()
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setMirroredRepositories(final List<ArtifactRepository> mirroredRepositories)
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public String toString()
     {
         StringBuilder sb = new StringBuilder();
diff --git a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven31DependencyCollector.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven31DependencyCollector.java
index 50f3700..1dc768c 100644
--- a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven31DependencyCollector.java
+++ b/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven31DependencyCollector.java
@@ -22,14 +22,21 @@ package org.apache.maven.shared.transfer.dependencies.collect.internal;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
 import org.apache.maven.RepositoryUtils;
 import org.apache.maven.artifact.handler.ArtifactHandler;
 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
 import org.apache.maven.model.Model;
+import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
 import org.apache.maven.shared.transfer.dependencies.collect.CollectorResult;
 import org.apache.maven.shared.transfer.dependencies.collect.DependencyCollector;
 import org.apache.maven.shared.transfer.dependencies.collect.DependencyCollectorException;
+import org.apache.maven.shared.transfer.internal.ComponentSupport;
+import org.apache.maven.shared.transfer.internal.Selector;
 import org.eclipse.aether.RepositorySystem;
 import org.eclipse.aether.RepositorySystemSession;
 import org.eclipse.aether.artifact.Artifact;
@@ -45,51 +52,49 @@ import org.eclipse.aether.repository.RemoteRepository;
  *
  * @author Robert Scholte
  */
-class Maven31DependencyCollector implements MavenDependencyCollector
+@Singleton
+@Named(Selector.MAVEN_3_1)
+public class Maven31DependencyCollector
+    extends ComponentSupport
+    implements DependencyCollectorDelegate
 {
     private final RepositorySystem repositorySystem;
 
     private final ArtifactHandlerManager artifactHandlerManager;
 
-    private final RepositorySystemSession session;
-
     private final List<RemoteRepository> aetherRepositories;
 
-    Maven31DependencyCollector( RepositorySystem repositorySystem, ArtifactHandlerManager artifactHandlerManager,
-            RepositorySystemSession session, List<RemoteRepository> aetherRepositories )
+    @Inject
+    public Maven31DependencyCollector( final RepositorySystem repositorySystem,
+                                       final ArtifactHandlerManager artifactHandlerManager,
+                                       final List<RemoteRepository> aetherRepositories )
     {
-        super();
         this.repositorySystem = repositorySystem;
         this.artifactHandlerManager = artifactHandlerManager;
-        this.session = session;
         this.aetherRepositories = aetherRepositories;
     }
 
     private static Dependency toDependency( org.apache.maven.model.Dependency mavenDependency,
-            ArtifactTypeRegistry typeRegistry ) throws DependencyCollectorException
+            ArtifactTypeRegistry typeRegistry )
     {
-        Class<?>[] argClasses = new Class<?>[] {org.apache.maven.model.Dependency.class, ArtifactTypeRegistry.class};
-
-        Object[] args = new Object[] {mavenDependency, typeRegistry};
-
-        return Invoker.invoke( RepositoryUtils.class, "toDependency", argClasses, args );
+        return RepositoryUtils.toDependency(mavenDependency, typeRegistry);
     }
 
     @Override
-    public CollectorResult collectDependencies( org.apache.maven.model.Dependency root )
+    public CollectorResult collectDependencies( ProjectBuildingRequest buildingRequest, org.apache.maven.model.Dependency root )
             throws DependencyCollectorException
     {
-        ArtifactTypeRegistry typeRegistry = Invoker.invoke( RepositoryUtils.class, "newArtifactTypeRegistry",
-                ArtifactHandlerManager.class, artifactHandlerManager );
+        ArtifactTypeRegistry typeRegistry = RepositoryUtils.newArtifactTypeRegistry(artifactHandlerManager);
 
         CollectRequest request = new CollectRequest();
         request.setRoot( toDependency( root, typeRegistry ) );
 
-        return collectDependencies( request );
+        return collectDependencies( buildingRequest.getRepositorySession(), request );
     }
 
     @Override
-    public CollectorResult collectDependencies( DependableCoordinate root ) throws DependencyCollectorException
+    public CollectorResult collectDependencies( ProjectBuildingRequest buildingRequest,
+                                                DependableCoordinate root ) throws DependencyCollectorException
     {
         ArtifactHandler artifactHandler = artifactHandlerManager.getArtifactHandler( root.getType() );
 
@@ -101,11 +106,12 @@ class Maven31DependencyCollector implements MavenDependencyCollector
         CollectRequest request = new CollectRequest();
         request.setRoot( new Dependency( aetherArtifact, null ) );
 
-        return collectDependencies( request );
+        return collectDependencies( buildingRequest.getRepositorySession(), request );
     }
 
     @Override
-    public CollectorResult collectDependencies( Model root ) throws DependencyCollectorException
+    public CollectorResult collectDependencies( ProjectBuildingRequest buildingRequest,
+                                                Model root ) throws DependencyCollectorException
     {
         // Are there examples where packaging and type are NOT in sync
         ArtifactHandler artifactHandler = artifactHandlerManager.getArtifactHandler( root.getPackaging() );
@@ -118,8 +124,7 @@ class Maven31DependencyCollector implements MavenDependencyCollector
         CollectRequest request = new CollectRequest();
         request.setRoot( new Dependency( aetherArtifact, null ) );
 
-        ArtifactTypeRegistry typeRegistry = Invoker.invoke( RepositoryUtils.class, "newArtifactTypeRegistry",
-                ArtifactHandlerManager.class, artifactHandlerManager );
+        ArtifactTypeRegistry typeRegistry = RepositoryUtils.newArtifactTypeRegistry(artifactHandlerManager);
 
         List<Dependency> aetherDependencies = new ArrayList<>( root.getDependencies().size() );
         for ( org.apache.maven.model.Dependency mavenDependency : root.getDependencies() )
@@ -141,10 +146,11 @@ class Maven31DependencyCollector implements MavenDependencyCollector
             request.setManagedDependencies( aetherManagerDependencies );
         }
 
-        return collectDependencies( request );
+        return collectDependencies( buildingRequest.getRepositorySession(), request );
     }
 
-    private CollectorResult collectDependencies( CollectRequest request ) throws DependencyCollectorException
+    private CollectorResult collectDependencies( RepositorySystemSession session,
+                                                 CollectRequest request ) throws DependencyCollectorException
     {
         request.setRepositories( aetherRepositories );
 
diff --git a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven31DependencyNodeAdapter.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven31DependencyNodeAdapter.java
index f0cccc4..cdd2f22 100644
--- a/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven31DependencyNodeAdapter.java
+++ b/src/main/java/org/apache/maven/shared/transfer/dependencies/collect/internal/Maven31DependencyNodeAdapter.java
@@ -150,14 +150,6 @@ class Maven31DependencyNodeAdapter implements DependencyNode
 
     private Artifact getArtifact( org.eclipse.aether.artifact.Artifact aetherArtifact )
     {
-        try
-        {
-            return Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                org.eclipse.aether.artifact.Artifact.class, aetherArtifact );
-        }
-        catch ( DependencyCollectorException e )
-        {
-            throw new RuntimeException( e );
-        }
+        return RepositoryUtils.toArtifact(aetherArtifact);
     }
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/DefaultDependencyResolver.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/DefaultDependencyResolver.java
index 7718c19..309d076 100644
--- a/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/DefaultDependencyResolver.java
+++ b/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/DefaultDependencyResolver.java
@@ -20,10 +20,12 @@ package org.apache.maven.shared.transfer.dependencies.resolve.internal;
  */
 
 import java.util.Collection;
-import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
 
-import org.apache.maven.RepositoryUtils;
-import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
 import org.apache.maven.model.Dependency;
 import org.apache.maven.model.Model;
 import org.apache.maven.project.ProjectBuildingRequest;
@@ -32,96 +34,55 @@ import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult;
 import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
 import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver;
 import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException;
-import org.codehaus.plexus.PlexusConstants;
-import org.codehaus.plexus.PlexusContainer;
-import org.codehaus.plexus.component.annotations.Component;
-import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
-import org.codehaus.plexus.context.Context;
-import org.codehaus.plexus.context.ContextException;
-import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
+import org.apache.maven.shared.transfer.internal.Delegator;
 
 /**
  *
  */
-@Component( role = DependencyResolver.class, hint = "default" )
-class DefaultDependencyResolver implements DependencyResolver, Contextualizable
+@Singleton
+@Named
+public class DefaultDependencyResolver
+    extends Delegator<DependencyResolverDelegate>
+    implements DependencyResolver
 {
-    private PlexusContainer container;
+    private final DependencyResolverDelegate delegate;
 
-    @Override
-    public Iterable<ArtifactResult> resolveDependencies( ProjectBuildingRequest buildingRequest,
-            Collection<Dependency> coordinates, Collection<Dependency> managedDependencies, TransformableFilter filter )
-            throws DependencyResolverException
+    @Inject
+    public DefaultDependencyResolver(final Map<String, DependencyResolverDelegate> delegates)
     {
-        validateBuildingRequest( buildingRequest );
-
-        try
-        {
-            return getMavenDependencyResolver( buildingRequest ).resolveDependencies( coordinates, managedDependencies,
-                    filter );
-        }
-        catch ( ComponentLookupException e )
-        {
-            throw new DependencyResolverException( e.getMessage(), e );
-        }
+        super(delegates);
+        this.delegate = selectDelegate();
     }
 
     @Override
-    public Iterable<ArtifactResult> resolveDependencies( ProjectBuildingRequest buildingRequest,
-            DependableCoordinate coordinate, TransformableFilter filter ) throws DependencyResolverException
+    public Iterable<ArtifactResult> resolveDependencies(final ProjectBuildingRequest buildingRequest,
+                                                        final DependableCoordinate coordinate,
+                                                        final TransformableFilter filter)
+        throws DependencyResolverException
     {
         validateParameters( buildingRequest, coordinate );
-        try
-        {
-            return getMavenDependencyResolver( buildingRequest ).resolveDependencies( coordinate, filter );
-        }
-        catch ( ComponentLookupException e )
-        {
-            throw new DependencyResolverException( e.getMessage(), e );
-        }
+        return delegate.resolveDependencies(buildingRequest, coordinate, filter);
     }
 
     @Override
-    public Iterable<ArtifactResult> resolveDependencies( ProjectBuildingRequest buildingRequest, Model model,
-            TransformableFilter filter ) throws DependencyResolverException
+    public Iterable<ArtifactResult> resolveDependencies(final ProjectBuildingRequest buildingRequest,
+                                                        final Model model,
+                                                        final TransformableFilter filter)
+        throws DependencyResolverException
     {
         validateParameters( buildingRequest, model );
-        try
-        {
-            return getMavenDependencyResolver( buildingRequest ).resolveDependencies( model, filter );
-        }
-        catch ( ComponentLookupException e )
-        {
-            throw new DependencyResolverException( e.getMessage(), e );
-        }
-    }
-
-    /**
-     * @return true if the current Maven version is Maven 3.1.
-     */
-    private boolean isMaven31()
-    {
-        try
-        {
-            // Maven 3.1 specific
-            Thread.currentThread().getContextClassLoader().loadClass( "org.eclipse.aether.artifact.Artifact" );
-            return true;
-        }
-        catch ( ClassNotFoundException e )
-        {
-            return false;
-        }
+        return delegate.resolveDependencies(buildingRequest, model, filter);
     }
 
-    /**
-     * Injects the Plexus content.
-     *
-     * @param context Plexus context to inject.
-     * @throws ContextException if the PlexusContainer could not be located.
-     */
-    public void contextualize( Context context ) throws ContextException
+    @Override
+    public Iterable<ArtifactResult> resolveDependencies(final ProjectBuildingRequest buildingRequest,
+                                                        final Collection<Dependency> dependencies,
+                                                        final Collection<Dependency> managedDependencies,
+                                                        final TransformableFilter filter)
+        throws DependencyResolverException
     {
-        container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
+        validateBuildingRequest( buildingRequest );
+        return delegate.resolveDependencies(buildingRequest, dependencies, managedDependencies, filter);
     }
 
     private void validateParameters( ProjectBuildingRequest buildingRequest, DependableCoordinate coordinate )
@@ -143,42 +104,6 @@ class DefaultDependencyResolver implements DependencyResolver, Contextualizable
 
     }
 
-    private MavenDependencyResolver getMavenDependencyResolver( ProjectBuildingRequest buildingRequest )
-            throws ComponentLookupException, DependencyResolverException
-    {
-        ArtifactHandlerManager artifactHandlerManager = container.lookup( ArtifactHandlerManager.class );
-
-        if ( isMaven31() )
-        {
-            org.eclipse.aether.RepositorySystem m31RepositorySystem = container.lookup(
-                    org.eclipse.aether.RepositorySystem.class );
-
-            org.eclipse.aether.RepositorySystemSession session = Invoker.invoke( buildingRequest,
-                    "getRepositorySession" );
-
-            List<org.eclipse.aether.repository.RemoteRepository> aetherRepositories = Invoker.invoke(
-                    RepositoryUtils.class, "toRepos", List.class, buildingRequest.getRemoteRepositories() );
-
-            return new Maven31DependencyResolver( m31RepositorySystem, artifactHandlerManager, session,
-                    aetherRepositories );
-        }
-        else
-        {
-            org.sonatype.aether.RepositorySystem m30RepositorySystem = container.lookup(
-                    org.sonatype.aether.RepositorySystem.class );
-
-            org.sonatype.aether.RepositorySystemSession session = Invoker.invoke( buildingRequest,
-                    "getRepositorySession" );
-
-            List<org.sonatype.aether.repository.RemoteRepository> aetherRepositories = Invoker.invoke(
-                    RepositoryUtils.class, "toRepos", List.class, buildingRequest.getRemoteRepositories() );
-
-            return new Maven30DependencyResolver( m30RepositorySystem, artifactHandlerManager, session,
-                    aetherRepositories );
-
-        }
-    }
-
     private void validateBuildingRequest( ProjectBuildingRequest buildingRequest )
     {
         if ( buildingRequest == null )
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/MavenArtifactDeployer.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/DependencyResolverDelegate.java
similarity index 60%
copy from src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/MavenArtifactDeployer.java
copy to src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/DependencyResolverDelegate.java
index 8f9fea1..a70f128 100644
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/MavenArtifactDeployer.java
+++ b/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/DependencyResolverDelegate.java
@@ -1,4 +1,4 @@
-package org.apache.maven.shared.transfer.artifact.deploy.internal;
+package org.apache.maven.shared.transfer.dependencies.resolve.internal;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,24 +19,11 @@ package org.apache.maven.shared.transfer.artifact.deploy.internal;
  * under the License.
  */
 
-import java.util.Collection;
-
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployerException;
+import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver;
 
 /**
- * 
  * @author Robert Scholte
- *
  */
-interface MavenArtifactDeployer
+public interface DependencyResolverDelegate extends DependencyResolver
 {
-
-    void deploy( Collection<Artifact> mavenArtifacts )
-        throws ArtifactDeployerException;
-
-    void deploy( ArtifactRepository remoteRepository, Collection<Artifact> mavenArtifacts )
-        throws ArtifactDeployerException;
-
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Invoker.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Invoker.java
deleted file mode 100644
index dc7ad4c..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Invoker.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package org.apache.maven.shared.transfer.dependencies.resolve.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.lang.reflect.InvocationTargetException;
-
-import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException;
-
-/**
- * Invokes method on objects using reflection.
- */
-final class Invoker
-{
-    private Invoker()
-    {
-        // do not instantiate
-    }
-
-    public static <T> T invoke( Object object, String method )
-        throws DependencyResolverException
-    {
-        try
-        {
-            @SuppressWarnings( "unchecked" )
-            T invoke = (T) object.getClass().getMethod( method ).invoke( object );
-            return invoke;
-        }
-        catch ( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
-        {
-            throw new DependencyResolverException( e.getMessage(), e );
-        }
-    }
-
-    public static <T> T invoke( Class<?> objectClazz, String staticMethod, Class<?> argClazz, Object arg )
-        throws DependencyResolverException
-    {
-        try
-        {
-            @SuppressWarnings( "unchecked" )
-            T invoke = (T) objectClazz.getMethod( staticMethod, argClazz ).invoke( null, arg );
-            return invoke;
-        }
-        catch ( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
-        {
-            throw new DependencyResolverException( e.getMessage(), e );
-        }
-    }
-
-    /**
-     * <strong>Note:</strong> Ensure that argClasses and args have the same number of elements
-     * 
-     * @param objectClazz the class of the static method
-     * @param staticMethod the static method to call
-     * @param argClasses the classes of the argument, used to select the right static method
-     * @param args the actual arguments to be passed
-     * @return the result of the method invocation
-     * @throws DependencyResolverException if any checked exception occurs
-     */
-    public static <T> T invoke( Class<?> objectClazz, String staticMethod, Class<?>[] argClasses, Object[] args )
-        throws DependencyResolverException
-    {
-        if ( args.length != argClasses.length )
-        {
-            throw new IllegalArgumentException( "The number of elements in argClasses and args are not the same." );
-        }
-
-        try
-        {
-            @SuppressWarnings( "unchecked" )
-            T invoke = (T) objectClazz.getMethod( staticMethod, argClasses ).invoke( null, args );
-            return invoke;
-        }
-        catch ( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
-        {
-            throw new DependencyResolverException( e.getMessage(), e );
-        }
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Maven30ArtifactResult.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Maven30ArtifactResult.java
deleted file mode 100644
index b9f37d9..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Maven30ArtifactResult.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.apache.maven.shared.transfer.dependencies.resolve.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import org.apache.maven.RepositoryUtils;
-import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException;
-import org.sonatype.aether.artifact.Artifact;
-import org.sonatype.aether.resolution.ArtifactResult;
-
-/**
- * {@link org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult} wrapper for {@link ArtifactResult}
- *
- * @author Robert Scholte
- * @since 3.0
- */
-class Maven30ArtifactResult implements org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult
-{
-    private final ArtifactResult artifactResult;
-
-    /**
-     * @param artifactResult {@link ArtifactResult}
-     */
-    Maven30ArtifactResult( ArtifactResult artifactResult )
-    {
-        this.artifactResult = artifactResult;
-    }
-
-    @Override
-    public org.apache.maven.artifact.Artifact getArtifact()
-    {
-        try
-        {
-            return Invoker.invoke( RepositoryUtils.class, "toArtifact", Artifact.class, artifactResult.getArtifact() );
-        }
-        catch ( DependencyResolverException e )
-        {
-            throw new RuntimeException( e );
-        }
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Maven30DependencyResolver.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Maven30DependencyResolver.java
deleted file mode 100644
index 031d604..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Maven30DependencyResolver.java
+++ /dev/null
@@ -1,247 +0,0 @@
-package org.apache.maven.shared.transfer.dependencies.resolve.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.maven.RepositoryUtils;
-import org.apache.maven.artifact.handler.ArtifactHandler;
-import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
-import org.apache.maven.model.DependencyManagement;
-import org.apache.maven.model.Model;
-import org.apache.maven.shared.artifact.filter.resolve.TransformableFilter;
-import org.apache.maven.shared.artifact.filter.resolve.transform.SonatypeAetherFilterTransformer;
-import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
-import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException;
-import org.sonatype.aether.RepositorySystem;
-import org.sonatype.aether.RepositorySystemSession;
-import org.sonatype.aether.artifact.Artifact;
-import org.sonatype.aether.artifact.ArtifactType;
-import org.sonatype.aether.artifact.ArtifactTypeRegistry;
-import org.sonatype.aether.collection.CollectRequest;
-import org.sonatype.aether.collection.DependencyCollectionException;
-import org.sonatype.aether.graph.Dependency;
-import org.sonatype.aether.graph.DependencyFilter;
-import org.sonatype.aether.repository.RemoteRepository;
-import org.sonatype.aether.resolution.ArtifactResolutionException;
-import org.sonatype.aether.resolution.ArtifactResult;
-import org.sonatype.aether.util.artifact.DefaultArtifact;
-import org.sonatype.aether.util.artifact.DefaultArtifactType;
-
-/**
- *
- */
-class Maven30DependencyResolver implements MavenDependencyResolver
-{
-    private static final Class<?>[] ARG_CLASSES = new Class<?>[] {org.apache.maven.model.Dependency.class,
-            ArtifactTypeRegistry.class};
-    private final RepositorySystem repositorySystem;
-    private final ArtifactHandlerManager artifactHandlerManager;
-    private final RepositorySystemSession session;
-    private final List<RemoteRepository> aetherRepositories;
-
-    Maven30DependencyResolver( RepositorySystem repositorySystem, ArtifactHandlerManager artifactHandlerManager,
-            RepositorySystemSession session, List<RemoteRepository> aetherRepositories )
-    {
-        super();
-        this.repositorySystem = repositorySystem;
-        this.artifactHandlerManager = artifactHandlerManager;
-        this.session = session;
-        this.aetherRepositories = aetherRepositories;
-    }
-
-    /**
-     * Based on RepositoryUtils#toDependency(org.apache.maven.model.Dependency, ArtifactTypeRegistry)
-     *
-     * @param coordinate  {@link DependableCoordinate}
-     * @param stereotypes {@link org.eclipse.aether.artifact.ArtifactTypeRegistry
-     * @return as Aether Dependency
-     */
-    private static Dependency toDependency( DependableCoordinate coordinate, ArtifactTypeRegistry stereotypes )
-    {
-        ArtifactType stereotype = stereotypes.get( coordinate.getType() );
-        if ( stereotype == null )
-        {
-            stereotype = new DefaultArtifactType( coordinate.getType() );
-        }
-
-        Artifact artifact = new DefaultArtifact( coordinate.getGroupId(), coordinate.getArtifactId(),
-                coordinate.getClassifier(), null, coordinate.getVersion(), null, stereotype );
-
-        return new Dependency( artifact, null );
-    }
-
-    private static Dependency toDependency( org.apache.maven.model.Dependency mavenDependency,
-            ArtifactTypeRegistry typeRegistry ) throws DependencyResolverException
-    {
-        Object[] args = new Object[] {mavenDependency, typeRegistry};
-
-        return Invoker.invoke( RepositoryUtils.class, "toDependency", ARG_CLASSES, args );
-    }
-
-    @Override
-    // CHECKSTYLE_OFF: LineLength
-    public Iterable<org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult> resolveDependencies(
-            DependableCoordinate coordinate, TransformableFilter dependencyFilter )
-        // CHECKSTYLE_ON: LineLength
-            throws DependencyResolverException
-    {
-        ArtifactTypeRegistry typeRegistry = createTypeRegistry();
-
-        Dependency aetherRoot = toDependency( coordinate, typeRegistry );
-
-        CollectRequest request = new CollectRequest( aetherRoot, aetherRepositories );
-
-        return resolveDependencies( dependencyFilter, request );
-    }
-
-    private ArtifactTypeRegistry createTypeRegistry() throws DependencyResolverException
-    {
-        return Invoker.invoke( RepositoryUtils.class, "newArtifactTypeRegistry", ArtifactHandlerManager.class,
-                artifactHandlerManager );
-    }
-
-    @Override
-    // CHECKSTYLE_OFF: LineLength
-    public Iterable<org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult> resolveDependencies( Model model,
-            TransformableFilter dependencyFilter )
-        // CHECKSTYLE_ON: LineLength
-            throws DependencyResolverException
-    {
-        // Are there examples where packaging and type are NOT in sync
-        ArtifactHandler artifactHandler = artifactHandlerManager.getArtifactHandler( model.getPackaging() );
-
-        String extension = artifactHandler != null ? artifactHandler.getExtension() : null;
-
-        Artifact aetherArtifact = new DefaultArtifact( model.getGroupId(), model.getArtifactId(), extension,
-                model.getVersion() );
-
-        Dependency aetherRoot = new Dependency( aetherArtifact, null );
-
-        CollectRequest request = new CollectRequest( aetherRoot, aetherRepositories );
-
-        request.setDependencies( resolveDependencies( model.getDependencies() ) );
-
-        DependencyManagement mavenDependencyManagement = model.getDependencyManagement();
-        if ( mavenDependencyManagement != null )
-        {
-            request.setManagedDependencies( resolveDependencies( mavenDependencyManagement.getDependencies() ) );
-        }
-
-        return resolveDependencies( dependencyFilter, request );
-    }
-
-    /**
-     * @param mavenDependencies {@link org.apache.maven.model.Dependency} can be {@code null}.
-     * @return List of resolved dependencies.
-     * @throws DependencyResolverException in case of a failure of the typeRegistry error.
-     */
-    // CHECKSTYLE_OFF: LineLength
-    private List<Dependency> resolveDependencies( Collection<org.apache.maven.model.Dependency> mavenDependencies )
-            throws DependencyResolverException
-    // CHECKSTYLE_ON: LineLength
-    {
-        if ( mavenDependencies == null )
-        {
-            return Collections.emptyList();
-        }
-
-        ArtifactTypeRegistry typeRegistry = createTypeRegistry();
-
-        List<Dependency> aetherDependencies = new ArrayList<>( mavenDependencies.size() );
-
-        for ( org.apache.maven.model.Dependency mavenDependency : mavenDependencies )
-        {
-            aetherDependencies.add( toDependency( mavenDependency, typeRegistry ) );
-        }
-
-        return aetherDependencies;
-    }
-
-    @Override
-    // CHECKSTYLE_OFF: LineLength
-    public Iterable<org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult> resolveDependencies(
-            Collection<org.apache.maven.model.Dependency> mavenDependencies,
-            Collection<org.apache.maven.model.Dependency> managedMavenDependencies, TransformableFilter filter )
-        // CHECKSTYLE_ON: LineLength
-            throws DependencyResolverException
-    {
-
-        List<Dependency> aetherDependencies = resolveDependencies( mavenDependencies );
-
-        List<Dependency> aetherManagedDependencies = resolveDependencies( managedMavenDependencies );
-
-        CollectRequest request = new CollectRequest( aetherDependencies, aetherManagedDependencies,
-                aetherRepositories );
-
-        return resolveDependencies( filter, request );
-    }
-
-    // CHECKSTYLE_OFF: LineLength
-    private Iterable<org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult> resolveDependencies(
-            TransformableFilter dependencyFilter, CollectRequest request ) throws DependencyResolverException
-    // CHECKSTYLE_ON :LineLength
-    {
-        try
-        {
-            DependencyFilter depFilter = null;
-            if ( dependencyFilter != null )
-            {
-                depFilter = dependencyFilter.transform( new SonatypeAetherFilterTransformer() );
-            }
-
-            final List<ArtifactResult> dependencyResults = repositorySystem.resolveDependencies( session, request,
-                    depFilter );
-
-            // Keep it lazy! Often artifactsResults aren't used, so transforming up front is too expensive
-            return new Iterable<org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult>()
-            {
-                @Override
-                public Iterator<org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult> iterator()
-                {
-                    // CHECKSTYLE_OFF: LineLength
-                    Collection<org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult> artResults =
-                            new ArrayList<>(
-                            dependencyResults.size() );
-                    // CHECKSTYLE_ON: LineLength
-
-                    for ( ArtifactResult artifactResult : dependencyResults )
-                    {
-                        artResults.add( new Maven30ArtifactResult( artifactResult ) );
-                    }
-
-                    return artResults.iterator();
-                }
-            };
-        }
-        catch ( ArtifactResolutionException e )
-        {
-            throw new Maven30DependencyResolverException( e );
-        }
-        catch ( DependencyCollectionException e )
-        {
-            throw new Maven30DependencyResolverException( e );
-        }
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Maven30DependencyResolverException.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Maven30DependencyResolverException.java
deleted file mode 100644
index 699903b..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Maven30DependencyResolverException.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package org.apache.maven.shared.transfer.dependencies.resolve.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.List;
-
-import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException;
-import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResult;
-import org.sonatype.aether.collection.DependencyCollectionException;
-import org.sonatype.aether.resolution.ArtifactResolutionException;
-
-/**
- * 
- * @author Robert Scholte
- *
- */
-class Maven30DependencyResolverException extends DependencyResolverException
-{
-    private DependencyCollectionException dce;
-    
-    protected Maven30DependencyResolverException( DependencyCollectionException e )
-    {
-        super( e );
-        this.dce = e;
-    }
-    
-    Maven30DependencyResolverException( ArtifactResolutionException e )
-    {
-        super( e );
-    }
-    
-    @Override
-    public DependencyResult getResult()
-    {
-        return new DependencyResult()
-        {
-            @Override
-            public List<Exception> getCollectorExceptions()
-            {
-                return dce.getResult().getExceptions();
-            }
-        };
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Maven31ArtifactResult.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Maven31ArtifactResult.java
index fe26ce4..faf7440 100644
--- a/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Maven31ArtifactResult.java
+++ b/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Maven31ArtifactResult.java
@@ -20,9 +20,7 @@ package org.apache.maven.shared.transfer.dependencies.resolve.internal;
  */
 
 import org.apache.maven.RepositoryUtils;
-import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException;
 import org.eclipse.aether.resolution.ArtifactResult;
-import org.eclipse.aether.artifact.Artifact;
 
 /**
  * {@link org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult} wrapper for {@link ArtifactResult}
@@ -46,14 +44,6 @@ class Maven31ArtifactResult
     @Override
     public org.apache.maven.artifact.Artifact getArtifact()
     {
-        try
-        {
-            return Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                                                                        Artifact.class, artifactResult.getArtifact() );
-        }
-        catch ( DependencyResolverException e )
-        {
-            throw new RuntimeException( e );
-        }
+        return RepositoryUtils.toArtifact(artifactResult.getArtifact());
     }
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Maven31DependencyResolver.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Maven31DependencyResolver.java
index ea35bc5..5d93239 100644
--- a/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Maven31DependencyResolver.java
+++ b/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/Maven31DependencyResolver.java
@@ -24,18 +24,25 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Objects;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
 
 import org.apache.maven.RepositoryUtils;
 import org.apache.maven.artifact.handler.ArtifactHandler;
 import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
 import org.apache.maven.model.DependencyManagement;
 import org.apache.maven.model.Model;
+import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.shared.artifact.filter.resolve.TransformableFilter;
 import org.apache.maven.shared.artifact.filter.resolve.transform.EclipseAetherFilterTransformer;
 import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
 import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException;
+import org.apache.maven.shared.transfer.internal.ComponentSupport;
+import org.apache.maven.shared.transfer.internal.Selector;
 import org.eclipse.aether.RepositorySystem;
-import org.eclipse.aether.RepositorySystemSession;
 import org.eclipse.aether.artifact.Artifact;
 import org.eclipse.aether.artifact.ArtifactType;
 import org.eclipse.aether.artifact.ArtifactTypeRegistry;
@@ -53,23 +60,26 @@ import org.eclipse.aether.resolution.DependencyResult;
 /**
  *
  */
-class Maven31DependencyResolver implements MavenDependencyResolver
+@Singleton
+@Named(Selector.MAVEN_3_1)
+public class Maven31DependencyResolver
+    extends ComponentSupport
+    implements DependencyResolverDelegate
 {
-    private static final Class<?>[] ARG_CLASSES = new Class<?>[] {org.apache.maven.model.Dependency.class,
-            ArtifactTypeRegistry.class};
     private final RepositorySystem repositorySystem;
+
     private final ArtifactHandlerManager artifactHandlerManager;
-    private final RepositorySystemSession session;
+
     private final List<RemoteRepository> aetherRepositories;
 
-    Maven31DependencyResolver( RepositorySystem repositorySystem, ArtifactHandlerManager artifactHandlerManager,
-            RepositorySystemSession session, List<RemoteRepository> aetherRepositories )
+    @Inject
+    public Maven31DependencyResolver( final RepositorySystem repositorySystem,
+                                      final ArtifactHandlerManager artifactHandlerManager,
+                                      final List<RemoteRepository> aetherRepositories )
     {
-        super();
-        this.repositorySystem = repositorySystem;
-        this.artifactHandlerManager = artifactHandlerManager;
-        this.session = session;
-        this.aetherRepositories = aetherRepositories;
+        this.repositorySystem = Objects.requireNonNull( repositorySystem );
+        this.artifactHandlerManager = Objects.requireNonNull( artifactHandlerManager );
+        this.aetherRepositories = Objects.requireNonNull( aetherRepositories );
     }
 
     /**
@@ -94,19 +104,15 @@ class Maven31DependencyResolver implements MavenDependencyResolver
     }
 
     private static Dependency toDependency( org.apache.maven.model.Dependency root, ArtifactTypeRegistry typeRegistry )
-            throws DependencyResolverException
     {
-        Object[] args = new Object[] {root, typeRegistry};
-
-        return Invoker.invoke( RepositoryUtils.class, "toDependency", ARG_CLASSES, args );
+        return RepositoryUtils.toDependency(root, typeRegistry);
     }
 
     @Override
-    // CHECKSTYLE_OFF: LineLength
     public Iterable<org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult> resolveDependencies(
-            DependableCoordinate coordinate, TransformableFilter dependencyFilter )
-        // CHECKSTYLE_ON: LineLength
-            throws DependencyResolverException
+            ProjectBuildingRequest buildingRequest,
+            DependableCoordinate coordinate,
+            TransformableFilter dependencyFilter ) throws DependencyResolverException
     {
         ArtifactTypeRegistry typeRegistry = createTypeRegistry();
 
@@ -114,21 +120,19 @@ class Maven31DependencyResolver implements MavenDependencyResolver
 
         CollectRequest request = new CollectRequest( aetherRoot, aetherRepositories );
 
-        return resolveDependencies( dependencyFilter, request );
+        return resolveDependencies( buildingRequest, dependencyFilter, request );
     }
 
     private ArtifactTypeRegistry createTypeRegistry() throws DependencyResolverException
     {
-        return Invoker.invoke( RepositoryUtils.class, "newArtifactTypeRegistry", ArtifactHandlerManager.class,
-                artifactHandlerManager );
+        return RepositoryUtils.newArtifactTypeRegistry( artifactHandlerManager );
     }
 
     @Override
-    // CHECKSTYLE_OFF: LineLength
-    public Iterable<org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult> resolveDependencies( Model model,
-            TransformableFilter dependencyFilter )
-        // CHECKSTYLE_ON: LineLength
-            throws DependencyResolverException
+    public Iterable<org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult> resolveDependencies(
+            ProjectBuildingRequest buildingRequest,
+            Model model,
+            TransformableFilter dependencyFilter ) throws DependencyResolverException
     {
         // Are there examples where packaging and type are NOT in sync
         ArtifactHandler artifactHandler = artifactHandlerManager.getArtifactHandler( model.getPackaging() );
@@ -150,7 +154,7 @@ class Maven31DependencyResolver implements MavenDependencyResolver
             request.setManagedDependencies( resolveDependencies( model.getDependencyManagement().getDependencies() ) );
         }
 
-        return resolveDependencies( dependencyFilter, request );
+        return resolveDependencies( buildingRequest, dependencyFilter, request );
     }
 
     /**
@@ -183,6 +187,7 @@ class Maven31DependencyResolver implements MavenDependencyResolver
     @Override
     // CHECKSTYLE_OFF: LineLength
     public Iterable<org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult> resolveDependencies(
+            ProjectBuildingRequest buildingRequest,
             Collection<org.apache.maven.model.Dependency> mavenDependencies,
             Collection<org.apache.maven.model.Dependency> managedMavenDependencies, TransformableFilter filter )
         // CHECKSTYLE_ON: LineLength
@@ -195,12 +200,12 @@ class Maven31DependencyResolver implements MavenDependencyResolver
 
         CollectRequest request = new CollectRequest( aetherDeps, aetherManagedDependencies, aetherRepositories );
 
-        return resolveDependencies( filter, request );
+        return resolveDependencies( buildingRequest, filter, request );
     }
 
     // CHECKSTYLE_OFF: LineLength
     private Iterable<org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult> resolveDependencies(
-            TransformableFilter dependencyFilter, CollectRequest request ) throws DependencyResolverException
+        ProjectBuildingRequest buildingRequest, TransformableFilter dependencyFilter, CollectRequest request ) throws DependencyResolverException
     // CHECKSTYLE_ON: LineLength
     {
         try
@@ -213,7 +218,9 @@ class Maven31DependencyResolver implements MavenDependencyResolver
 
             DependencyRequest depRequest = new DependencyRequest( request, depFilter );
 
-            final DependencyResult dependencyResults = repositorySystem.resolveDependencies( session, depRequest );
+            final DependencyResult dependencyResults = repositorySystem.resolveDependencies(
+                buildingRequest.getRepositorySession(), depRequest
+            );
 
             // Keep it lazy! Often artifactsResults aren't used, so transforming up front is too expensive
             return new Iterable<org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult>()
diff --git a/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/MavenDependencyResolver.java b/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/MavenDependencyResolver.java
deleted file mode 100644
index 8652207..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/dependencies/resolve/internal/MavenDependencyResolver.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.apache.maven.shared.transfer.dependencies.resolve.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.Collection;
-
-import org.apache.maven.model.Dependency;
-import org.apache.maven.model.Model;
-import org.apache.maven.shared.artifact.filter.resolve.TransformableFilter;
-import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult;
-import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
-import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException;
-
-/**
- * 
- * @author Robert Scholte
- *
- */
-interface MavenDependencyResolver
-{
-
-    Iterable<ArtifactResult> resolveDependencies( DependableCoordinate coordinate,
-                                                  TransformableFilter dependencyFilter )
-        throws DependencyResolverException;
-
-    Iterable<ArtifactResult> resolveDependencies( Model model, TransformableFilter dependencyFilter )
-        throws DependencyResolverException;
-
-    Iterable<ArtifactResult> resolveDependencies( Collection<Dependency> mavenDependencies,
-                                                  Collection<Dependency> managedMavenDependencies,
-                                                  TransformableFilter filter )
-        throws DependencyResolverException;
-
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/MavenArtifactDeployer.java b/src/main/java/org/apache/maven/shared/transfer/internal/ComponentSupport.java
similarity index 54%
rename from src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/MavenArtifactDeployer.java
rename to src/main/java/org/apache/maven/shared/transfer/internal/ComponentSupport.java
index 8f9fea1..51df1b9 100644
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/deploy/internal/MavenArtifactDeployer.java
+++ b/src/main/java/org/apache/maven/shared/transfer/internal/ComponentSupport.java
@@ -1,4 +1,4 @@
-package org.apache.maven.shared.transfer.artifact.deploy.internal;
+package org.apache.maven.shared.transfer.internal;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,24 +19,32 @@ package org.apache.maven.shared.transfer.artifact.deploy.internal;
  * under the License.
  */
 
-import java.util.Collection;
+import java.util.Objects;
 
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployerException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
- * 
- * @author Robert Scholte
- *
+ * Support class for components.
  */
-interface MavenArtifactDeployer
+public abstract class ComponentSupport
 {
+    private static final String GUICE_ENHANCED = "$$EnhancerByGuice$$";
 
-    void deploy( Collection<Artifact> mavenArtifacts )
-        throws ArtifactDeployerException;
+    public static Logger getLogger( final Class<?> type )
+    {
+        Objects.requireNonNull( type );
+        if (type.getName().contains(GUICE_ENHANCED))
+        {
+            return LoggerFactory.getLogger(type.getSuperclass());
+        }
+        return LoggerFactory.getLogger(type);
+    }
 
-    void deploy( ArtifactRepository remoteRepository, Collection<Artifact> mavenArtifacts )
-        throws ArtifactDeployerException;
+    protected final Logger logger;
 
+    protected ComponentSupport()
+    {
+        this.logger = getLogger( getClass() );
+    }
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/MavenArtifactInstaller.java b/src/main/java/org/apache/maven/shared/transfer/internal/Delegator.java
similarity index 63%
copy from src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/MavenArtifactInstaller.java
copy to src/main/java/org/apache/maven/shared/transfer/internal/Delegator.java
index 6d6509d..7de2bab 100644
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/MavenArtifactInstaller.java
+++ b/src/main/java/org/apache/maven/shared/transfer/internal/Delegator.java
@@ -1,4 +1,4 @@
-package org.apache.maven.shared.transfer.artifact.install.internal;
+package org.apache.maven.shared.transfer.internal;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,18 +19,24 @@ package org.apache.maven.shared.transfer.artifact.install.internal;
  * under the License.
  */
 
-import java.util.Collection;
-
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.shared.transfer.artifact.install.ArtifactInstallerException;
+import java.util.Map;
+import java.util.Objects;
 
 /**
- * 
- * @author Robert Scholte
- *
+ * Delegating helper.
  */
-interface MavenArtifactInstaller
+public abstract class Delegator<D>
+    extends ComponentSupport
 {
-    void install( Collection<Artifact> mavenArtifacts )
-        throws ArtifactInstallerException;
+    private final Map<String, D> delegates;
+
+    protected Delegator( final Map<String, D> delegates )
+    {
+        this.delegates = Objects.requireNonNull( delegates );
+    }
+
+    protected D selectDelegate()
+    {
+        return delegates.get( Selector.selectedMaven() );
+    }
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/repository/internal/Maven302RepositoryManager.java b/src/main/java/org/apache/maven/shared/transfer/internal/Selector.java
similarity index 50%
rename from src/main/java/org/apache/maven/shared/transfer/repository/internal/Maven302RepositoryManager.java
rename to src/main/java/org/apache/maven/shared/transfer/internal/Selector.java
index 29178f4..866aaa2 100644
--- a/src/main/java/org/apache/maven/shared/transfer/repository/internal/Maven302RepositoryManager.java
+++ b/src/main/java/org/apache/maven/shared/transfer/internal/Selector.java
@@ -1,4 +1,4 @@
-package org.apache.maven.shared.transfer.repository.internal;
+package org.apache.maven.shared.transfer.internal;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,37 +19,36 @@ package org.apache.maven.shared.transfer.repository.internal;
  * under the License.
  */
 
-import org.sonatype.aether.RepositorySystem;
-import org.sonatype.aether.RepositorySystemSession;
-import org.sonatype.aether.repository.LocalRepository;
-
 /**
- * 
+ * Maven version selector helper.
  */
-class Maven302RepositoryManager
-    extends Maven30RepositoryManager
+public final class Selector
 {
-    Maven302RepositoryManager( RepositorySystem repositorySystem, RepositorySystemSession session )
+    public static final String MAVEN_3_0 = "maven-3.0";
+
+    public static final String MAVEN_3_1 = "maven-3.1";
+
+    public static final String MAVEN_4_0 = "maven-4.0";
+
+    public static String selectedMaven()
     {
-        super( repositorySystem, session );
+        return MAVEN_3_1; // TODO: add logic here. Maven3.0 should fail with meaningful error as "not supported"
     }
 
     /**
-     * Aether-1.9+ (i.e. M3.0.2+) expects "default", not "enhanced" as repositoryType
+     * Returns {@code true} if the current Maven version is Maven 3.1.
      */
-    @Override
-    protected String resolveRepositoryType( LocalRepository localRepository )
+    private static boolean isMaven31()
     {
-        String repositoryType;
-        if ( "enhanced".equals( localRepository.getContentType() ) )
+        try
         {
-            repositoryType = "default";
+            // Maven 3.1 specific
+            Thread.currentThread().getContextClassLoader().loadClass( "org.eclipse.aether.artifact.Artifact" );
+            return true;
         }
-        else
+        catch ( ClassNotFoundException e )
         {
-            // this should be "simple"
-            repositoryType = localRepository.getContentType();
+            return false;
         }
-        return repositoryType;
     }
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/metadata/internal/Maven30MetadataBridge.java b/src/main/java/org/apache/maven/shared/transfer/metadata/internal/Maven30MetadataBridge.java
deleted file mode 100644
index fde00a8..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/metadata/internal/Maven30MetadataBridge.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package org.apache.maven.shared.transfer.metadata.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.io.File;
-
-import org.apache.maven.artifact.metadata.ArtifactMetadata;
-import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
-import org.sonatype.aether.metadata.Metadata;
-
-/**
- * A MetadataBridge for Maven 3.0
- * 
- * @author Robert Scholte
- *
- */
-public class Maven30MetadataBridge implements Metadata
-{
-    private ArtifactMetadata metadata;
-    
-    private File file;
-
-    public Maven30MetadataBridge( ArtifactMetadata metadata )
-    {
-        this.metadata = metadata;
-    }
-
-    @Override
-    public String getGroupId()
-    {
-        return emptify( metadata.getGroupId() );
-    }
-
-    @Override
-    public String getArtifactId()
-    {
-        return metadata.storedInGroupDirectory() ? "" : emptify( metadata.getArtifactId() );
-    }
-
-    @Override
-    public String getVersion()
-    {
-        return metadata.storedInArtifactVersionDirectory() ? emptify( metadata.getBaseVersion() ) : "";
-    }
-
-    @Override
-    public String getType()
-    {
-        return metadata.getRemoteFilename();
-    }
-
-    private String emptify( String string )
-    {
-        return ( string != null ) ? string : "";
-    }
-
-    @Override
-    public File getFile()
-    {
-        return file;
-    }
-    
-    @Override
-    public Maven30MetadataBridge setFile( File file )
-    {
-        this.file = file;
-        return this;
-    }
-
-    @Override
-    public Nature getNature()
-    {
-        if ( metadata instanceof RepositoryMetadata )
-        {
-            switch ( ( (RepositoryMetadata) metadata ).getNature() )
-            {
-                case RepositoryMetadata.RELEASE_OR_SNAPSHOT:
-                    return Nature.RELEASE_OR_SNAPSHOT;
-                case RepositoryMetadata.SNAPSHOT:
-                    return Nature.SNAPSHOT;
-                default:
-                    return Nature.RELEASE;
-            }
-        }
-        else
-        {
-            return Nature.RELEASE;
-        }
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/project/MavenAetherUtils.java b/src/main/java/org/apache/maven/shared/transfer/project/MavenAetherUtils.java
deleted file mode 100644
index ccaee94..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/project/MavenAetherUtils.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package org.apache.maven.shared.transfer.project;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import org.codehaus.plexus.classworlds.realm.ClassRealm;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This util class will import the Aether library available from the installed Maven distribution. It will do nothing if
- * it is called from outside of a ClassRealm.
- *
- * @since 0.11.1
- * @author Gabriel Belingueres <a href="mailto:belingueres@gmail.com">belingueres@gmail.com</a>
- */
-public class MavenAetherUtils
-{
-
-    private static final Logger LOGGER = LoggerFactory.getLogger( MavenAetherUtils.class );
-
-    private static final String NO_SUCH_REALM_EXCEPTION = "org.codehaus.plexus.classworlds.realm.NoSuchRealmException";
-
-    /**
-     * Import the core Aether library from the maven distribution.
-     */
-    public static void importAetherLibrary()
-    {
-        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-        if ( isClassRealm( classLoader ) )
-        {
-            importAether( classLoader );
-        }
-    }
-
-    /**
-     * Imports aether-util library from the user's Maven distribution.
-     * <p>
-     * PRECONDITION: the classLoader parameter is an instance of ClassRealm.
-     * </p>
-     *
-     * @param classLoader the Classloader which needs to access aether-util.
-     */
-    private static void importAether( ClassLoader classLoader )
-    {
-        ClassRealm classRealm = (ClassRealm) classLoader;
-        try
-        {
-            classRealm.importFrom( "plexus.core", "org.eclipse.aether.util" );
-        }
-        catch ( Exception e )
-        {
-            if ( NO_SUCH_REALM_EXCEPTION.equals( e.getClass().getCanonicalName() ) )
-            {
-                LOGGER.info( "'plexus.core' ClassRealm could not be found. "
-                    + "Ignore this message if you are using the library outside of a Maven execution.", e );
-            }
-            else
-            {
-                // another exception
-                LOGGER.error( "Unexpected exception when importing Aether library to the '{}' ClassRealm", classLoader,
-                              e );
-            }
-        }
-    }
-
-    /**
-     * Using reflection, check if the Classloader is actually an instance of a ClassRealm.
-     *
-     * @param classLoader the Classloader to test.
-     * @return true if it an instance of ClassRealm; false otherwise.
-     */
-    private static boolean isClassRealm( ClassLoader classLoader )
-    {
-        for ( Class<?> clazz = classLoader.getClass(); clazz != null; clazz = clazz.getSuperclass() )
-        {
-            if ( "org.codehaus.plexus.classworlds.realm.ClassRealm".equals( clazz.getCanonicalName() ) )
-            {
-                return true;
-            }
-        }
-        return false;
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/project/deploy/internal/DefaultProjectDeployer.java b/src/main/java/org/apache/maven/shared/transfer/project/deploy/internal/DefaultProjectDeployer.java
index 16d1d1b..f54050a 100644
--- a/src/main/java/org/apache/maven/shared/transfer/project/deploy/internal/DefaultProjectDeployer.java
+++ b/src/main/java/org/apache/maven/shared/transfer/project/deploy/internal/DefaultProjectDeployer.java
@@ -23,6 +23,11 @@ import java.io.File;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.Objects;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
 
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.repository.ArtifactRepository;
@@ -30,6 +35,7 @@ import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.project.artifact.ProjectArtifactMetadata;
 import org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployer;
 import org.apache.maven.shared.transfer.artifact.deploy.ArtifactDeployerException;
+import org.apache.maven.shared.transfer.internal.ComponentSupport;
 import org.apache.maven.shared.transfer.project.NoFileAssignedException;
 import org.apache.maven.shared.transfer.project.deploy.ProjectDeployer;
 import org.apache.maven.shared.transfer.project.deploy.ProjectDeployerRequest;
@@ -45,17 +51,23 @@ import org.slf4j.LoggerFactory;
  * @author Karl Heinz Marbaise <a href="mailto:khmarbaise@apache.org">khmarbaise@apache.org</a> Most of the code is
  *         taken from maven-deploy-plugin.
  */
-@Component( role = ProjectDeployer.class )
+@Singleton
+@Named
 class DefaultProjectDeployer
+    extends ComponentSupport
     implements ProjectDeployer
 {
-    private static final Logger LOGGER = LoggerFactory.getLogger( DefaultProjectDeployer.class );
+    private final ArtifactDeployer deployer;
 
-    @Requirement
-    private ArtifactDeployer deployer;
+    private final RepositoryManager repositoryManager;
 
-    @Requirement
-    private RepositoryManager repositoryManager;
+    @Inject
+    public DefaultProjectDeployer(final ArtifactDeployer deployer,
+                                  final RepositoryManager repositoryManager)
+    {
+        this.deployer = Objects.requireNonNull( deployer );
+        this.repositoryManager = Objects.requireNonNull( repositoryManager );
+    }
 
     /**
      * {@inheritDoc}
@@ -155,7 +167,7 @@ class DefaultProjectDeployer
             {
                 if ( count > 0 )
                 {
-                    LOGGER.info( "Retrying deployment attempt " + ( count + 1 ) + " of "
+                    logger.info( "Retrying deployment attempt " + ( count + 1 ) + " of "
                         + retryFailedDeploymentCounter );
                 }
 
@@ -167,8 +179,8 @@ class DefaultProjectDeployer
             {
                 if ( count + 1 < retryFailedDeploymentCounter )
                 {
-                    LOGGER.warn( "Encountered issue during deployment: " + e.getLocalizedMessage() );
-                    LOGGER.debug( e.getMessage() );
+                    logger.warn( "Encountered issue during deployment: " + e.getLocalizedMessage() );
+                    logger.debug( e.getMessage() );
                 }
                 if ( exception == null )
                 {
diff --git a/src/main/java/org/apache/maven/shared/transfer/project/install/internal/DefaultProjectInstaller.java b/src/main/java/org/apache/maven/shared/transfer/project/install/internal/DefaultProjectInstaller.java
index 675b55c..1205c0a 100644
--- a/src/main/java/org/apache/maven/shared/transfer/project/install/internal/DefaultProjectInstaller.java
+++ b/src/main/java/org/apache/maven/shared/transfer/project/install/internal/DefaultProjectInstaller.java
@@ -25,6 +25,11 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Objects;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
 
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.metadata.ArtifactMetadata;
@@ -34,32 +39,34 @@ import org.apache.maven.project.artifact.ProjectArtifact;
 import org.apache.maven.project.artifact.ProjectArtifactMetadata;
 import org.apache.maven.shared.transfer.artifact.install.ArtifactInstaller;
 import org.apache.maven.shared.transfer.artifact.install.ArtifactInstallerException;
+import org.apache.maven.shared.transfer.internal.ComponentSupport;
 import org.apache.maven.shared.transfer.project.NoFileAssignedException;
 import org.apache.maven.shared.transfer.project.install.ProjectInstaller;
 import org.apache.maven.shared.transfer.project.install.ProjectInstallerRequest;
 import org.apache.maven.shared.transfer.repository.RepositoryManager;
-import org.codehaus.plexus.component.annotations.Component;
-import org.codehaus.plexus.component.annotations.Requirement;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * This will install a whole project into the appropriate repository.
  * 
  * @author Karl Heinz Marbaise <a href="mailto:khmarbaise@apache.org">khmarbaise@apache.org</a>
  */
-@Component( role = ProjectInstaller.class )
-class DefaultProjectInstaller
+@Singleton
+@Named
+public class DefaultProjectInstaller
+    extends ComponentSupport
     implements ProjectInstaller
 {
+    private final ArtifactInstaller installer;
 
-    private static final Logger LOGGER = LoggerFactory.getLogger( DefaultProjectInstaller.class );
-
-    @Requirement
-    private ArtifactInstaller installer;
+    private final RepositoryManager repositoryManager;
 
-    @Requirement
-    private RepositoryManager repositoryManager;
+    @Inject
+    public DefaultProjectInstaller(final ArtifactInstaller installer,
+                                   final RepositoryManager repositoryManager)
+    {
+        this.installer = Objects.requireNonNull( installer );
+        this.repositoryManager = Objects.requireNonNull( repositoryManager );
+    }
 
     /**
      * {@inheritDoc}
@@ -126,7 +133,7 @@ class DefaultProjectInstaller
 
         for ( Artifact attached : attachedArtifacts )
         {
-            LOGGER.debug( "Installing artifact: {}", attached.getId() );
+            logger.debug( "Installing artifact: {}", attached.getId() );
             installer.install( buildingRequest, Collections.singletonList( attached ) );
             addMetaDataFilesForArtifact( buildingRequest, attached, metadataFiles );
         }
diff --git a/src/main/java/org/apache/maven/shared/transfer/repository/internal/DefaultRepositoryManager.java b/src/main/java/org/apache/maven/shared/transfer/repository/internal/DefaultRepositoryManager.java
index c29cc08..faee597 100644
--- a/src/main/java/org/apache/maven/shared/transfer/repository/internal/DefaultRepositoryManager.java
+++ b/src/main/java/org/apache/maven/shared/transfer/repository/internal/DefaultRepositoryManager.java
@@ -20,172 +20,64 @@ package org.apache.maven.shared.transfer.repository.internal;
  */
 
 import java.io.File;
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
 
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.metadata.ArtifactMetadata;
 import org.apache.maven.project.ProjectBuildingRequest;
-import org.apache.maven.project.artifact.ProjectArtifactMetadata;
 import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate;
-import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate;
+import org.apache.maven.shared.transfer.internal.Delegator;
 import org.apache.maven.shared.transfer.repository.RepositoryManager;
-import org.apache.maven.shared.transfer.repository.RepositoryManagerException;
-import org.codehaus.plexus.PlexusConstants;
-import org.codehaus.plexus.PlexusContainer;
-import org.codehaus.plexus.component.annotations.Component;
-import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
-import org.codehaus.plexus.context.Context;
-import org.codehaus.plexus.context.ContextException;
-import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
 
 /**
- * 
+ *
  */
-@Component( role = RepositoryManager.class )
+@Singleton
+@Named
 class DefaultRepositoryManager
-    implements RepositoryManager, Contextualizable 
+    extends Delegator<RepositoryManagerDelegate>
+    implements RepositoryManager
 {
-    private PlexusContainer container;
-    
-    @Override
-    public String getPathForLocalArtifact( ProjectBuildingRequest buildingRequest, Artifact artifact )
-    {
-        try
-        {
-            return getMavenRepositoryManager( buildingRequest ).getPathForLocalArtifact( artifact );
-        }
-        catch ( ComponentLookupException | RepositoryManagerException e )
-        {
-            throw new IllegalStateException( e.getMessage(), e );
-        }
-    }
-
-    @Override
-    public String getPathForLocalArtifact( ProjectBuildingRequest buildingRequest, ArtifactCoordinate coor )
-    {
-        try
-        {
-            return getMavenRepositoryManager( buildingRequest ).getPathForLocalArtifact( coor );
-        }
-        catch ( ComponentLookupException | RepositoryManagerException e )
-        {
-            throw new IllegalStateException( e.getMessage(), e );
-        }
-    }
-
-    @Override
-    public String getPathForLocalMetadata( ProjectBuildingRequest buildingRequest, ArtifactMetadata metadata )
-    {
-        if ( metadata instanceof ProjectArtifactMetadata )
-        {
-            DefaultArtifactCoordinate pomCoordinate = new DefaultArtifactCoordinate();
-            pomCoordinate.setGroupId( metadata.getGroupId() );
-            pomCoordinate.setArtifactId( metadata.getArtifactId() );
-            pomCoordinate.setVersion( metadata.getBaseVersion() );
-            pomCoordinate.setExtension( "pom" );
-            return getPathForLocalArtifact( buildingRequest, pomCoordinate );
-        }
-
-        try
-        {
-            return getMavenRepositoryManager( buildingRequest ).getPathForLocalMetadata( metadata );
-        }
-        catch ( ComponentLookupException | RepositoryManagerException e )
-        {
-            throw new IllegalStateException( e.getMessage(), e );
-        }
-    }
-
-    @Override
-    public ProjectBuildingRequest setLocalRepositoryBasedir( ProjectBuildingRequest buildingRequest, File basedir )
-    {
-        try
-        {
-            return getMavenRepositoryManager( buildingRequest ).setLocalRepositoryBasedir( buildingRequest, basedir );
-        }
-        catch ( ComponentLookupException | RepositoryManagerException e )
-        {
-            throw new IllegalStateException( e.getMessage(), e );
-        }
-    }
-
-    @Override
-    public File getLocalRepositoryBasedir( ProjectBuildingRequest buildingRequest )
-    {
-        try
-        {
-            return getMavenRepositoryManager( buildingRequest ).getLocalRepositoryBasedir();
-        }
-        catch ( ComponentLookupException | RepositoryManagerException e )
-        {
-            throw new IllegalStateException( e.getMessage(), e );
-        }
-    }
-
-    /**
-     * @return true if the current Maven version is Maven 3.1.
-     */
-    private boolean isMaven31()
-    {
-        return canFindCoreClass( "org.eclipse.aether.artifact.Artifact" ); // Maven 3.1 specific
-    }
-
-    /**
-     * @return true if the current Maven version is Maven 3.0.2
-     */
-    private boolean isMaven302()
-    {
-        return canFindCoreClass( "org.sonatype.aether.spi.localrepo.LocalRepositoryManagerFactory" );
-    }
-
-    private boolean canFindCoreClass( String className )
-    {
-        try
-        {
-            Thread.currentThread().getContextClassLoader().loadClass( className );
-
-            return true;
-        }
-        catch ( ClassNotFoundException e )
-        {
-            return false;
-        }
-    }
-    
-    private MavenRepositoryManager getMavenRepositoryManager( ProjectBuildingRequest buildingRequest )
-        throws ComponentLookupException, RepositoryManagerException
-    {
-        if ( isMaven31() )
-        {
-            org.eclipse.aether.RepositorySystem m31RepositorySystem =
-                            container.lookup( org.eclipse.aether.RepositorySystem.class );
-
-            org.eclipse.aether.RepositorySystemSession session = Invoker.invoke( buildingRequest,
-                    "getRepositorySession" );
-
-            return new Maven31RepositoryManager( m31RepositorySystem, session );
-        }
-        else
-        {
-            org.sonatype.aether.RepositorySystem m30RepositorySystem =
-                container.lookup( org.sonatype.aether.RepositorySystem.class );
-
-            org.sonatype.aether.RepositorySystemSession session = Invoker.invoke( buildingRequest,
-                    "getRepositorySession" );
-            
-            if ( isMaven302() )
-            {
-                return new Maven302RepositoryManager( m30RepositorySystem, session );
-                
-            }
-            else
-            {
-                return new Maven30RepositoryManager( m30RepositorySystem, session );
-            }
-        }
-    }
-    
-    public void contextualize( Context context ) throws ContextException
-    {
-        container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
-    }
+  private final RepositoryManagerDelegate delegate;
+
+  @Inject
+  public DefaultRepositoryManager(final Map<String, RepositoryManagerDelegate> delegates) {
+    super(delegates);
+    this.delegate = selectDelegate();
+  }
+
+  @Override
+  public String getPathForLocalArtifact(final ProjectBuildingRequest buildingRequest,
+                                        final Artifact artifact)
+  {
+    return delegate.getPathForLocalArtifact(buildingRequest, artifact);
+  }
+
+  @Override
+  public String getPathForLocalArtifact(final ProjectBuildingRequest buildingRequest,
+                                        final ArtifactCoordinate coordinate)
+  {
+    return delegate.getPathForLocalArtifact(buildingRequest, coordinate);
+  }
+
+  @Override
+  public String getPathForLocalMetadata(final ProjectBuildingRequest buildingRequest,
+                                        final ArtifactMetadata metadata)
+  {
+    return delegate.getPathForLocalMetadata(buildingRequest, metadata);
+  }
+
+  @Override
+  public ProjectBuildingRequest setLocalRepositoryBasedir(final ProjectBuildingRequest request, final File basedir) {
+    return delegate.setLocalRepositoryBasedir(request, basedir);
+  }
+
+  @Override
+  public File getLocalRepositoryBasedir(final ProjectBuildingRequest request) {
+    return delegate.getLocalRepositoryBasedir(request);
+  }
 }
diff --git a/src/main/java/org/apache/maven/shared/transfer/repository/internal/Invoker.java b/src/main/java/org/apache/maven/shared/transfer/repository/internal/Invoker.java
deleted file mode 100644
index 48342dc..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/repository/internal/Invoker.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package org.apache.maven.shared.transfer.repository.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.lang.reflect.InvocationTargetException;
-
-import org.apache.maven.shared.transfer.repository.RepositoryManagerException;
-
-/**
- * Invokes method on objects using reflection.
- */
-final class Invoker
-{
-    private Invoker()
-    {
-        // do not instantiate
-    }
-
-    public static <T> T invoke( Object object, String method )
-        throws RepositoryManagerException
-    {
-        try
-        {
-            @SuppressWarnings( "unchecked" )
-            T invoke = (T) object.getClass().getMethod( method ).invoke( object );
-            return invoke;
-        }
-        catch ( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
-        {
-            throw new RepositoryManagerException( e.getMessage(), e );
-        }
-    }
-
-    public static <T> T invoke( Object object, String method, Class<?> argClazz, Object arg )
-        throws RepositoryManagerException
-    {
-        try
-        {
-            final Class<?> objectClazz = object.getClass();
-            @SuppressWarnings( "unchecked" )
-            T invoke = (T) objectClazz.getMethod( method, argClazz ).invoke( object, arg );
-            return invoke;
-        }
-        catch ( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
-        {
-            throw new RepositoryManagerException( e.getMessage(), e );
-        }
-    }
-
-    public static Object invoke( Class<?> objectClazz, String staticMethod, Class<?> argClazz, Object arg )
-        throws RepositoryManagerException
-    {
-        try
-        {
-            return objectClazz.getMethod( staticMethod, argClazz ).invoke( null, arg );
-        }
-        catch ( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
-        {
-            throw new RepositoryManagerException( e.getMessage(), e );
-        }
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/repository/internal/Maven30RepositoryManager.java b/src/main/java/org/apache/maven/shared/transfer/repository/internal/Maven30RepositoryManager.java
deleted file mode 100644
index b7b9214..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/repository/internal/Maven30RepositoryManager.java
+++ /dev/null
@@ -1,172 +0,0 @@
-package org.apache.maven.shared.transfer.repository.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.io.File;
-
-import org.apache.maven.RepositoryUtils;
-import org.apache.maven.artifact.metadata.ArtifactMetadata;
-import org.apache.maven.project.DefaultProjectBuildingRequest;
-import org.apache.maven.project.ProjectBuildingRequest;
-import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate;
-import org.apache.maven.shared.transfer.repository.RepositoryManagerException;
-import org.sonatype.aether.RepositorySystem;
-import org.sonatype.aether.RepositorySystemSession;
-import org.sonatype.aether.artifact.Artifact;
-import org.sonatype.aether.metadata.Metadata;
-import org.sonatype.aether.metadata.Metadata.Nature;
-import org.sonatype.aether.repository.LocalRepository;
-import org.sonatype.aether.repository.LocalRepositoryManager;
-import org.sonatype.aether.util.DefaultRepositoryCache;
-import org.sonatype.aether.util.DefaultRepositorySystemSession;
-import org.sonatype.aether.util.artifact.DefaultArtifact;
-import org.sonatype.aether.util.metadata.DefaultMetadata;
-
-/**
- * 
- */
-class Maven30RepositoryManager
-    implements MavenRepositoryManager
-{
-    private final RepositorySystem repositorySystem;
-
-    private final RepositorySystemSession session;
-    
-    Maven30RepositoryManager( RepositorySystem repositorySystem, RepositorySystemSession session )
-    {
-        this.repositorySystem = repositorySystem;
-        this.session = session;
-    }
-
-    @Override
-    public String getPathForLocalArtifact( org.apache.maven.artifact.Artifact mavenArtifact )
-    {
-        Artifact aetherArtifact;
-
-        // LRM.getPathForLocalArtifact() won't throw an Exception, so translate reflection error to RuntimeException
-        try
-        {
-            aetherArtifact = (Artifact) Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                                                        org.apache.maven.artifact.Artifact.class, mavenArtifact );
-        }
-        catch ( RepositoryManagerException e )
-        {
-            throw new RuntimeException( e.getMessage(), e );
-        }
-
-        return session.getLocalRepositoryManager().getPathForLocalArtifact( aetherArtifact );
-    }
-
-    @Override
-    public String getPathForLocalArtifact( ArtifactCoordinate coordinate )
-    {
-        Artifact aetherArtifact = toArtifact( coordinate );
-
-        // LRM.getPathForLocalArtifact() won't throw an Exception, so translate reflection error to RuntimeException
-
-        return session.getLocalRepositoryManager().getPathForLocalArtifact( aetherArtifact );
-    }
-
-    @Override
-    public String getPathForLocalMetadata( ArtifactMetadata metadata )
-    {
-        Metadata aetherMetadata =
-            new DefaultMetadata( metadata.getGroupId(),
-                                 metadata.storedInGroupDirectory() ? null : metadata.getArtifactId(),
-                                 metadata.storedInArtifactVersionDirectory() ? metadata.getBaseVersion() : null,
-                                 "maven-metadata.xml", Nature.RELEASE_OR_SNAPSHOT );
-
-        return session.getLocalRepositoryManager().getPathForLocalMetadata( aetherMetadata );
-    }
-    
-    @Override
-    public ProjectBuildingRequest setLocalRepositoryBasedir( ProjectBuildingRequest buildingRequest, File basedir )
-    {
-        ProjectBuildingRequest newRequest = new DefaultProjectBuildingRequest( buildingRequest );
-
-        RepositorySystemSession session;
-        try
-        {
-            session = Invoker.invoke( buildingRequest, "getRepositorySession" );
-        }
-        catch ( RepositoryManagerException e )
-        {
-            throw new RuntimeException( e.getMessage(), e );
-        }
-
-        // "clone" session and replace localRepository
-        DefaultRepositorySystemSession newSession = new DefaultRepositorySystemSession( session );
-
-        // Clear cache, since we're using a new local repository
-        newSession.setCache( new DefaultRepositoryCache() );
-
-        // keep same repositoryType
-        String repositoryType = resolveRepositoryType( session.getLocalRepository() );
-
-        LocalRepositoryManager localRepositoryManager =
-            repositorySystem.newLocalRepositoryManager( new LocalRepository( basedir, repositoryType ) );
-
-        newSession.setLocalRepositoryManager( localRepositoryManager );
-
-        try
-        {
-            Invoker.invoke( newRequest, "setRepositorySession", RepositorySystemSession.class, newSession );
-        }
-        catch ( RepositoryManagerException e )
-        {
-            throw new RuntimeException( e.getMessage(), e );
-        }
-
-        return newRequest;
-    }
-
-    @Override
-    public File getLocalRepositoryBasedir()
-    {
-        return session.getLocalRepository().getBasedir();
-    }
-
-    /**
-     * @param localRepository {@link LocalRepository}
-     * @return the resolved type.
-     */
-    protected String resolveRepositoryType( LocalRepository localRepository )
-    {
-        return localRepository.getContentType();
-    }
-
-    /**
-     * @param coordinate {@link ArtifactCoordinate}
-     * @return {@link Artifact}
-     */
-    protected Artifact toArtifact( ArtifactCoordinate coordinate )
-    {
-        if ( coordinate == null )
-        {
-            return null;
-        }
-
-        Artifact result =
-            new DefaultArtifact( coordinate.getGroupId(), coordinate.getArtifactId(), coordinate.getClassifier(),
-                                 coordinate.getExtension(), coordinate.getVersion() );
-
-        return result;
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/repository/internal/Maven31RepositoryManager.java b/src/main/java/org/apache/maven/shared/transfer/repository/internal/Maven31RepositoryManager.java
index 6f486a0..ba80cf1 100644
--- a/src/main/java/org/apache/maven/shared/transfer/repository/internal/Maven31RepositoryManager.java
+++ b/src/main/java/org/apache/maven/shared/transfer/repository/internal/Maven31RepositoryManager.java
@@ -20,12 +20,19 @@ package org.apache.maven.shared.transfer.repository.internal;
  */
 
 import java.io.File;
+import java.util.Objects;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
 
 import org.apache.maven.RepositoryUtils;
 import org.apache.maven.artifact.metadata.ArtifactMetadata;
 import org.apache.maven.project.DefaultProjectBuildingRequest;
 import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate;
+import org.apache.maven.shared.transfer.internal.Selector;
+import org.apache.maven.shared.transfer.repository.RepositoryManager;
 import org.apache.maven.shared.transfer.repository.RepositoryManagerException;
 import org.eclipse.aether.DefaultRepositoryCache;
 import org.eclipse.aether.DefaultRepositorySystemSession;
@@ -42,73 +49,57 @@ import org.eclipse.aether.repository.LocalRepositoryManager;
 /**
  * 
  */
-class Maven31RepositoryManager
-    implements MavenRepositoryManager
+@Singleton
+@Named( Selector.MAVEN_3_1 )
+public final class Maven31RepositoryManager
+    implements RepositoryManagerDelegate
 {
     private final RepositorySystem repositorySystem;
 
-    private final RepositorySystemSession session;
-
-    Maven31RepositoryManager( RepositorySystem repositorySystem, 
-                              RepositorySystemSession session )
+    @Inject
+    public Maven31RepositoryManager( final RepositorySystem repositorySystem )
     {
-        this.repositorySystem = repositorySystem;
-        this.session = session;
+        this.repositorySystem = Objects.requireNonNull( repositorySystem );
     }
 
     @Override
-    public String getPathForLocalArtifact( org.apache.maven.artifact.Artifact mavenArtifact )
+    public String getPathForLocalArtifact( final ProjectBuildingRequest buildingRequest,
+                                           final org.apache.maven.artifact.Artifact artifact )
     {
-        Artifact aetherArtifact;
-
-        // LRM.getPathForLocalArtifact() won't throw an Exception, so translate reflection error to RuntimeException
-        try
-        {
-            aetherArtifact = (Artifact) Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                                                        org.apache.maven.artifact.Artifact.class, mavenArtifact );
-        }
-        catch ( RepositoryManagerException e )
-        {
-            throw new RuntimeException( e.getMessage(), e );
-        }
-
-        return session.getLocalRepositoryManager().getPathForLocalArtifact( aetherArtifact );
+        Artifact aetherArtifact = RepositoryUtils.toArtifact( artifact );
+        return buildingRequest.getRepositorySession()
+            .getLocalRepositoryManager().getPathForLocalArtifact( aetherArtifact );
     }
 
     @Override
-    public String getPathForLocalArtifact( ArtifactCoordinate coordinate )
+    public String getPathForLocalArtifact( final ProjectBuildingRequest buildingRequest,
+                                           final ArtifactCoordinate coordinate )
     {
         Artifact aetherArtifact = toArtifact( coordinate );
-
-        return session.getLocalRepositoryManager().getPathForLocalArtifact( aetherArtifact );
+        return buildingRequest.getRepositorySession()
+            .getLocalRepositoryManager().getPathForLocalArtifact( aetherArtifact );
     }
-    
+
     @Override
-    public String getPathForLocalMetadata( ArtifactMetadata metadata )
+    public String getPathForLocalMetadata( final ProjectBuildingRequest buildingRequest,
+                                           final ArtifactMetadata metadata )
     {
         Metadata aetherMetadata =
             new DefaultMetadata( metadata.getGroupId(),
-                                 metadata.storedInGroupDirectory() ? null : metadata.getArtifactId(),
-                                 metadata.storedInArtifactVersionDirectory() ? metadata.getBaseVersion() : null,
-                                 "maven-metadata.xml", Nature.RELEASE_OR_SNAPSHOT );
+                metadata.storedInGroupDirectory() ? null : metadata.getArtifactId(),
+                metadata.storedInArtifactVersionDirectory() ? metadata.getBaseVersion() : null,
+                "maven-metadata.xml", Nature.RELEASE_OR_SNAPSHOT );
 
-        return session.getLocalRepositoryManager().getPathForLocalMetadata( aetherMetadata );
+        return buildingRequest.getRepositorySession()
+            .getLocalRepositoryManager().getPathForLocalMetadata( aetherMetadata );
     }
 
     @Override
-    public ProjectBuildingRequest setLocalRepositoryBasedir( ProjectBuildingRequest buildingRequest, File basedir )
+    public ProjectBuildingRequest setLocalRepositoryBasedir( final ProjectBuildingRequest request, final File basedir )
     {
-        ProjectBuildingRequest newRequest = new DefaultProjectBuildingRequest( buildingRequest );
+        ProjectBuildingRequest newRequest = new DefaultProjectBuildingRequest( request );
 
-        RepositorySystemSession session;
-        try
-        {
-            session = Invoker.invoke( buildingRequest, "getRepositorySession" );
-        }
-        catch ( RepositoryManagerException e )
-        {
-            throw new RuntimeException( e.getMessage(), e );
-        }
+        RepositorySystemSession session = request.getRepositorySession();
 
         // "clone" session and replace localRepository
         DefaultRepositorySystemSession newSession = new DefaultRepositorySystemSession( session );
@@ -124,29 +115,22 @@ class Maven31RepositoryManager
 
         newSession.setLocalRepositoryManager( localRepositoryManager );
 
-        try
-        {
-            Invoker.invoke( newRequest, "setRepositorySession", RepositorySystemSession.class, newSession );
-        }
-        catch ( RepositoryManagerException e )
-        {
-            throw new RuntimeException( e.getMessage(), e );
-        }
+        newRequest.setRepositorySession( newSession );
 
         return newRequest;
     }
 
     @Override
-    public File getLocalRepositoryBasedir()
+    public File getLocalRepositoryBasedir(final ProjectBuildingRequest request)
     {
-        return session.getLocalRepository().getBasedir();
+        return request.getRepositorySession().getLocalRepository().getBasedir();
     }
 
     /**
      * @param localRepository {@link LocalRepository}
      * @return the resolved type.
      */
-    protected String resolveRepositoryType( LocalRepository localRepository )
+    private String resolveRepositoryType( LocalRepository localRepository )
     {
         String repositoryType;
         if ( "enhanced".equals( localRepository.getContentType() ) )
@@ -165,7 +149,7 @@ class Maven31RepositoryManager
      * @param coordinate {@link ArtifactCoordinate}
      * @return {@link Artifact}
      */
-    protected Artifact toArtifact( ArtifactCoordinate coordinate )
+    private Artifact toArtifact( ArtifactCoordinate coordinate )
     {
         if ( coordinate == null )
         {
diff --git a/src/main/java/org/apache/maven/shared/transfer/repository/internal/MavenRepositoryManager.java b/src/main/java/org/apache/maven/shared/transfer/repository/internal/MavenRepositoryManager.java
deleted file mode 100644
index e494b15..0000000
--- a/src/main/java/org/apache/maven/shared/transfer/repository/internal/MavenRepositoryManager.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package org.apache.maven.shared.transfer.repository.internal;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.io.File;
-
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.metadata.ArtifactMetadata;
-import org.apache.maven.project.ProjectBuildingRequest;
-import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate;
-
-/**
- * 
- * @author Robert Scholte
- */
-interface MavenRepositoryManager
-{
-    /**
-     * @param artifact {@link Artifact}
-     * @return the path of the local artifact.
-     */
-    String getPathForLocalArtifact( Artifact artifact );
-
-    /**
-     * @param coordinate {@link ArtifactCoordinate}
-     * @return the path for the local artifact.
-     */
-    String getPathForLocalArtifact( ArtifactCoordinate coordinate );
-    
-    /**
-     * @param metadata {@link ArtifactMetadata}
-     * @return the path of the local metadata.
-     */
-    String getPathForLocalMetadata( ArtifactMetadata metadata );
-
-    /**
-     * Create a new {@code ProjectBuildingRequest} with an adjusted repository session.
-     * 
-     * @param basedir the base directory of the local repository
-     * @return a new project building request
-     */
-    ProjectBuildingRequest setLocalRepositoryBasedir( ProjectBuildingRequest request, File basedir );
-
-    /**
-     * Get the localRepositryBasedir as specified in the repository session of the request
-     * 
-     * @return the local repository base directory
-     */
-    File getLocalRepositoryBasedir();
-}
diff --git a/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/MavenArtifactInstaller.java b/src/main/java/org/apache/maven/shared/transfer/repository/internal/RepositoryManagerDelegate.java
similarity index 68%
rename from src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/MavenArtifactInstaller.java
rename to src/main/java/org/apache/maven/shared/transfer/repository/internal/RepositoryManagerDelegate.java
index 6d6509d..606de03 100644
--- a/src/main/java/org/apache/maven/shared/transfer/artifact/install/internal/MavenArtifactInstaller.java
+++ b/src/main/java/org/apache/maven/shared/transfer/repository/internal/RepositoryManagerDelegate.java
@@ -1,4 +1,4 @@
-package org.apache.maven.shared.transfer.artifact.install.internal;
+package org.apache.maven.shared.transfer.repository.internal;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,18 +19,11 @@ package org.apache.maven.shared.transfer.artifact.install.internal;
  * under the License.
  */
 
-import java.util.Collection;
-
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.shared.transfer.artifact.install.ArtifactInstallerException;
+import org.apache.maven.shared.transfer.repository.RepositoryManager;
 
 /**
  * 
- * @author Robert Scholte
- *
  */
-interface MavenArtifactInstaller
+public interface RepositoryManagerDelegate extends RepositoryManager
 {
-    void install( Collection<Artifact> mavenArtifacts )
-        throws ArtifactInstallerException;
 }
diff --git a/src/test/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven30ArtifactInstallerTest.java b/src/test/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven30ArtifactInstallerTest.java
index 19d1939..b376e52 100644
--- a/src/test/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven30ArtifactInstallerTest.java
+++ b/src/test/java/org/apache/maven/shared/transfer/artifact/install/internal/Maven30ArtifactInstallerTest.java
@@ -28,7 +28,6 @@ import org.apache.maven.artifact.DefaultArtifact;
 import org.apache.maven.artifact.handler.DefaultArtifactHandler;
 import org.apache.maven.project.DefaultProjectBuildingRequest;
 import org.apache.maven.repository.internal.MavenRepositorySystemSession;
-import org.apache.maven.shared.transfer.artifact.install.internal.Maven30ArtifactInstaller;
 import org.codehaus.plexus.PlexusTestCase;
 import org.sonatype.aether.RepositorySystem;
 import org.sonatype.aether.impl.internal.SimpleLocalRepositoryManager;
diff --git a/src/test/java/org/apache/maven/shared/transfer/repository/internal/Maven30RepositoryManagerTest.java b/src/test/java/org/apache/maven/shared/transfer/repository/internal/Maven30RepositoryManagerTest.java
index 6e20cb4..de8d4d0 100644
--- a/src/test/java/org/apache/maven/shared/transfer/repository/internal/Maven30RepositoryManagerTest.java
+++ b/src/test/java/org/apache/maven/shared/transfer/repository/internal/Maven30RepositoryManagerTest.java
@@ -24,7 +24,6 @@ import java.io.File;
 import org.apache.maven.project.DefaultProjectBuildingRequest;
 import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.repository.internal.MavenRepositorySystemSession;
-import org.apache.maven.shared.transfer.repository.internal.Maven30RepositoryManager;
 import org.codehaus.plexus.PlexusTestCase;
 import org.sonatype.aether.RepositorySystem;
 import org.sonatype.aether.impl.internal.EnhancedLocalRepositoryManager;