diff --git a/pom.xml b/pom.xml
index 08fc42f..25c3ed1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -69,7 +69,7 @@
     <dependency>
       <groupId>org.apache.maven</groupId>
       <artifactId>maven-core</artifactId>
-      <version>3.0.5</version>
+      <version>3.2.5</version>
     </dependency>
     <dependency>
       <groupId>org.codehaus.plexus</groupId>
@@ -77,12 +77,6 @@
       <optional>true</optional>
     </dependency>
     <dependency>
-      <groupId>org.sonatype.aether</groupId>
-      <artifactId>aether-api</artifactId>
-      <version>1.13.1</version>
-      <optional>true</optional>
-    </dependency>
-    <dependency>
       <groupId>org.eclipse.aether</groupId>
       <artifactId>aether-api</artifactId>
       <version>1.1.0</version>
diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/DependencyCollectorBuilder.java b/src/main/java/org/apache/maven/shared/dependency/graph/DependencyCollectorBuilder.java
index 9ece96f..38e60e5 100644
--- a/src/main/java/org/apache/maven/shared/dependency/graph/DependencyCollectorBuilder.java
+++ b/src/main/java/org/apache/maven/shared/dependency/graph/DependencyCollectorBuilder.java
@@ -23,7 +23,7 @@
 import org.apache.maven.project.ProjectBuildingRequest;
 
 /**
- * Maven project dependency raw dependency collector API, providing an abstraction layer against Maven 3 and Maven 3.1+
+ * Maven project dependency raw dependency collector API, providing an abstraction layer against Maven 3.1+
  * particular Aether implementations.
  * 
  * @author Gabriel Belingueres
diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/DependencyGraphBuilder.java b/src/main/java/org/apache/maven/shared/dependency/graph/DependencyGraphBuilder.java
index cab4ce8..3c9c37e 100644
--- a/src/main/java/org/apache/maven/shared/dependency/graph/DependencyGraphBuilder.java
+++ b/src/main/java/org/apache/maven/shared/dependency/graph/DependencyGraphBuilder.java
@@ -26,7 +26,7 @@
 import java.util.Collection;
 
 /**
- * Maven project dependency graph builder API, neutral against Maven 2 or Maven 3.
+ * Maven project dependency graph builder API, neutral Maven 3.
  *
  * @author Hervé Boutemy
  * @since 2.0
diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyCollectorBuilder.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyCollectorBuilder.java
index cddf101..4f9db16 100644
--- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyCollectorBuilder.java
+++ b/src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyCollectorBuilder.java
@@ -20,7 +20,6 @@
  */
 
 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
-import org.apache.maven.execution.MavenSession;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.shared.dependency.graph.DependencyCollectorBuilder;
@@ -36,7 +35,7 @@
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
 
 /**
- * Default project dependency raw dependency collector API, providing an abstraction layer against Maven 3 and Maven
+ * Default project dependency raw dependency collector API, providing an abstraction layer against Maven
  * 3.1+ particular Aether implementations.
  * 
  * @author Gabriel Belingueres
@@ -55,17 +54,15 @@
     {
         try
         {
-            String hint = isMaven31() ? "maven31" : "maven3";
 
             DependencyCollectorBuilder effectiveGraphBuilder =
-                (DependencyCollectorBuilder) container.lookup( DependencyCollectorBuilder.class.getCanonicalName(),
-                                                               hint );
+                    container.lookup( DependencyCollectorBuilder.class, "maven31" );
 
             if ( getLogger().isDebugEnabled() )
             {
                 MavenProject project = buildingRequest.getProject();
 
-                getLogger().debug( "building " + hint + " RAW dependency tree for " + project.getId() + " with "
+                getLogger().debug( "building Maven 3.1+ RAW dependency tree for " + project.getId() + " with "
                     + effectiveGraphBuilder.getClass().getSimpleName() );
             }
 
@@ -78,23 +75,6 @@
     }
 
     /**
-     * @return true if the current Maven version is Maven 3.1.
-     */
-    protected static boolean isMaven31()
-    {
-        try
-        {
-            Class<?> repoSessionClass =  MavenSession.class.getMethod( "getRepositorySession" ).getReturnType();
-            
-            return "org.eclipse.aether.RepositorySystemSession".equals( repoSessionClass.getName() );
-        }
-        catch ( NoSuchMethodException e )
-        {
-            throw new IllegalStateException( "Cannot determine return type of MavenSession.getRepositorySession" );
-        }
-    }
-
-    /**
      * Injects the Plexus content.
      *
      * @param context Plexus context to inject.
diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyGraphBuilder.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyGraphBuilder.java
index 84f27f3..d183ba2 100644
--- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyGraphBuilder.java
+++ b/src/main/java/org/apache/maven/shared/dependency/graph/internal/DefaultDependencyGraphBuilder.java
@@ -20,7 +20,6 @@
  */
 
 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
-import org.apache.maven.execution.MavenSession;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
@@ -36,10 +35,8 @@
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
 
 /**
- * Default dependency graph builder that detects current Maven version to delegate to either Maven 3.0 or 3.1+ specific
- * code.
+ * Default dependency graph builder that detects current Maven version and delegate to 3.1+ specific code.
  *
- * @see Maven3DependencyGraphBuilder
  * @see Maven31DependencyGraphBuilder
  * @author Hervé Boutemy
  * @since 2.0
@@ -65,16 +62,14 @@
     {
         try
         {
-            String hint = isMaven31() ? "maven31" : "maven3";
-
             DependencyGraphBuilder effectiveGraphBuilder =
-                (DependencyGraphBuilder) container.lookup( DependencyGraphBuilder.class.getCanonicalName(), hint );
+                    container.lookup( DependencyGraphBuilder.class, "maven31" );
             
             if ( getLogger().isDebugEnabled() )
             {
                 MavenProject project = buildingRequest.getProject();
                 
-                getLogger().debug( "building " + hint + " dependency graph for " + project.getId() + " with "
+                getLogger().debug( "building Maven 3.1+ dependency graph for " + project.getId() + " with "
                                 + effectiveGraphBuilder.getClass().getSimpleName() );
             }
 
@@ -87,23 +82,6 @@
     }
 
     /**
-     * @return true if the current Maven version is Maven 3.1.
-     */
-    protected static boolean isMaven31()
-    {
-        try
-        {
-            Class<?> repoSessionClass =  MavenSession.class.getMethod( "getRepositorySession" ).getReturnType();
-            
-            return "org.eclipse.aether.RepositorySystemSession".equals( repoSessionClass.getName() );
-        }
-        catch ( NoSuchMethodException e )
-        {
-            throw new IllegalStateException( "Cannot determine return type of MavenSession.getRepositorySession" );
-        }
-    }
-
-    /**
      * Injects the Plexus content.
      *
      * @param context   Plexus context to inject.
diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Invoker.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/Invoker.java
deleted file mode 100644
index 8cc8851..0000000
--- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Invoker.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package org.apache.maven.shared.dependency.graph.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.dependency.graph.DependencyGraphBuilderException;
-
-/**
- * Invokes method on objects using reflection.
- */
-final class Invoker
-{
-    private Invoker()
-    {
-        // do not instantiate
-    }
-
-    static <T extends Exception> Object invoke( Object object, String method, ExceptionHandler<T> exceptionHandler )
-        throws T
-    {
-        return invoke( object.getClass(), object, method, exceptionHandler );
-    }
-
-    static <T extends Exception> Object invoke( Class<?> objectClazz, Object object, String method,
-                                                ExceptionHandler<T> exceptionHandler )
-        throws T
-    {
-        try
-        {
-            return objectClazz.getMethod( method ).invoke( object );
-        }
-        catch ( ReflectiveOperationException e )
-        {
-            throw exceptionHandler.create( e.getMessage(), e );
-        }
-    }
-
-    static Object invoke( Object object, String method, Class<?> clazz, Object arg )
-        throws DependencyGraphBuilderException
-    {
-        try
-        {
-            final Class<?> objectClazz = object.getClass();
-            return objectClazz.getMethod( method, clazz ).invoke( object, arg );
-        }
-        catch ( ReflectiveOperationException e )
-        {
-            throw new DependencyGraphBuilderException( e.getMessage(), e );
-        }
-    }
-    
-    static <T extends Exception> Object invoke( Class<?> objectClazz, String staticMethod,
-                                                               Class<?> argClazz, Object arg,
-                                                               ExceptionHandler<T> exceptionHandler )
-        throws T
-    {
-        try
-        {
-            return objectClazz.getMethod( staticMethod, argClazz ).invoke( null, arg );
-        }
-        catch ( ReflectiveOperationException e )
-        {
-            throw exceptionHandler.create( e.getMessage(), e );
-        }
-    }
-
-    static <T extends Exception> Object invoke( Class<?> objectClazz, String staticMethod, Class<?> argClazz1,
-                                                Class<?> argClazz2, Object arg1, Object arg2,
-                                                ExceptionHandler<T> exceptionHandler )
-        throws T
-    {
-        try
-        {
-            return objectClazz.getMethod( staticMethod, argClazz1, argClazz2 ).invoke( null, arg1, arg2 );
-        }
-        catch ( ReflectiveOperationException e )
-        {
-            throw exceptionHandler.create( e.getMessage(), e );
-        }
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven31DependencyCollectorBuilder.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven31DependencyCollectorBuilder.java
index 73d06de..f8517e4 100644
--- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven31DependencyCollectorBuilder.java
+++ b/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven31DependencyCollectorBuilder.java
@@ -40,6 +40,7 @@
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 import org.eclipse.aether.DefaultRepositorySystemSession;
 import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
 import org.eclipse.aether.artifact.ArtifactTypeRegistry;
 import org.eclipse.aether.collection.CollectRequest;
 import org.eclipse.aether.collection.CollectResult;
@@ -60,6 +61,8 @@
 import org.eclipse.aether.util.graph.visitor.TreeDependencyVisitor;
 import org.eclipse.aether.version.VersionConstraint;
 
+import static org.apache.maven.RepositoryUtils.toArtifact;
+
 /**
  * Project dependency raw dependency collector API, abstracting Maven 3.1+'s Aether implementation.
  * 
@@ -93,9 +96,15 @@
             Artifact projectArtifact = project.getArtifact();
             List<ArtifactRepository> remoteArtifactRepositories = project.getRemoteArtifactRepositories();
 
-            DefaultRepositorySystemSession repositorySession =
-                (DefaultRepositorySystemSession) Invoker.invoke( buildingRequest, "getRepositorySession",
-                                                                 exceptionHandler );
+            RepositorySystemSession repositorySession;
+            try
+            {
+                repositorySession = buildingRequest.getRepositorySession();
+            }
+            catch ( Exception e )
+            {
+                throw exceptionHandler.create( e.getMessage(), e );
+            }
 
             session = new DefaultRepositorySystemSession( repositorySession );
 
@@ -113,17 +122,25 @@
             session.setConfigProperty( ConflictResolver.CONFIG_PROP_VERBOSE, true );
             session.setConfigProperty( DependencyManagerUtils.CONFIG_PROP_VERBOSE, true );
 
-            org.eclipse.aether.artifact.Artifact aetherArtifact =
-                (org.eclipse.aether.artifact.Artifact) Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                                                                       Artifact.class, projectArtifact,
-                                                                       exceptionHandler );
+            org.eclipse.aether.artifact.Artifact aetherArtifact;
+            try
+            {
+                aetherArtifact = RepositoryUtils.toArtifact( projectArtifact );
+            }
+            catch ( Exception e )
+            {
+                throw exceptionHandler.create( e.getMessage(), e );
+            }
 
-            @SuppressWarnings( "unchecked" )
-            List<org.eclipse.aether.repository.RemoteRepository> aetherRepos =
-                (List<org.eclipse.aether.repository.RemoteRepository>) Invoker.invoke( RepositoryUtils.class, "toRepos",
-                                                                                       List.class,
-                                                                                       remoteArtifactRepositories,
-                                                                                       exceptionHandler );
+            List<org.eclipse.aether.repository.RemoteRepository> aetherRepos;
+            try
+            {
+                aetherRepos = RepositoryUtils.toRepos( remoteArtifactRepositories );
+            }
+            catch ( Exception e )
+            {
+                throw exceptionHandler.create( e.getMessage(), e );
+            }
 
             CollectRequest collectRequest = new CollectRequest();
             collectRequest.setRootArtifact( aetherArtifact );
@@ -202,8 +219,7 @@
     {
         for ( Dependency dependency : project.getDependencies() )
         {
-            org.eclipse.aether.graph.Dependency aetherDep = toAetherDependency( stereotypes, dependency );
-            collectRequest.addDependency( aetherDep );
+            collectRequest.addDependency( toAetherDependency( stereotypes, dependency ) );
         }
     }
 
@@ -212,33 +228,23 @@
                                                                     Dependency dependency )
         throws DependencyCollectorBuilderException
     {
-        return (org.eclipse.aether.graph.Dependency) Invoker.invoke( RepositoryUtils.class, "toDependency",
-                                                              Dependency.class,
-                                                              ArtifactTypeRegistry.class,
-                                                              dependency, stereotypes, exceptionHandler );
+        try
+        {
+            return RepositoryUtils.toDependency( dependency, stereotypes );
+        }
+        catch ( Exception e )
+        {
+            throw exceptionHandler.create( e.getMessage(), e );
+        }
     }
     // CHECKSTYLE_ON: LineLength
 
     private Artifact getDependencyArtifact( org.eclipse.aether.graph.Dependency dep )
     {
-        org.eclipse.aether.artifact.Artifact artifact = dep.getArtifact();
-
-        try
-        {
-            Artifact mavenArtifact =
-                (Artifact) Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                                           org.eclipse.aether.artifact.Artifact.class, artifact, exceptionHandler );
-
-            mavenArtifact.setScope( dep.getScope() );
-            mavenArtifact.setOptional( dep.isOptional() );
-
-            return mavenArtifact;
-        }
-        catch ( DependencyCollectorBuilderException e )
-        {
-            // ReflectionException should not happen
-            throw new RuntimeException( e.getMessage(), e );
-        }
+        Artifact mavenArtifact = toArtifact( dep.getArtifact() );
+        mavenArtifact.setScope( dep.getScope() );
+        mavenArtifact.setOptional( dep.isOptional() );
+        return mavenArtifact;
     }
 
     private DependencyNode buildDependencyNode( DependencyNode parent, org.eclipse.aether.graph.DependencyNode node,
diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven31DependencyGraphBuilder.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven31DependencyGraphBuilder.java
index bdecb91..59c678d 100644
--- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven31DependencyGraphBuilder.java
+++ b/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven31DependencyGraphBuilder.java
@@ -19,13 +19,13 @@
  * under the License.
  */
 
+import static org.apache.maven.RepositoryUtils.toArtifact;
 import static org.eclipse.aether.util.graph.manager.DependencyManagerUtils.NODE_DATA_PREMANAGED_VERSION;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-import org.apache.maven.RepositoryUtils;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
 import org.apache.maven.project.DefaultDependencyResolutionRequest;
@@ -44,7 +44,6 @@
 import org.eclipse.aether.DefaultRepositorySystemSession;
 import org.eclipse.aether.RepositorySystemSession;
 import org.eclipse.aether.graph.Dependency;
-import org.eclipse.aether.graph.DependencyFilter;
 import org.eclipse.aether.graph.Exclusion;
 import org.eclipse.aether.util.graph.manager.DependencyManagerUtils;
 import org.eclipse.aether.version.VersionConstraint;
@@ -64,11 +63,8 @@
     @Requirement
     private ProjectDependenciesResolver resolver;
 
-    private final ExceptionHandler<DependencyGraphBuilderException> exceptionHandler;
-    
     public Maven31DependencyGraphBuilder()
     {
-        this.exceptionHandler = DependencyGraphBuilderException::new;
     }
 
     /**
@@ -85,10 +81,7 @@
     {
         MavenProject project = buildingRequest.getProject();
 
-        RepositorySystemSession session =
-            (RepositorySystemSession) Invoker.invoke( buildingRequest, "getRepositorySession", exceptionHandler );
-
-        
+        RepositorySystemSession session = buildingRequest.getRepositorySession();
         if ( Boolean.TRUE != session.getConfigProperties().get( NODE_DATA_PREMANAGED_VERSION ) )
         {
             DefaultRepositorySystemSession newSession = new DefaultRepositorySystemSession( session );
@@ -98,17 +91,13 @@
 
         final DependencyResolutionRequest request = new DefaultDependencyResolutionRequest();
         request.setMavenProject( project );
-        Invoker.invoke( request, "setRepositorySession", RepositorySystemSession.class, session );
+        request.setRepositorySession( session );
         // only download the poms, not the artifacts
-        DependencyFilter collectFilter = ( node, parents ) -> false;
-        Invoker.invoke( request, "setResolutionFilter", DependencyFilter.class, collectFilter );
+        request.setResolutionFilter( ( node, parents ) -> false );
 
-        final DependencyResolutionResult result = resolveDependencies( request );
-        org.eclipse.aether.graph.DependencyNode graph =
-            (org.eclipse.aether.graph.DependencyNode) Invoker.invoke( DependencyResolutionResult.class, result,
-                                                                      "getDependencyGraph", exceptionHandler );
+        DependencyResolutionResult result = resolveDependencies( request );
 
-        return buildDependencyNode( null, graph, project.getArtifact(), filter );
+        return buildDependencyNode( null, result.getDependencyGraph(), project.getArtifact(), filter );
     }
 
     private DependencyResolutionResult resolveDependencies( DependencyResolutionRequest request )
@@ -125,27 +114,6 @@
         }
     }
 
-    private Artifact getDependencyArtifact( Dependency dep )
-    {
-        org.eclipse.aether.artifact.Artifact artifact = dep.getArtifact();
-
-        try
-        {
-            Artifact mavenArtifact = (Artifact) Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                                              org.eclipse.aether.artifact.Artifact.class, artifact, exceptionHandler );
-
-            mavenArtifact.setScope( dep.getScope() );
-            mavenArtifact.setOptional( dep.isOptional() );
-
-            return mavenArtifact;
-        }
-        catch ( DependencyGraphBuilderException e )
-        {
-            // ReflectionException should not happen
-            throw new RuntimeException( e.getMessage(), e );
-        }
-    }
-
     private DependencyNode buildDependencyNode( DependencyNode parent, org.eclipse.aether.graph.DependencyNode node,
                                                 Artifact artifact, ArtifactFilter filter )
     {
@@ -174,11 +142,14 @@
         List<DependencyNode> nodes = new ArrayList<>( node.getChildren().size() );
         for ( org.eclipse.aether.graph.DependencyNode child : node.getChildren() )
         {
-            Artifact childArtifact = getDependencyArtifact( child.getDependency() );
+            Dependency dep = child.getDependency();
+            Artifact mavenArtifact = toArtifact( dep.getArtifact() );
+            mavenArtifact.setScope( dep.getScope() );
+            mavenArtifact.setOptional( dep.isOptional() );
 
-            if ( ( filter == null ) || filter.include( childArtifact ) )
+            if ( ( filter == null ) || filter.include( mavenArtifact ) )
             {
-                nodes.add( buildDependencyNode( current, child, childArtifact, filter ) );
+                nodes.add( buildDependencyNode( current, child, mavenArtifact, filter ) );
             }
         }
 
diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven3DependencyCollectorBuilder.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven3DependencyCollectorBuilder.java
deleted file mode 100644
index 2a3a555..0000000
--- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven3DependencyCollectorBuilder.java
+++ /dev/null
@@ -1,321 +0,0 @@
-package org.apache.maven.shared.dependency.graph.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.Collections;
-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.artifact.resolver.filter.ArtifactFilter;
-import org.apache.maven.model.Dependency;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.project.ProjectBuildingRequest;
-import org.apache.maven.shared.dependency.graph.DependencyCollectorBuilder;
-import org.apache.maven.shared.dependency.graph.DependencyCollectorBuilderException;
-import org.apache.maven.shared.dependency.graph.DependencyNode;
-import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver;
-import org.apache.maven.shared.dependency.graph.internal.maven30.JavaScopeDeriver;
-import org.apache.maven.shared.dependency.graph.internal.maven30.Maven3DirectScopeDependencySelector;
-import org.apache.maven.shared.dependency.graph.internal.maven30.NearestVersionSelector;
-import org.apache.maven.shared.dependency.graph.internal.maven30.SimpleOptionalitySelector;
-import org.apache.maven.shared.dependency.graph.internal.maven30.VerboseJavaScopeSelector;
-import org.codehaus.plexus.component.annotations.Component;
-import org.codehaus.plexus.component.annotations.Requirement;
-import org.codehaus.plexus.logging.AbstractLogEnabled;
-import org.sonatype.aether.RepositorySystem;
-import org.sonatype.aether.RepositorySystemSession;
-import org.sonatype.aether.artifact.ArtifactTypeRegistry;
-import org.sonatype.aether.collection.CollectRequest;
-import org.sonatype.aether.collection.CollectResult;
-import org.sonatype.aether.collection.DependencyCollectionException;
-import org.sonatype.aether.collection.DependencyGraphTransformer;
-import org.sonatype.aether.collection.DependencySelector;
-import org.sonatype.aether.graph.DependencyVisitor;
-import org.sonatype.aether.graph.Exclusion;
-import org.sonatype.aether.util.DefaultRepositorySystemSession;
-import org.sonatype.aether.util.artifact.JavaScopes;
-import org.sonatype.aether.util.graph.TreeDependencyVisitor;
-import org.sonatype.aether.util.graph.selector.AndDependencySelector;
-import org.sonatype.aether.util.graph.selector.ExclusionDependencySelector;
-import org.sonatype.aether.util.graph.selector.OptionalDependencySelector;
-import org.sonatype.aether.version.VersionConstraint;
-
-/**
- * Project dependency raw dependency collector API, abstracting Maven 3's Aether implementation.
- * 
- * @author Gabriel Belingueres
- * @since 3.1.0
- */
-@Component( role = DependencyCollectorBuilder.class, hint = "maven3" )
-public class Maven3DependencyCollectorBuilder
-    extends AbstractLogEnabled
-    implements DependencyCollectorBuilder
-{
-    @Requirement
-    private RepositorySystem repositorySystem;
-    
-    private final ExceptionHandler<DependencyCollectorBuilderException> exceptionHandler;
-    
-    public Maven3DependencyCollectorBuilder()
-    {
-        this.exceptionHandler = DependencyCollectorBuilderException::new;
-    }
-
-    @Override
-    public DependencyNode collectDependencyGraph( ProjectBuildingRequest buildingRequest, ArtifactFilter filter )
-        throws DependencyCollectorBuilderException
-    {
-        try
-        {
-            MavenProject project = buildingRequest.getProject();
-
-            Artifact projectArtifact = project.getArtifact();
-            List<ArtifactRepository> remoteArtifactRepositories = project.getRemoteArtifactRepositories();
-
-            // throws ClassCastException (classloading issues?)
-            // DefaultRepositorySystemSession repositorySystemSession =
-            // (DefaultRepositorySystemSession) Invoker.invoke( buildingRequest, "getRepositorySession" );
-            RepositorySystemSession repositorySystemSession = buildingRequest.getRepositorySession();
-
-            DefaultRepositorySystemSession session = new DefaultRepositorySystemSession( repositorySystemSession );
-
-            DependencyGraphTransformer transformer =
-                new ConflictResolver( new NearestVersionSelector(), new VerboseJavaScopeSelector(),
-                                      new SimpleOptionalitySelector(), new JavaScopeDeriver() );
-            session.setDependencyGraphTransformer( transformer );
-
-            DependencySelector depFilter =
-                new AndDependencySelector( new Maven3DirectScopeDependencySelector( JavaScopes.TEST ),
-                                           new OptionalDependencySelector(), 
-                                           new ExclusionDependencySelector() );
-            session.setDependencySelector( depFilter );
-
-            session.setConfigProperty( ConflictResolver.CONFIG_PROP_VERBOSE, true );
-            session.setConfigProperty( "aether.dependencyManager.verbose", true );
-
-            org.sonatype.aether.artifact.Artifact aetherArtifact =
-                (org.sonatype.aether.artifact.Artifact) Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                                                                        Artifact.class, projectArtifact,
-                                                                        exceptionHandler );
-
-            @SuppressWarnings( "unchecked" )
-            List<org.sonatype.aether.repository.RemoteRepository> aetherRepos =
-                (List<org.sonatype.aether.repository.RemoteRepository>) Invoker.invoke( RepositoryUtils.class,
-                                                                                        "toRepos", List.class,
-                                                                                        remoteArtifactRepositories,
-                                                                                        exceptionHandler );
-
-            CollectRequest collectRequest = new CollectRequest();
-            collectRequest.setRoot( new org.sonatype.aether.graph.Dependency( aetherArtifact, "" ) );
-            collectRequest.setRepositories( aetherRepos );
-
-            org.sonatype.aether.artifact.ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry();
-            collectDependencyList( collectRequest, project, stereotypes );
-            collectManagedDependencyList( collectRequest, project, stereotypes );
-
-            CollectResult collectResult = repositorySystem.collectDependencies( session, collectRequest );
-
-            org.sonatype.aether.graph.DependencyNode rootNode = collectResult.getRoot();
-
-            if ( getLogger().isDebugEnabled() )
-            {
-                logTree( rootNode );
-            }
-
-            return buildDependencyNode( null, rootNode, projectArtifact, filter );
-        }
-        catch ( DependencyCollectionException e )
-        {
-            throw new DependencyCollectorBuilderException( "Could not collect dependencies: " + e.getResult(), e );
-        }
-    }
-
-    private void logTree( org.sonatype.aether.graph.DependencyNode rootNode )
-    {
-        // print the node tree with its associated data Map
-        rootNode.accept( new TreeDependencyVisitor( new DependencyVisitor()
-        {
-            String indent = "";
-
-            @Override
-            public boolean visitEnter( org.sonatype.aether.graph.DependencyNode dependencyNode )
-            {
-                StringBuilder sb = new StringBuilder();
-                sb.append( indent ).append( "Aether node: " ).append( dependencyNode );
-                if ( !dependencyNode.getData().isEmpty() )
-                {
-                    sb.append( "data map: " ).append( dependencyNode.getData() );
-                }
-                if ( dependencyNode.getPremanagedVersion() != null && !dependencyNode.getPremanagedVersion().isEmpty() )
-                {
-                    sb.append( "Premanaged.version: " ).append( dependencyNode.getPremanagedVersion() );
-                }
-                if ( dependencyNode.getPremanagedScope() != null && !dependencyNode.getPremanagedScope().isEmpty() )
-                {
-                    sb.append( "Premanaged.scope: " ).append( dependencyNode.getPremanagedScope() );
-                }
-                getLogger().debug( sb.toString() );
-                indent += "    ";
-                return true;
-            }
-
-            @Override
-            public boolean visitLeave( org.sonatype.aether.graph.DependencyNode dependencyNode )
-            {
-                indent = indent.substring( 0, indent.length() - 4 );
-                return true;
-            }
-        } ) );
-    }
-
-    private void collectManagedDependencyList( CollectRequest collectRequest, MavenProject project,
-                                               ArtifactTypeRegistry stereotypes )
-        throws DependencyCollectorBuilderException
-    {
-        if ( project.getDependencyManagement() != null )
-        {
-            for ( Dependency dependency : project.getDependencyManagement().getDependencies() )
-            {
-                org.sonatype.aether.graph.Dependency aetherDep = toAetherDependency( stereotypes, dependency );
-                collectRequest.addManagedDependency( aetherDep );
-            }
-        }
-    }
-
-    private void collectDependencyList( CollectRequest collectRequest, MavenProject project,
-                                        org.sonatype.aether.artifact.ArtifactTypeRegistry stereotypes )
-        throws DependencyCollectorBuilderException
-    {
-        for ( Dependency dependency : project.getDependencies() )
-        {
-            org.sonatype.aether.graph.Dependency aetherDep = toAetherDependency( stereotypes, dependency );
-            collectRequest.addDependency( aetherDep );
-        }
-    }
-
-    // CHECKSTYLE_OFF: LineLength
-    private org.sonatype.aether.graph.Dependency toAetherDependency( org.sonatype.aether.artifact.ArtifactTypeRegistry stereotypes,
-                                                                    Dependency dependency )
-        throws DependencyCollectorBuilderException
-    {
-        return (org.sonatype.aether.graph.Dependency) Invoker.invoke( RepositoryUtils.class, "toDependency",
-                                                              Dependency.class,
-                                                               ArtifactTypeRegistry.class,
-                                                              dependency, stereotypes, exceptionHandler );
-    }
-    // CHECKSTYLE_ON: LineLength
-
-    private Artifact getDependencyArtifact( org.sonatype.aether.graph.Dependency dep )
-    {
-        org.sonatype.aether.artifact.Artifact artifact = dep.getArtifact();
-
-        try
-        {
-            Artifact mavenArtifact =
-                (Artifact) Invoker.invoke( RepositoryUtils.class, "toArtifact",
-                                           org.sonatype.aether.artifact.Artifact.class, artifact, exceptionHandler );
-
-            mavenArtifact.setScope( dep.getScope() );
-            mavenArtifact.setOptional( dep.isOptional() );
-
-            return mavenArtifact;
-        }
-        catch ( DependencyCollectorBuilderException e )
-        {
-            // ReflectionException should not happen
-            throw new RuntimeException( e.getMessage(), e );
-        }
-    }
-
-    private DependencyNode buildDependencyNode( DependencyNode parent, org.sonatype.aether.graph.DependencyNode node,
-                                                Artifact artifact, ArtifactFilter filter )
-    {
-        String premanagedVersion = node.getPremanagedVersion();
-        String premanagedScope = node.getPremanagedScope();
-
-        Boolean optional = null;
-        if ( node.getDependency() != null )
-        {
-            optional = node.getDependency().isOptional();
-        }
-
-        List<org.apache.maven.model.Exclusion> exclusions = null;
-        if ( node.getDependency() != null )
-        {
-            exclusions = new ArrayList<>( node.getDependency().getExclusions().size() );
-            for ( Exclusion exclusion : node.getDependency().getExclusions() )
-            {
-                org.apache.maven.model.Exclusion modelExclusion = new org.apache.maven.model.Exclusion();
-                modelExclusion.setGroupId( exclusion.getGroupId() );
-                modelExclusion.setArtifactId( exclusion.getArtifactId() );
-                exclusions.add( modelExclusion );
-            }
-        }
-
-        org.sonatype.aether.graph.DependencyNode winner =
-            (org.sonatype.aether.graph.DependencyNode) node.getData().get( ConflictResolver.NODE_DATA_WINNER );
-        String winnerVersion = null;
-        String ignoredScope = null;
-        if ( winner != null )
-        {
-            winnerVersion = winner.getVersion().toString();
-        }
-        else
-        {
-            ignoredScope = (String) node.getData().get( VerboseJavaScopeSelector.REDUCED_SCOPE );
-        }
-
-        ConflictData data = new ConflictData( winnerVersion, ignoredScope );
-
-        VerboseDependencyNode current =
-            new VerboseDependencyNode( parent, artifact, premanagedVersion, premanagedScope,
-                                       getVersionSelectedFromRange( node.getVersionConstraint() ), optional, exclusions,
-                                       data );
-
-        List<DependencyNode> nodes = new ArrayList<>( node.getChildren().size() );
-        for ( org.sonatype.aether.graph.DependencyNode child : node.getChildren() )
-        {
-            Artifact childArtifact = getDependencyArtifact( child.getDependency() );
-
-            if ( ( filter == null ) || filter.include( childArtifact ) )
-            {
-                nodes.add( buildDependencyNode( current, child, childArtifact, filter ) );
-            }
-        }
-
-        current.setChildren( Collections.unmodifiableList( nodes ) );
-
-        return current;
-    }
-
-    private String getVersionSelectedFromRange( VersionConstraint constraint )
-    {
-        if ( ( constraint == null ) || ( constraint.getVersion() != null ) || ( constraint.getRanges().isEmpty() ) )
-        {
-            return null;
-        }
-
-        return constraint.getRanges().iterator().next().toString();
-    }
-
-}
diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven3DependencyGraphBuilder.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven3DependencyGraphBuilder.java
deleted file mode 100644
index 2ec8f94..0000000
--- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/Maven3DependencyGraphBuilder.java
+++ /dev/null
@@ -1,155 +0,0 @@
-package org.apache.maven.shared.dependency.graph.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.Collections;
-import java.util.List;
-
-import org.apache.maven.RepositoryUtils;
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
-import org.apache.maven.project.DefaultDependencyResolutionRequest;
-import org.apache.maven.project.DependencyResolutionException;
-import org.apache.maven.project.DependencyResolutionRequest;
-import org.apache.maven.project.DependencyResolutionResult;
-import org.apache.maven.project.MavenProject;
-import org.apache.maven.project.ProjectBuildingRequest;
-import org.apache.maven.project.ProjectDependenciesResolver;
-import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
-import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException;
-import org.apache.maven.shared.dependency.graph.DependencyNode;
-import org.codehaus.plexus.component.annotations.Component;
-import org.codehaus.plexus.component.annotations.Requirement;
-import org.codehaus.plexus.logging.AbstractLogEnabled;
-import org.sonatype.aether.graph.DependencyFilter;
-import org.sonatype.aether.graph.Dependency;
-import org.sonatype.aether.version.VersionConstraint;
-
-/**
- * Wrapper around Maven 3 dependency resolver.
- *
- * @see ProjectDependenciesResolver
- * @author Hervé Boutemy
- * @since 2.0
- */
-@Component( role = DependencyGraphBuilder.class, hint = "maven3" )
-public class Maven3DependencyGraphBuilder
-    extends AbstractLogEnabled
-    implements DependencyGraphBuilder
-{
-    @Requirement
-    private ProjectDependenciesResolver resolver;
-
-    /**
-     * Builds the dependency graph for Maven 3.
-     *
-     * @param buildingRequest the buildingRequest
-     * @param filter artifact filter (can be <code>null</code>)
-     * @return DependencyNode containing the dependency graph.
-     * @throws DependencyGraphBuilderException if some of the dependencies could not be resolved.
-     */
-    @Override
-    public DependencyNode buildDependencyGraph( ProjectBuildingRequest buildingRequest, ArtifactFilter filter )
-        throws DependencyGraphBuilderException
-    {
-        MavenProject project = buildingRequest.getProject();
-
-        DependencyResolutionRequest request =
-            new DefaultDependencyResolutionRequest( project, buildingRequest.getRepositorySession() );
-
-        // only download the poms, not the artifacts
-        DependencyFilter collectFilter = ( node, parents ) -> false;
-        request.setResolutionFilter( collectFilter );
-
-        DependencyResolutionResult result = resolveDependencies( request );
-
-        return buildDependencyNode( null, result.getDependencyGraph(), project.getArtifact(), filter );
-    }
-
-    private DependencyResolutionResult resolveDependencies( DependencyResolutionRequest request )
-        throws DependencyGraphBuilderException
-    {
-        try
-        {
-            return resolver.resolve( request );
-        }
-        catch ( DependencyResolutionException e )
-        {
-            throw new DependencyGraphBuilderException( "Could not resolve following dependencies: "
-                + e.getResult().getUnresolvedDependencies(), e );
-        }
-    }
-
-    private Artifact getDependencyArtifact( Dependency dep )
-    {
-        Artifact mavenArtifact = RepositoryUtils.toArtifact( dep.getArtifact() );
-
-        mavenArtifact.setScope( dep.getScope() );
-        mavenArtifact.setOptional( dep.isOptional() );
-
-        return mavenArtifact;
-    }
-
-    private DependencyNode buildDependencyNode( DependencyNode parent, org.sonatype.aether.graph.DependencyNode node,
-                                                Artifact artifact, ArtifactFilter filter )
-    {
-        DefaultDependencyNode current =
-            new DefaultDependencyNode( parent, artifact,
-                                       null /* node.getPremanagedVersion() */,
-                                       null /* node.getPremanagedScope() */,
-                                       getVersionSelectedFromRange( node.getVersionConstraint() ) );
-
-        List<DependencyNode> nodes = new ArrayList<>( node.getChildren().size() );
-        for ( org.sonatype.aether.graph.DependencyNode child : node.getChildren() )
-        {
-            Artifact childArtifact = getDependencyArtifact( child.getDependency() );
-
-            if ( ( filter == null ) || filter.include( childArtifact ) )
-            {
-                nodes.add( buildDependencyNode( current, child, childArtifact, filter ) );
-            }
-        }
-
-        current.setChildren( Collections.unmodifiableList( nodes ) );
-
-        return current;
-    }
-
-    private String getVersionSelectedFromRange( VersionConstraint constraint )
-    {
-        if ( ( constraint == null ) || ( constraint.getVersion() != null ) )
-        {
-            return null;
-        }
-
-        StringBuilder sb = new StringBuilder();
-        for ( org.sonatype.aether.version.VersionRange range : constraint.getRanges() )
-        {
-            if ( sb.length() > 0 )
-            {
-                sb.append( ',' );
-            }
-            sb.append( range );
-        }
-
-        return sb.toString();
-    }
-}
diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ConflictIdSorter.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ConflictIdSorter.java
deleted file mode 100644
index 35cb5a8..0000000
--- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ConflictIdSorter.java
+++ /dev/null
@@ -1,370 +0,0 @@
-package org.apache.maven.shared.dependency.graph.internal.maven30;
-
-/*
- * 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.HashMap;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.sonatype.aether.RepositoryException;
-import org.sonatype.aether.collection.DependencyGraphTransformationContext;
-import org.sonatype.aether.collection.DependencyGraphTransformer;
-import org.sonatype.aether.graph.DependencyNode;
-import org.sonatype.aether.util.graph.transformer.ConflictMarker;
-import org.sonatype.aether.util.graph.transformer.TransformationContextKeys;
-
-/**
- * This class is a copy of their homonymous in the Eclipse Aether library, adapted to work with Sonatype Aether.
- * 
- * @author Gabriel Belingueres
- * @since 3.1.0
- */
-public final class ConflictIdSorter
-    implements DependencyGraphTransformer
-{
-
-    public DependencyNode transformGraph( DependencyNode node, DependencyGraphTransformationContext context )
-        throws RepositoryException
-    {
-        Map<?, ?> conflictIds = (Map<?, ?>) context.get( TransformationContextKeys.CONFLICT_IDS );
-        if ( conflictIds == null )
-        {
-            ConflictMarker marker = new ConflictMarker();
-            marker.transformGraph( node, context );
-
-            conflictIds = (Map<?, ?>) context.get( TransformationContextKeys.CONFLICT_IDS );
-        }
-
-//        @SuppressWarnings( "unchecked" )
-//        Map<String, Object> stats = (Map<String, Object>) context.get( TransformationContextKeys.STATS );
-//        long time1 = System.currentTimeMillis();
-
-        Map<Object, ConflictId> ids = new LinkedHashMap<>( 256 );
-
-        // CHECKSTYLE_OFF: AvoidNestedBlocks
-        {
-            ConflictId id = null;
-            Object key = conflictIds.get( node );
-            if ( key != null )
-            {
-                id = new ConflictId( key, 0 );
-                ids.put( key, id );
-            }
-
-            Map<DependencyNode, Object> visited = new IdentityHashMap<>( conflictIds.size() );
-
-            buildConflitIdDAG( ids, node, id, 0, visited, conflictIds );
-        }
-        // CHECKSTYLE_NO: AvoidNestedBlocks
-
-//        long time2 = System.currentTimeMillis();
-
-        topsortConflictIds( ids.values(), context );
-//        int cycles = topsortConflictIds( ids.values(), context );
-
-//        if ( stats != null )
-//        {
-//            long time3 = System.currentTimeMillis();
-//            stats.put( "ConflictIdSorter.graphTime", time2 - time1 );
-//            stats.put( "ConflictIdSorter.topsortTime", time3 - time2 );
-//            stats.put( "ConflictIdSorter.conflictIdCount", ids.size() );
-//            stats.put( "ConflictIdSorter.conflictIdCycleCount", cycles );
-//        }
-
-        return node;
-    }
-
-    private void buildConflitIdDAG( Map<Object, ConflictId> ids, DependencyNode node, ConflictId id, int depth,
-                                    Map<DependencyNode, Object> visited, Map<?, ?> conflictIds )
-    {
-        if ( visited.put( node, Boolean.TRUE ) != null )
-        {
-            return;
-        }
-
-        depth++;
-
-        for ( DependencyNode child : node.getChildren() )
-        {
-            Object key = conflictIds.get( child );
-            ConflictId childId = ids.get( key );
-            if ( childId == null )
-            {
-                childId = new ConflictId( key, depth );
-                ids.put( key, childId );
-            }
-            else
-            {
-                childId.pullup( depth );
-            }
-
-            if ( id != null )
-            {
-                id.add( childId );
-            }
-
-            buildConflitIdDAG( ids, child, childId, depth, visited, conflictIds );
-        }
-    }
-
-    private int topsortConflictIds( Collection<ConflictId> conflictIds, DependencyGraphTransformationContext context )
-    {
-        List<Object> sorted = new ArrayList<>( conflictIds.size() );
-
-        RootQueue roots = new RootQueue( conflictIds.size() / 2 );
-        for ( ConflictId id : conflictIds )
-        {
-            if ( id.inDegree <= 0 )
-            {
-                roots.add( id );
-            }
-        }
-
-        processRoots( sorted, roots );
-
-        boolean cycle = sorted.size() < conflictIds.size();
-
-        while ( sorted.size() < conflictIds.size() )
-        {
-            // cycle -> deal gracefully with nodes still having positive in-degree
-
-            ConflictId nearest = null;
-            for ( ConflictId id : conflictIds )
-            {
-                if ( id.inDegree <= 0 )
-                {
-                    continue;
-                }
-                if ( nearest == null || id.minDepth < nearest.minDepth
-                    || ( id.minDepth == nearest.minDepth && id.inDegree < nearest.inDegree ) )
-                {
-                    nearest = id;
-                }
-            }
-
-            nearest.inDegree = 0;
-            roots.add( nearest );
-
-            processRoots( sorted, roots );
-        }
-
-        Collection<Collection<Object>> cycles = Collections.emptySet();
-        if ( cycle )
-        {
-            cycles = findCycles( conflictIds );
-        }
-
-        context.put( TransformationContextKeys.SORTED_CONFLICT_IDS, sorted );
-        context.put( TransformationContextKeys.CYCLIC_CONFLICT_IDS, cycles );
-
-        return cycles.size();
-    }
-
-    private void processRoots( List<Object> sorted, RootQueue roots )
-    {
-        while ( !roots.isEmpty() )
-        {
-            ConflictId root = roots.remove();
-
-            sorted.add( root.key );
-
-            for ( ConflictId child : root.children )
-            {
-                child.inDegree--;
-                if ( child.inDegree == 0 )
-                {
-                    roots.add( child );
-                }
-            }
-        }
-    }
-
-    private Collection<Collection<Object>> findCycles( Collection<ConflictId> conflictIds )
-    {
-        Collection<Collection<Object>> cycles = new HashSet<>();
-
-        Map<Object, Integer> stack = new HashMap<>( 128 );
-        Map<ConflictId, Object> visited = new IdentityHashMap<>( conflictIds.size() );
-        for ( ConflictId id : conflictIds )
-        {
-            findCycles( id, visited, stack, cycles );
-        }
-
-        return cycles;
-    }
-
-    private void findCycles( ConflictId id, Map<ConflictId, Object> visited, Map<Object, Integer> stack,
-                             Collection<Collection<Object>> cycles )
-    {
-        Integer depth = stack.put( id.key, stack.size() );
-        if ( depth != null )
-        {
-            stack.put( id.key, depth );
-            Collection<Object> cycle = new HashSet<>();
-            for ( Map.Entry<Object, Integer> entry : stack.entrySet() )
-            {
-                if ( entry.getValue() >= depth )
-                {
-                    cycle.add( entry.getKey() );
-                }
-            }
-            cycles.add( cycle );
-        }
-        else
-        {
-            if ( visited.put( id, Boolean.TRUE ) == null )
-            {
-                for ( ConflictId childId : id.children )
-                {
-                    findCycles( childId, visited, stack, cycles );
-                }
-            }
-            stack.remove( id.key );
-        }
-    }
-
-    static final class ConflictId
-    {
-
-        final Object key;
-
-        Collection<ConflictId> children = Collections.emptySet();
-
-        int inDegree;
-
-        int minDepth;
-
-        ConflictId( Object key, int depth )
-        {
-            this.key = key;
-            this.minDepth = depth;
-        }
-
-        public void add( ConflictId child )
-        {
-            if ( children.isEmpty() )
-            {
-                children = new HashSet<>();
-            }
-            if ( children.add( child ) )
-            {
-                child.inDegree++;
-            }
-        }
-
-        public void pullup( int depth )
-        {
-            if ( depth < minDepth )
-            {
-                minDepth = depth;
-                depth++;
-                for ( ConflictId child : children )
-                {
-                    child.pullup( depth );
-                }
-            }
-        }
-
-        @Override
-        public boolean equals( Object obj )
-        {
-            if ( this == obj )
-            {
-                return true;
-            }
-            else if ( !( obj instanceof ConflictId ) )
-            {
-                return false;
-            }
-            ConflictId that = (ConflictId) obj;
-            return this.key.equals( that.key );
-        }
-
-        @Override
-        public int hashCode()
-        {
-            return key.hashCode();
-        }
-
-        @Override
-        public String toString()
-        {
-            return key + " @ " + minDepth + " <" + inDegree;
-        }
-
-    }
-
-    static final class RootQueue
-    {
-
-        private int nextOut;
-
-        private int nextIn;
-
-        private ConflictId[] ids;
-
-        RootQueue( int capacity )
-        {
-            ids = new ConflictId[capacity + 16];
-        }
-
-        boolean isEmpty()
-        {
-            return nextOut >= nextIn;
-        }
-
-        void add( ConflictId id )
-        {
-            if ( nextOut >= nextIn && nextOut > 0 )
-            {
-                nextIn -= nextOut;
-                nextOut = 0;
-            }
-            if ( nextIn >= ids.length )
-            {
-                ConflictId[] tmp = new ConflictId[ids.length + ids.length / 2 + 16];
-                System.arraycopy( ids, nextOut, tmp, 0, nextIn - nextOut );
-                ids = tmp;
-                nextIn -= nextOut;
-                nextOut = 0;
-            }
-            int i;
-            for ( i = nextIn - 1; i >= nextOut && id.minDepth < ids[i].minDepth; i-- )
-            {
-                ids[i + 1] = ids[i];
-            }
-            ids[i + 1] = id;
-            nextIn++;
-        }
-
-        ConflictId remove()
-        {
-            return ids[nextOut++];
-        }
-
-    }
-
-}
diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ConflictResolver.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ConflictResolver.java
deleted file mode 100644
index 329c028..0000000
--- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ConflictResolver.java
+++ /dev/null
@@ -1,1314 +0,0 @@
-package org.apache.maven.shared.dependency.graph.internal.maven30;
-
-/*
- * 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.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-
-import org.sonatype.aether.RepositoryException;
-import org.sonatype.aether.artifact.Artifact;
-import org.sonatype.aether.collection.DependencyGraphTransformationContext;
-import org.sonatype.aether.collection.DependencyGraphTransformer;
-import org.sonatype.aether.graph.Dependency;
-import org.sonatype.aether.graph.DependencyNode;
-import org.sonatype.aether.util.ConfigUtils;
-import org.sonatype.aether.util.graph.DefaultDependencyNode;
-import org.sonatype.aether.util.graph.transformer.TransformationContextKeys;
-
-/**
- * This class is a copy of their homonymous in the Eclipse Aether library, adapted to work with Sonatype Aether.
- * 
- * @author Gabriel Belingueres
- * @since 3.1.0
- */
-public final class ConflictResolver
-    implements DependencyGraphTransformer
-{
-
-    /**
-     * The key in the repository session's {@link org.sonatype.aether.RepositorySystemSession#getConfigProperties()
-     * configuration properties} used to store a {@link Boolean} flag controlling the transformer's verbose mode.
-     */
-    public static final String CONFIG_PROP_VERBOSE = "aether.conflictResolver.verbose";
-
-    /**
-     * The key in the dependency node's {@link DependencyNode#getData() custom data} under which a reference to the
-     * {@link DependencyNode} which has won the conflict is stored.
-     */
-    public static final String NODE_DATA_WINNER = "conflict.winner";
-
-    /**
-     * The key in the dependency node's {@link DependencyNode#getData() custom data} under which the scope of the
-     * dependency before scope derivation and conflict resolution is stored.
-     */
-    public static final String NODE_DATA_ORIGINAL_SCOPE = "conflict.originalScope";
-
-    /**
-     * The key in the dependency node's {@link DependencyNode#getData() custom data} under which the optional flag of
-     * the dependency before derivation and conflict resolution is stored.
-     */
-    public static final String NODE_DATA_ORIGINAL_OPTIONALITY = "conflict.originalOptionality";
-
-    private final VersionSelector versionSelector;
-
-    private final ScopeSelector scopeSelector;
-
-    private final ScopeDeriver scopeDeriver;
-
-    private final OptionalitySelector optionalitySelector;
-
-    /**
-     * Creates a new conflict resolver instance with the specified hooks.
-     * 
-     * @param versionSelector The version selector to use, must not be {@code null}.
-     * @param scopeSelector The scope selector to use, must not be {@code null}.
-     * @param optionalitySelector The optionality selector ot use, must not be {@code null}.
-     * @param scopeDeriver The scope deriver to use, must not be {@code null}.
-     */
-    public ConflictResolver( VersionSelector versionSelector, ScopeSelector scopeSelector,
-                             OptionalitySelector optionalitySelector, ScopeDeriver scopeDeriver )
-    {
-        if ( versionSelector == null )
-        {
-            throw new IllegalArgumentException( "version selector not specified" );
-        }
-        this.versionSelector = versionSelector;
-        if ( scopeSelector == null )
-        {
-            throw new IllegalArgumentException( "scope selector not specified" );
-        }
-        this.scopeSelector = scopeSelector;
-        if ( scopeDeriver == null )
-        {
-            throw new IllegalArgumentException( "scope deriver not specified" );
-        }
-        this.scopeDeriver = scopeDeriver;
-        if ( optionalitySelector == null )
-        {
-            throw new IllegalArgumentException( "optionality selector not specified" );
-        }
-        this.optionalitySelector = optionalitySelector;
-    }
-
-    public DependencyNode transformGraph( DependencyNode node, DependencyGraphTransformationContext context )
-        throws RepositoryException
-    {
-        List<?> sortedConflictIds = (List<?>) context.get( TransformationContextKeys.SORTED_CONFLICT_IDS );
-        if ( sortedConflictIds == null )
-        {
-            ConflictIdSorter sorter = new ConflictIdSorter();
-            sorter.transformGraph( node, context );
-
-            sortedConflictIds = (List<?>) context.get( TransformationContextKeys.SORTED_CONFLICT_IDS );
-        }
-
-//        @SuppressWarnings( "unchecked" )
-//        Map<String, Object> stats = (Map<String, Object>) context.get( TransformationContextKeys.STATS );
-//        long time1 = System.currentTimeMillis();
-
-        @SuppressWarnings( "unchecked" )
-        Collection<Collection<?>> conflictIdCycles =
-            (Collection<Collection<?>>) context.get( TransformationContextKeys.CYCLIC_CONFLICT_IDS );
-        if ( conflictIdCycles == null )
-        {
-            throw new RepositoryException( "conflict id cycles have not been identified" );
-        }
-
-        Map<?, ?> conflictIds = (Map<?, ?>) context.get( TransformationContextKeys.CONFLICT_IDS );
-        if ( conflictIds == null )
-        {
-            throw new RepositoryException( "conflict groups have not been identified" );
-        }
-
-        Map<Object, Collection<Object>> cyclicPredecessors = new HashMap<>();
-        for ( Collection<?> cycle : conflictIdCycles )
-        {
-            for ( Object conflictId : cycle )
-            {
-                Collection<Object> predecessors =
-                        cyclicPredecessors.computeIfAbsent( conflictId, k -> new HashSet<>() );
-                predecessors.addAll( cycle );
-            }
-        }
-
-        State state = new State( node, conflictIds, sortedConflictIds.size(), context );
-        for ( Iterator<?> it = sortedConflictIds.iterator(); it.hasNext(); )
-        {
-            Object conflictId = it.next();
-
-            // reset data structures for next graph walk
-            state.prepare( conflictId, cyclicPredecessors.get( conflictId ) );
-
-            // find nodes with the current conflict id and while walking the graph (more deeply), nuke leftover losers
-            gatherConflictItems( node, state );
-
-            // now that we know the min depth of the parents, update depth of conflict items
-            state.finish();
-
-            // earlier runs might have nuked all parents of the current conflict id, so it might not exist anymore
-            if ( !state.items.isEmpty() )
-            {
-                ConflictContext ctx = state.conflictCtx;
-                state.versionSelector.selectVersion( ctx );
-                if ( ctx.winner == null )
-                {
-                    throw new RepositoryException( "conflict resolver did not select winner among " + state.items );
-                }
-                DependencyNode winner = ctx.winner.node;
-
-                state.scopeSelector.selectScope( ctx );
-                if ( state.verbose )
-                {
-                    winner.setData( NODE_DATA_ORIGINAL_SCOPE, winner.getDependency().getScope() );
-                }
-                winner.setScope( ctx.scope );
-
-                state.optionalitySelector.selectOptionality( ctx );
-                if ( state.verbose )
-                {
-                    winner.setData( NODE_DATA_ORIGINAL_OPTIONALITY, winner.getDependency().isOptional() );
-                }
-                winner.getDependency().setOptional( ctx.optional );
-//                winner.setOptional( ctx.optional );
-
-                removeLosers( state );
-            }
-
-            // record the winner so we can detect leftover losers during future graph walks
-            state.winner();
-
-            // in case of cycles, trigger final graph walk to ensure all leftover losers are gone
-            if ( !it.hasNext() && !conflictIdCycles.isEmpty() && state.conflictCtx.winner != null )
-            {
-                DependencyNode winner = state.conflictCtx.winner.node;
-                state.prepare( state, null );
-                gatherConflictItems( winner, state );
-            }
-        }
-
-//        if ( stats != null )
-//        {
-//            long time2 = System.currentTimeMillis();
-//            stats.put( "ConflictResolver.totalTime", time2 - time1 );
-//            stats.put( "ConflictResolver.conflictItemCount", state.totalConflictItems );
-//        }
-
-        return node;
-    }
-
-    private boolean gatherConflictItems( DependencyNode node, State state )
-        throws RepositoryException
-    {
-        Object conflictId = state.conflictIds.get( node );
-        if ( state.currentId.equals( conflictId ) )
-        {
-            // found it, add conflict item (if not already done earlier by another path)
-            state.add( node );
-            // we don't recurse here so we might miss losers beneath us, those will be nuked during future walks below
-        }
-        else if ( state.loser( node, conflictId ) )
-        {
-            // found a leftover loser (likely in a cycle) of an already processed conflict id, tell caller to nuke it
-            return false;
-        }
-        else if ( state.push( node, conflictId ) )
-        {
-            // found potential parent, no cycle and not visisted before with the same derived scope, so recurse
-            for ( Iterator<DependencyNode> it = node.getChildren().iterator(); it.hasNext(); )
-            {
-                DependencyNode child = it.next();
-                if ( !gatherConflictItems( child, state ) )
-                {
-                    it.remove();
-                }
-            }
-            state.pop();
-        }
-        return true;
-    }
-
-    private void removeLosers( State state )
-    {
-        ConflictItem winner = state.conflictCtx.winner;
-        List<DependencyNode> previousParent = null;
-        ListIterator<DependencyNode> childIt = null;
-        boolean conflictVisualized = false;
-        for ( ConflictItem item : state.items )
-        {
-            if ( item == winner )
-            {
-                continue;
-            }
-            if ( item.parent != previousParent )
-            {
-                childIt = item.parent.listIterator();
-                previousParent = item.parent;
-                conflictVisualized = false;
-            }
-            while ( childIt.hasNext() )
-            {
-                DependencyNode child = childIt.next();
-                if ( child == item.node )
-                {
-                    if ( state.verbose && !conflictVisualized && item.parent != winner.parent )
-                    {
-                        conflictVisualized = true;
-                        DependencyNode loser = new DefaultDependencyNode( child );
-                        loser.setData( NODE_DATA_WINNER, winner.node );
-                        loser.setData( NODE_DATA_ORIGINAL_SCOPE, loser.getDependency().getScope() );
-                        loser.setData( NODE_DATA_ORIGINAL_OPTIONALITY, loser.getDependency().isOptional() );
-                        loser.setScope( item.getScopes().iterator().next() );
-//                        loser.setChildren( Collections.<DependencyNode>emptyList() );
-                        childIt.set( loser );
-                    }
-                    else
-                    {
-                        childIt.remove();
-                    }
-                    break;
-                }
-            }
-        }
-        // there might still be losers beneath the winner (e.g. in case of cycles)
-        // those will be nuked during future graph walks when we include the winner in the recursion
-    }
-
-    static final class NodeInfo
-    {
-
-        /**
-         * The smallest depth at which the node was seen, used for "the" depth of its conflict items.
-         */
-        int minDepth;
-
-        /**
-         * The set of derived scopes the node was visited with, used to check whether an already seen node needs to be
-         * revisited again in context of another scope. To conserve memory, we start with {@code String} and update to
-         * {@code Set<String>} if needed.
-         */
-        Object derivedScopes;
-
-        /**
-         * The set of derived optionalities the node was visited with, used to check whether an already seen node needs
-         * to be revisited again in context of another optionality. To conserve memory, encoded as bit field (bit 0 ->
-         * optional=false, bit 1 -> optional=true).
-         */
-        int derivedOptionalities;
-
-        /**
-         * The conflict items which are immediate children of the node, used to easily update those conflict items after
-         * a new parent scope/optionality was encountered.
-         */
-        List<ConflictItem> children;
-
-        static final int CHANGE_SCOPE = 0x01;
-
-        static final int CHANGE_OPTIONAL = 0x02;
-
-        private static final int OPT_FALSE = 0x01;
-
-        private static final int OPT_TRUE = 0x02;
-
-        NodeInfo( int depth, String derivedScope, boolean optional )
-        {
-            minDepth = depth;
-            derivedScopes = derivedScope;
-            derivedOptionalities = optional ? OPT_TRUE : OPT_FALSE;
-        }
-
-        @SuppressWarnings( "unchecked" )
-        int update( int depth, String derivedScope, boolean optional )
-        {
-            if ( depth < minDepth )
-            {
-                minDepth = depth;
-            }
-            int changes;
-            if ( derivedScopes.equals( derivedScope ) )
-            {
-                changes = 0;
-            }
-            else if ( derivedScopes instanceof Collection )
-            {
-                changes = ( (Collection<String>) derivedScopes ).add( derivedScope ) ? CHANGE_SCOPE : 0;
-            }
-            else
-            {
-                Collection<String> scopes = new HashSet<>();
-                scopes.add( (String) derivedScopes );
-                scopes.add( derivedScope );
-                derivedScopes = scopes;
-                changes = CHANGE_SCOPE;
-            }
-            int bit = optional ? OPT_TRUE : OPT_FALSE;
-            if ( ( derivedOptionalities & bit ) == 0 )
-            {
-                derivedOptionalities |= bit;
-                changes |= CHANGE_OPTIONAL;
-            }
-            return changes;
-        }
-
-        void add( ConflictItem item )
-        {
-            if ( children == null )
-            {
-                children = new ArrayList<>( 1 );
-            }
-            children.add( item );
-        }
-
-    }
-
-    final class State
-    {
-
-        /**
-         * The conflict id currently processed.
-         */
-        Object currentId;
-
-        /**
-         * Stats counter.
-         */
-        int totalConflictItems;
-
-        /**
-         * Flag whether we should keep losers in the graph to enable visualization/troubleshooting of conflicts.
-         */
-        final boolean verbose;
-
-        /**
-         * A mapping from conflict id to winner node, helps to recognize nodes that have their effective
-         * scope&optionality set or are leftovers from previous removals.
-         */
-        final Map<Object, DependencyNode> resolvedIds;
-
-        /**
-         * The set of conflict ids which could apply to ancestors of nodes with the current conflict id, used to avoid
-         * recursion early on. This is basically a superset of the key set of resolvedIds, the additional ids account
-         * for cyclic dependencies.
-         */
-        final Collection<Object> potentialAncestorIds;
-
-        /**
-         * The output from the conflict marker
-         */
-        final Map<?, ?> conflictIds;
-
-        /**
-         * The conflict items we have gathered so far for the current conflict id.
-         */
-        final List<ConflictItem> items;
-
-        /**
-         * The (conceptual) mapping from nodes to extra infos, technically keyed by the node's child list which better
-         * captures the identity of a node since we're basically concerned with effects towards children.
-         */
-        final Map<List<DependencyNode>, NodeInfo> infos;
-
-        /**
-         * The set of nodes on the DFS stack to detect cycles, technically keyed by the node's child list to match the
-         * dirty graph structure produced by the dependency collector for cycles.
-         */
-        final Map<List<DependencyNode>, Object> stack;
-
-        /**
-         * The stack of parent nodes.
-         */
-        final List<DependencyNode> parentNodes;
-
-        /**
-         * The stack of derived scopes for parent nodes.
-         */
-        final List<String> parentScopes;
-
-        /**
-         * The stack of derived optional flags for parent nodes.
-         */
-        final List<Boolean> parentOptionals;
-
-        /**
-         * The stack of node infos for parent nodes, may contain {@code null} which is used to disable creating new
-         * conflict items when visiting their parent again (conflict items are meant to be unique by parent-node combo).
-         */
-        final List<NodeInfo> parentInfos;
-
-        /**
-         * The conflict context passed to the version/scope/optionality selectors, updated as we move along rather than
-         * recreated to avoid tmp objects.
-         */
-        final ConflictContext conflictCtx;
-
-        /**
-         * The scope context passed to the scope deriver, updated as we move along rather than recreated to avoid tmp
-         * objects.
-         */
-        final ScopeContext scopeCtx;
-
-        /**
-         * The effective version selector, i.e. after initialization.
-         */
-        final VersionSelector versionSelector;
-
-        /**
-         * The effective scope selector, i.e. after initialization.
-         */
-        final ScopeSelector scopeSelector;
-
-        /**
-         * The effective scope deriver, i.e. after initialization.
-         */
-        final ScopeDeriver scopeDeriver;
-
-        /**
-         * The effective optionality selector, i.e. after initialization.
-         */
-        final OptionalitySelector optionalitySelector;
-
-        State( DependencyNode root, Map<?, ?> conflictIds, int conflictIdCount,
-               DependencyGraphTransformationContext context )
-            throws RepositoryException
-        {
-            this.conflictIds = conflictIds;
-            verbose = ConfigUtils.getBoolean( context.getSession(), false, CONFIG_PROP_VERBOSE );
-            potentialAncestorIds = new HashSet<>( conflictIdCount * 2 );
-            resolvedIds = new HashMap<>( conflictIdCount * 2 );
-            items = new ArrayList<>( 256 );
-            infos = new IdentityHashMap<>( 64 );
-            stack = new IdentityHashMap<>( 64 );
-            parentNodes = new ArrayList<>( 64 );
-            parentScopes = new ArrayList<>( 64 );
-            parentOptionals = new ArrayList<>( 64 );
-            parentInfos = new ArrayList<>( 64 );
-            conflictCtx = new ConflictContext( root, conflictIds, items );
-            scopeCtx = new ScopeContext( null, null );
-            versionSelector = ConflictResolver.this.versionSelector.getInstance( root, context );
-            scopeSelector = ConflictResolver.this.scopeSelector.getInstance( root, context );
-            scopeDeriver = ConflictResolver.this.scopeDeriver.getInstance( root, context );
-            optionalitySelector = ConflictResolver.this.optionalitySelector.getInstance( root, context );
-        }
-
-        void prepare( Object conflictId, Collection<Object> cyclicPredecessors )
-        {
-            currentId = conflictId;
-            conflictCtx.conflictId = conflictId;
-            conflictCtx.winner = null;
-            conflictCtx.scope = null;
-            conflictCtx.optional = null;
-            items.clear();
-            infos.clear();
-            if ( cyclicPredecessors != null )
-            {
-                potentialAncestorIds.addAll( cyclicPredecessors );
-            }
-        }
-
-        void finish()
-        {
-            List<DependencyNode> previousParent = null;
-            int previousDepth = 0;
-            totalConflictItems += items.size();
-            for ( int i = items.size() - 1; i >= 0; i-- )
-            {
-                ConflictItem item = items.get( i );
-                if ( item.parent == previousParent )
-                {
-                    item.depth = previousDepth;
-                }
-                else if ( item.parent != null )
-                {
-                    previousParent = item.parent;
-                    NodeInfo info = infos.get( previousParent );
-                    previousDepth = info.minDepth + 1;
-                    item.depth = previousDepth;
-                }
-            }
-            potentialAncestorIds.add( currentId );
-        }
-
-        void winner()
-        {
-            resolvedIds.put( currentId, ( conflictCtx.winner != null ) ? conflictCtx.winner.node : null );
-        }
-
-        boolean loser( DependencyNode node, Object conflictId )
-        {
-            DependencyNode winner = resolvedIds.get( conflictId );
-            return winner != null && winner != node;
-        }
-
-        boolean push( DependencyNode node, Object conflictId )
-            throws RepositoryException
-        {
-            if ( conflictId == null )
-            {
-                if ( node.getDependency() != null )
-                {
-                    if ( node.getData().get( NODE_DATA_WINNER ) != null )
-                    {
-                        return false;
-                    }
-                    throw new RepositoryException( "missing conflict id for node " + node );
-                }
-            }
-            else if ( !potentialAncestorIds.contains( conflictId ) )
-            {
-                return false;
-            }
-
-            List<DependencyNode> graphNode = node.getChildren();
-            if ( stack.put( graphNode, Boolean.TRUE ) != null )
-            {
-                return false;
-            }
-
-            int depth = depth();
-            String scope = deriveScope( node, conflictId );
-            boolean optional = deriveOptional( node, conflictId );
-            NodeInfo info = infos.get( graphNode );
-            if ( info == null )
-            {
-                info = new NodeInfo( depth, scope, optional );
-                infos.put( graphNode, info );
-                parentInfos.add( info );
-                parentNodes.add( node );
-                parentScopes.add( scope );
-                parentOptionals.add( optional );
-            }
-            else
-            {
-                int changes = info.update( depth, scope, optional );
-                if ( changes == 0 )
-                {
-                    stack.remove( graphNode );
-                    return false;
-                }
-                parentInfos.add( null ); // disable creating new conflict items, we update the existing ones below
-                parentNodes.add( node );
-                parentScopes.add( scope );
-                parentOptionals.add( optional );
-                if ( info.children != null )
-                {
-                    if ( ( changes & NodeInfo.CHANGE_SCOPE ) != 0 )
-                    {
-                        for ( int i = info.children.size() - 1; i >= 0; i-- )
-                        {
-                            ConflictItem item = info.children.get( i );
-                            String childScope = deriveScope( item.node, null );
-                            item.addScope( childScope );
-                        }
-                    }
-                    if ( ( changes & NodeInfo.CHANGE_OPTIONAL ) != 0 )
-                    {
-                        for ( int i = info.children.size() - 1; i >= 0; i-- )
-                        {
-                            ConflictItem item = info.children.get( i );
-                            boolean childOptional = deriveOptional( item.node, null );
-                            item.addOptional( childOptional );
-                        }
-                    }
-                }
-            }
-
-            return true;
-        }
-
-        void pop()
-        {
-            int last = parentInfos.size() - 1;
-            parentInfos.remove( last );
-            parentScopes.remove( last );
-            parentOptionals.remove( last );
-            DependencyNode node = parentNodes.remove( last );
-            stack.remove( node.getChildren() );
-        }
-
-        void add( DependencyNode node )
-            throws RepositoryException
-        {
-            DependencyNode parent = parent();
-            if ( parent == null )
-            {
-                ConflictItem item = newConflictItem( parent, node );
-                items.add( item );
-            }
-            else
-            {
-                NodeInfo info = parentInfos.get( parentInfos.size() - 1 );
-                if ( info != null )
-                {
-                    ConflictItem item = newConflictItem( parent, node );
-                    info.add( item );
-                    items.add( item );
-                }
-            }
-        }
-
-        private ConflictItem newConflictItem( DependencyNode parent, DependencyNode node )
-            throws RepositoryException
-        {
-            return new ConflictItem( parent, node, deriveScope( node, null ), deriveOptional( node, null ) );
-        }
-
-        private int depth()
-        {
-            return parentNodes.size();
-        }
-
-        private DependencyNode parent()
-        {
-            int size = parentNodes.size();
-            return ( size <= 0 ) ? null : parentNodes.get( size - 1 );
-        }
-
-        private String deriveScope( DependencyNode node, Object conflictId )
-            throws RepositoryException
-        {
-            if ( node.getPremanagedScope() != null
-                || ( conflictId != null && resolvedIds.containsKey( conflictId ) ) )
-//            if ( ( node.getManagedBits() & DependencyNode.MANAGED_SCOPE ) != 0
-//                || ( conflictId != null && resolvedIds.containsKey( conflictId ) ) )
-            {
-                return scope( node.getDependency() );
-            }
-
-            int depth = parentNodes.size();
-            scopes( depth, node.getDependency() );
-            if ( depth > 0 )
-            {
-                scopeDeriver.deriveScope( scopeCtx );
-            }
-            return scopeCtx.derivedScope;
-        }
-
-        private void scopes( int parent, Dependency child )
-        {
-            scopeCtx.parentScope = ( parent > 0 ) ? parentScopes.get( parent - 1 ) : null;
-            scopeCtx.derivedScope = scope( child );
-            scopeCtx.childScope = scopeCtx.derivedScope;
-        }
-
-        private String scope( Dependency dependency )
-        {
-            return ( dependency != null ) ? dependency.getScope() : null;
-        }
-
-        private boolean deriveOptional( DependencyNode node, Object conflictId )
-        {
-            Dependency dep = node.getDependency();
-            boolean optional = dep != null && dep.isOptional();
-            if ( optional
-                || ( node.getData().get( NODE_DATA_ORIGINAL_OPTIONALITY ) != null
-                    && (Boolean) node.getData().get( NODE_DATA_ORIGINAL_OPTIONALITY ) )
-                || ( conflictId != null && resolvedIds.containsKey( conflictId ) ) )
-//            if ( optional || ( node.getManagedBits() & DependencyNode.MANAGED_OPTIONAL ) != 0
-//                || ( conflictId != null && resolvedIds.containsKey( conflictId ) ) )
-            {
-                return optional;
-            }
-            int depth = parentNodes.size();
-            return ( depth > 0 ) ? parentOptionals.get( depth - 1 ) : false;
-        }
-
-    }
-
-    /**
-     * A context used to hold information that is relevant for deriving the scope of a child dependency.
-     * 
-     * @see ScopeDeriver
-     * This class is not intended to be instantiated by clients in production code, the constructor may
-     *                change without notice and only exists to enable unit testing.
-     */
-    public static final class ScopeContext
-    {
-
-        String parentScope;
-
-        String childScope;
-
-        String derivedScope;
-
-        /**
-         * Creates a new scope context with the specified properties.
-         * 
-         * @param parentScope The scope of the parent dependency, may be {@code null}.
-         * @param childScope The scope of the child dependency, may be {@code null}.
-         * This class is not intended to be instantiated by clients in production code, the constructor may
-         *              change without notice and only exists to enable unit testing.
-         */
-        public ScopeContext( String parentScope, String childScope )
-        {
-            this.parentScope = ( parentScope != null ) ? parentScope : "";
-            derivedScope = ( childScope != null ) ? childScope : "";
-            this.childScope = derivedScope;
-        }
-
-        /**
-         * Gets the scope of the parent dependency. This is usually the scope that was derived by earlier invocations of
-         * the scope deriver.
-         * 
-         * @return The scope of the parent dependency, never {@code null}.
-         */
-        public String getParentScope()
-        {
-            return parentScope;
-        }
-
-        /**
-         * Gets the original scope of the child dependency. This is the scope that was declared in the artifact
-         * descriptor of the parent dependency.
-         * 
-         * @return The original scope of the child dependency, never {@code null}.
-         */
-        public String getChildScope()
-        {
-            return childScope;
-        }
-
-        /**
-         * Gets the derived scope of the child dependency. This is initially equal to {@link #getChildScope()} until the
-         * scope deriver makes changes.
-         * 
-         * @return The derived scope of the child dependency, never {@code null}.
-         */
-        public String getDerivedScope()
-        {
-            return derivedScope;
-        }
-
-        /**
-         * Sets the derived scope of the child dependency.
-         * 
-         * @param derivedScope The derived scope of the dependency, may be {@code null}.
-         */
-        public void setDerivedScope( String derivedScope )
-        {
-            this.derivedScope = ( derivedScope != null ) ? derivedScope : "";
-        }
-
-    }
-
-    /**
-     * A conflicting dependency.
-     * 
-     * This class is not intended to be instantiated by clients in production code, the constructor may
-     *                change without notice and only exists to enable unit testing.
-     */
-    public static final class ConflictItem
-    {
-
-        // nodes can share child lists, we care about the unique owner of a child node which is the child list
-        final List<DependencyNode> parent;
-
-        // only for debugging/toString() to help identify the parent node(s)
-        final Artifact artifact;
-
-        final DependencyNode node;
-
-        int depth;
-
-        // we start with String and update to Set<String> if needed
-        Object scopes;
-
-        // bit field of OPTIONAL_FALSE and OPTIONAL_TRUE
-        int optionalities;
-
-        /**
-         * Bit flag indicating whether one or more paths consider the dependency non-optional.
-         */
-        public static final int OPTIONAL_FALSE = 0x01;
-
-        /**
-         * Bit flag indicating whether one or more paths consider the dependency optional.
-         */
-        public static final int OPTIONAL_TRUE = 0x02;
-
-        ConflictItem( DependencyNode parent, DependencyNode node, String scope, boolean optional )
-        {
-            if ( parent != null )
-            {
-                this.parent = parent.getChildren();
-                this.artifact = parent.getDependency().getArtifact();
-//                this.artifact = parent.getArtifact();
-            }
-            else
-            {
-                this.parent = null;
-                this.artifact = null;
-            }
-            this.node = node;
-            this.scopes = scope;
-            this.optionalities = optional ? OPTIONAL_TRUE : OPTIONAL_FALSE;
-        }
-
-        /**
-         * Creates a new conflict item with the specified properties.
-         * 
-         * @param parent The parent node of the conflicting dependency, may be {@code null}.
-         * @param node The conflicting dependency, must not be {@code null}.
-         * @param depth The zero-based depth of the conflicting dependency.
-         * @param optionalities The optionalities the dependency was encountered with, encoded as a bit field consisting
-         *            of {@link ConflictResolver.ConflictItem#OPTIONAL_TRUE} and
-         *            {@link ConflictResolver.ConflictItem#OPTIONAL_FALSE}.
-         * @param scopes The derived scopes of the conflicting dependency, must not be {@code null}.
-         * This class is not intended to be instantiated by clients in production code, the constructor may
-         *              change without notice and only exists to enable unit testing.
-         */
-        public ConflictItem( DependencyNode parent, DependencyNode node, int depth, int optionalities,
-                             String... scopes )
-        {
-            this.parent = ( parent != null ) ? parent.getChildren() : null;
-            this.artifact = ( parent != null ) ? parent.getDependency().getArtifact() : null;
-//            this.artifact = ( parent != null ) ? parent.getArtifact() : null;
-            this.node = node;
-            this.depth = depth;
-            this.optionalities = optionalities;
-            this.scopes = Arrays.asList( scopes );
-        }
-
-        /**
-         * Determines whether the specified conflict item is a sibling of this item.
-         * 
-         * @param item The other conflict item, must not be {@code null}.
-         * @return {@code true} if the given item has the same parent as this item, {@code false} otherwise.
-         */
-        public boolean isSibling( ConflictItem item )
-        {
-            return parent == item.parent;
-        }
-
-        /**
-         * Gets the dependency node involved in the conflict.
-         * 
-         * @return The involved dependency node, never {@code null}.
-         */
-        public DependencyNode getNode()
-        {
-            return node;
-        }
-
-        /**
-         * Gets the dependency involved in the conflict, short for {@code getNode.getDependency()}.
-         * 
-         * @return The involved dependency, never {@code null}.
-         */
-        public Dependency getDependency()
-        {
-            return node.getDependency();
-        }
-
-        /**
-         * Gets the zero-based depth at which the conflicting node occurs in the graph. As such, the depth denotes the
-         * number of parent nodes. If actually multiple paths lead to the node, the return value denotes the smallest
-         * possible depth.
-         * 
-         * @return The zero-based depth of the node in the graph.
-         */
-        public int getDepth()
-        {
-            return depth;
-        }
-
-        /**
-         * Gets the derived scopes of the dependency. In general, the same dependency node could be reached via
-         * different paths and each path might result in a different derived scope.
-         * 
-         * @see ScopeDeriver
-         * @return The (read-only) set of derived scopes of the dependency, never {@code null}.
-         */
-        @SuppressWarnings( "unchecked" )
-        public Collection<String> getScopes()
-        {
-            if ( scopes instanceof String )
-            {
-                return Collections.singleton( (String) scopes );
-            }
-            return (Collection<String>) scopes;
-        }
-
-        @SuppressWarnings( "unchecked" )
-        void addScope( String scope )
-        {
-            if ( scopes instanceof Collection )
-            {
-                ( (Collection<String>) scopes ).add( scope );
-            }
-            else if ( !scopes.equals( scope ) )
-            {
-                Collection<Object> set = new HashSet<>();
-                set.add( scopes );
-                set.add( scope );
-                scopes = set;
-            }
-        }
-
-        /**
-         * Gets the derived optionalities of the dependency. In general, the same dependency node could be reached via
-         * different paths and each path might result in a different derived optionality.
-         * 
-         * @return A bit field consisting of {@link ConflictResolver.ConflictItem#OPTIONAL_FALSE} and/or
-         *         {@link ConflictResolver.ConflictItem#OPTIONAL_TRUE} indicating the derived optionalities the
-         *         dependency was encountered with.
-         */
-        public int getOptionalities()
-        {
-            return optionalities;
-        }
-
-        void addOptional( boolean optional )
-        {
-            optionalities |= optional ? OPTIONAL_TRUE : OPTIONAL_FALSE;
-        }
-
-        @Override
-        public String toString()
-        {
-            return node + " @ " + depth + " < " + artifact;
-        }
-
-    }
-
-    /**
-     * A context used to hold information that is relevant for resolving version and scope conflicts.
-     * 
-     * @see VersionSelector
-     * @see ScopeSelector
-     * This class is not intended to be instantiated by clients in production code, the constructor may
-     *                change without notice and only exists to enable unit testing.
-     */
-    public static final class ConflictContext
-    {
-
-        final DependencyNode root;
-
-        final Map<?, ?> conflictIds;
-
-        final Collection<ConflictItem> items;
-
-        Object conflictId;
-
-        ConflictItem winner;
-
-        String scope;
-
-        Boolean optional;
-
-        ConflictContext( DependencyNode root, Map<?, ?> conflictIds, Collection<ConflictItem> items )
-        {
-            this.root = root;
-            this.conflictIds = conflictIds;
-            this.items = Collections.unmodifiableCollection( items );
-        }
-
-        /**
-         * Creates a new conflict context.
-         * 
-         * @param root The root node of the dependency graph, must not be {@code null}.
-         * @param conflictId The conflict id for the set of conflicting dependencies in this context, must not be
-         *            {@code null}.
-         * @param conflictIds The mapping from dependency node to conflict id, must not be {@code null}.
-         * @param items The conflict items in this context, must not be {@code null}.
-         * This class is not intended to be instantiated by clients in production code, the constructor may
-         *              change without notice and only exists to enable unit testing.
-         */
-        public ConflictContext( DependencyNode root, Object conflictId, Map<DependencyNode, Object> conflictIds,
-                                Collection<ConflictItem> items )
-        {
-            this( root, conflictIds, items );
-            this.conflictId = conflictId;
-        }
-
-        /**
-         * Gets the root node of the dependency graph being transformed.
-         * 
-         * @return The root node of the dependeny graph, never {@code null}.
-         */
-        public DependencyNode getRoot()
-        {
-            return root;
-        }
-
-        /**
-         * Determines whether the specified dependency node belongs to this conflict context.
-         * 
-         * @param node The dependency node to check, must not be {@code null}.
-         * @return {@code true} if the given node belongs to this conflict context, {@code false} otherwise.
-         */
-        public boolean isIncluded( DependencyNode node )
-        {
-            return conflictId.equals( conflictIds.get( node ) );
-        }
-
-        /**
-         * Gets the collection of conflict items in this context.
-         * 
-         * @return The (read-only) collection of conflict items in this context, never {@code null}.
-         */
-        public Collection<ConflictItem> getItems()
-        {
-            return items;
-        }
-
-        /**
-         * Gets the conflict item which has been selected as the winner among the conflicting dependencies.
-         * 
-         * @return The winning conflict item or {@code null} if not set yet.
-         */
-        public ConflictItem getWinner()
-        {
-            return winner;
-        }
-
-        /**
-         * Sets the conflict item which has been selected as the winner among the conflicting dependencies.
-         * 
-         * @param winner The winning conflict item, may be {@code null}.
-         */
-        public void setWinner( ConflictItem winner )
-        {
-            this.winner = winner;
-        }
-
-        /**
-         * Gets the effective scope of the winning dependency.
-         * 
-         * @return The effective scope of the winning dependency or {@code null} if none.
-         */
-        public String getScope()
-        {
-            return scope;
-        }
-
-        /**
-         * Sets the effective scope of the winning dependency.
-         * 
-         * @param scope The effective scope, may be {@code null}.
-         */
-        public void setScope( String scope )
-        {
-            this.scope = scope;
-        }
-
-        /**
-         * Gets the effective optional flag of the winning dependency.
-         * 
-         * @return The effective optional flag or {@code null} if none.
-         */
-        public Boolean getOptional()
-        {
-            return optional;
-        }
-
-        /**
-         * Sets the effective optional flag of the winning dependency.
-         * 
-         * @param optional The effective optional flag, may be {@code null}.
-         */
-        public void setOptional( Boolean optional )
-        {
-            this.optional = optional;
-        }
-
-        @Override
-        public String toString()
-        {
-            return winner + " @ " + scope + " < " + items;
-        }
-
-    }
-
-    /**
-     * An extension point of {@link ConflictResolver} that determines the winner among conflicting dependencies. The
-     * winning node (and its children) will be retained in the dependency graph, the other nodes will get removed. The
-     * version selector does not need to deal with potential scope conflicts, these will be addressed afterwards by the
-     * {@link ScopeSelector}. Implementations must be stateless.
-     */
-    public abstract static class VersionSelector
-    {
-
-        /**
-         * Retrieves the version selector for use during the specified graph transformation. The conflict resolver calls
-         * this method once per
-         * {@link ConflictResolver#transformGraph(DependencyNode, DependencyGraphTransformationContext)} invocation to
-         * allow implementations to prepare any auxiliary data that is needed for their operation. Given that
-         * implementations need to be stateless, a new instance needs to be returned to hold such auxiliary data. The
-         * default implementation simply returns the current instance which is appropriate for implementations which do
-         * not require auxiliary data.
-         * 
-         * @param root The root node of the (possibly cyclic!) graph to transform, must not be {@code null}.
-         * @param context The graph transformation context, must not be {@code null}.
-         * @return The scope deriver to use for the given graph transformation, never {@code null}.
-         * @throws RepositoryException If the instance could not be retrieved.
-         */
-        public VersionSelector getInstance( DependencyNode root, DependencyGraphTransformationContext context )
-            throws RepositoryException
-        {
-            return this;
-        }
-
-        /**
-         * Determines the winning node among conflicting dependencies. Implementations will usually iterate
-         * {@link ConflictContext#getItems()}, inspect {@link ConflictItem#getNode()} and eventually call
-         * {@link ConflictContext#setWinner(ConflictResolver.ConflictItem)} to deliver the winner. Failure to select a
-         * winner will automatically fail the entire conflict resolution.
-         * 
-         * @param context The conflict context, must not be {@code null}.
-         * @throws RepositoryException If the version selection failed.
-         */
-        public abstract void selectVersion( ConflictContext context )
-            throws RepositoryException;
-
-    }
-
-    /**
-     * An extension point of {@link ConflictResolver} that determines the effective scope of a dependency from a
-     * potentially conflicting set of {@link ScopeDeriver derived scopes}. The scope selector gets invoked after the
-     * {@link VersionSelector} has picked the winning node. Implementations must be stateless.
-     */
-    public abstract static class ScopeSelector
-    {
-
-        /**
-         * Retrieves the scope selector for use during the specified graph transformation. The conflict resolver calls
-         * this method once per
-         * {@link ConflictResolver#transformGraph(DependencyNode, DependencyGraphTransformationContext)} invocation to
-         * allow implementations to prepare any auxiliary data that is needed for their operation. Given that
-         * implementations need to be stateless, a new instance needs to be returned to hold such auxiliary data. The
-         * default implementation simply returns the current instance which is appropriate for implementations which do
-         * not require auxiliary data.
-         * 
-         * @param root The root node of the (possibly cyclic!) graph to transform, must not be {@code null}.
-         * @param context The graph transformation context, must not be {@code null}.
-         * @return The scope selector to use for the given graph transformation, never {@code null}.
-         * @throws RepositoryException If the instance could not be retrieved.
-         */
-        public ScopeSelector getInstance( DependencyNode root, DependencyGraphTransformationContext context )
-            throws RepositoryException
-        {
-            return this;
-        }
-
-        /**
-         * Determines the effective scope of the dependency given by {@link ConflictContext#getWinner()}.
-         * Implementations will usually iterate {@link ConflictContext#getItems()}, inspect
-         * {@link ConflictItem#getScopes()} and eventually call {@link ConflictContext#setScope(String)} to deliver the
-         * effective scope.
-         * 
-         * @param context The conflict context, must not be {@code null}.
-         * @throws RepositoryException If the scope selection failed.
-         */
-        public abstract void selectScope( ConflictContext context )
-            throws RepositoryException;
-
-    }
-
-    /**
-     * An extension point of {@link ConflictResolver} that determines the scope of a dependency in relation to the scope
-     * of its parent. Implementations must be stateless.
-     */
-    public abstract static class ScopeDeriver
-    {
-
-        /**
-         * Retrieves the scope deriver for use during the specified graph transformation. The conflict resolver calls
-         * this method once per
-         * {@link ConflictResolver#transformGraph(DependencyNode, DependencyGraphTransformationContext)} invocation to
-         * allow implementations to prepare any auxiliary data that is needed for their operation. Given that
-         * implementations need to be stateless, a new instance needs to be returned to hold such auxiliary data. The
-         * default implementation simply returns the current instance which is appropriate for implementations which do
-         * not require auxiliary data.
-         * 
-         * @param root The root node of the (possibly cyclic!) graph to transform, must not be {@code null}.
-         * @param context The graph transformation context, must not be {@code null}.
-         * @return The scope deriver to use for the given graph transformation, never {@code null}.
-         * @throws RepositoryException If the instance could not be retrieved.
-         */
-        public ScopeDeriver getInstance( DependencyNode root, DependencyGraphTransformationContext context )
-            throws RepositoryException
-        {
-            return this;
-        }
-
-        /**
-         * Determines the scope of a dependency in relation to the scope of its parent. Implementors need to call
-         * {@link ScopeContext#setDerivedScope(String)} to deliver the result of their calculation. If said method is
-         * not invoked, the conflict resolver will assume the scope of the child dependency remains unchanged.
-         * 
-         * @param context The scope context, must not be {@code null}.
-         * @throws RepositoryException If the scope deriviation failed.
-         */
-        public abstract void deriveScope( ScopeContext context )
-            throws RepositoryException;
-
-    }
-
-    /**
-     * An extension point of {@link ConflictResolver} that determines the effective optional flag of a dependency from a
-     * potentially conflicting set of derived optionalities. The optionality selector gets invoked after the
-     * {@link VersionSelector} has picked the winning node. Implementations must be stateless.
-     */
-    public abstract static class OptionalitySelector
-    {
-
-        /**
-         * Retrieves the optionality selector for use during the specified graph transformation. The conflict resolver
-         * calls this method once per
-         * {@link ConflictResolver#transformGraph(DependencyNode, DependencyGraphTransformationContext)} invocation to
-         * allow implementations to prepare any auxiliary data that is needed for their operation. Given that
-         * implementations need to be stateless, a new instance needs to be returned to hold such auxiliary data. The
-         * default implementation simply returns the current instance which is appropriate for implementations which do
-         * not require auxiliary data.
-         * 
-         * @param root The root node of the (possibly cyclic!) graph to transform, must not be {@code null}.
-         * @param context The graph transformation context, must not be {@code null}.
-         * @return The optionality selector to use for the given graph transformation, never {@code null}.
-         * @throws RepositoryException If the instance could not be retrieved.
-         */
-        public OptionalitySelector getInstance( DependencyNode root, DependencyGraphTransformationContext context )
-            throws RepositoryException
-        {
-            return this;
-        }
-
-        /**
-         * Determines the effective optional flag of the dependency given by {@link ConflictContext#getWinner()}.
-         * Implementations will usually iterate {@link ConflictContext#getItems()}, inspect
-         * {@link ConflictItem#getOptionalities()} and eventually call {@link ConflictContext#setOptional(Boolean)} to
-         * deliver the effective optional flag.
-         * 
-         * @param context The conflict context, must not be {@code null}.
-         * @throws RepositoryException If the optionality selection failed.
-         */
-        public abstract void selectOptionality( ConflictContext context )
-            throws RepositoryException;
-
-    }
-
-}
diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ExclusionDependencySelector.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ExclusionDependencySelector.java
deleted file mode 100644
index 2808595..0000000
--- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/ExclusionDependencySelector.java
+++ /dev/null
@@ -1,228 +0,0 @@
-package org.apache.maven.shared.dependency.graph.internal.maven30;
-
-/*
- * 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.Arrays;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.TreeSet;
-
-import org.sonatype.aether.artifact.Artifact;
-import org.sonatype.aether.collection.DependencyCollectionContext;
-import org.sonatype.aether.collection.DependencySelector;
-import org.sonatype.aether.graph.Dependency;
-import org.sonatype.aether.graph.Exclusion;
-
-/**
- * This class is a copy of their homonymous in the Eclipse Aether library, adapted to work with Sonatype Aether.
- * 
- * @author Gabriel Belingueres
- * @since 3.1.0
- */
-public class ExclusionDependencySelector
-    implements DependencySelector
-{
-
-    // sorted and dupe-free array, faster to iterate than LinkedHashSet
-    private final Exclusion[] exclusions;
-
-    private int hashCode;
-
-    /**
-     * Creates a new selector without any exclusions.
-     */
-    public ExclusionDependencySelector()
-    {
-        this.exclusions = new Exclusion[0];
-    }
-
-    /**
-     * Creates a new selector with the specified exclusions.
-     * 
-     * @param exclusions The exclusions, may be {@code null}.
-     */
-    public ExclusionDependencySelector( Collection<Exclusion> exclusions )
-    {
-        if ( exclusions != null && !exclusions.isEmpty() )
-        {
-            TreeSet<Exclusion> sorted = new TreeSet<>( ExclusionComparator.INSTANCE );
-            sorted.addAll( exclusions );
-            this.exclusions = sorted.toArray( new Exclusion[0] );
-        }
-        else
-        {
-            this.exclusions = new Exclusion[0];
-        }
-    }
-
-    private ExclusionDependencySelector( Exclusion[] exclusions )
-    {
-        this.exclusions = exclusions;
-    }
-
-    public boolean selectDependency( Dependency dependency )
-    {
-        Artifact artifact = dependency.getArtifact();
-        for ( Exclusion exclusion : exclusions )
-        {
-            if ( matches( exclusion, artifact ) )
-            {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private boolean matches( Exclusion exclusion, Artifact artifact )
-    {
-        if ( !matches( exclusion.getArtifactId(), artifact.getArtifactId() ) )
-        {
-            return false;
-        }
-        if ( !matches( exclusion.getGroupId(), artifact.getGroupId() ) )
-        {
-            return false;
-        }
-        if ( !matches( exclusion.getExtension(), artifact.getExtension() ) )
-        {
-            return false;
-        }
-        if ( !matches( exclusion.getClassifier(), artifact.getClassifier() ) )
-        {
-            return false;
-        }
-        return true;
-    }
-
-    private boolean matches( String pattern, String value )
-    {
-        return "*".equals( pattern ) || pattern.equals( value );
-    }
-
-    public DependencySelector deriveChildSelector( DependencyCollectionContext context )
-    {
-        Dependency dependency = context.getDependency();
-        Collection<Exclusion> exclusions = ( dependency != null ) ? dependency.getExclusions() : null;
-        if ( exclusions == null || exclusions.isEmpty() )
-        {
-            return this;
-        }
-
-        Exclusion[] merged = this.exclusions;
-        int count = merged.length;
-        for ( Exclusion exclusion : exclusions )
-        {
-            int index = Arrays.binarySearch( merged, exclusion, ExclusionComparator.INSTANCE );
-            if ( index < 0 )
-            {
-                index = -( index + 1 );
-                if ( count >= merged.length )
-                {
-                    Exclusion[] tmp = new Exclusion[merged.length + exclusions.size()];
-                    System.arraycopy( merged, 0, tmp, 0, index );
-                    tmp[index] = exclusion;
-                    System.arraycopy( merged, index, tmp, index + 1, count - index );
-                    merged = tmp;
-                }
-                else
-                {
-                    System.arraycopy( merged, index, merged, index + 1, count - index );
-                    merged[index] = exclusion;
-                }
-                count++;
-            }
-        }
-        if ( merged == this.exclusions )
-        {
-            return this;
-        }
-        if ( merged.length != count )
-        {
-            Exclusion[] tmp = new Exclusion[count];
-            System.arraycopy( merged, 0, tmp, 0, count );
-            merged = tmp;
-        }
-
-        return new ExclusionDependencySelector( merged );
-    }
-
-    @Override
-    public boolean equals( Object obj )
-    {
-        if ( this == obj )
-        {
-            return true;
-        }
-        else if ( null == obj || !getClass().equals( obj.getClass() ) )
-        {
-            return false;
-        }
-
-        ExclusionDependencySelector that = (ExclusionDependencySelector) obj;
-        return Arrays.equals( exclusions, that.exclusions );
-    }
-
-    @Override
-    public int hashCode()
-    {
-        if ( hashCode == 0 )
-        {
-            int hash = getClass().hashCode();
-            hash = hash * 31 + Arrays.hashCode( exclusions );
-            hashCode = hash;
-        }
-        return hashCode;
-    }
-
-    private static class ExclusionComparator
-        implements Comparator<Exclusion>
-    {
-
-        static final ExclusionComparator INSTANCE = new ExclusionComparator();
-
-        public int compare( Exclusion e1, Exclusion e2 )
-        {
-            if ( e1 == null )
-            {
-                return ( e2 == null ) ? 0 : 1;
-            }
-            else if ( e2 == null )
-            {
-                return -1;
-            }
-            int rel = e1.getArtifactId().compareTo( e2.getArtifactId() );
-            if ( rel == 0 )
-            {
-                rel = e1.getGroupId().compareTo( e2.getGroupId() );
-                if ( rel == 0 )
-                {
-                    rel = e1.getExtension().compareTo( e2.getExtension() );
-                    if ( rel == 0 )
-                    {
-                        rel = e1.getClassifier().compareTo( e2.getClassifier() );
-                    }
-                }
-            }
-            return rel;
-        }
-
-    }
-
-}
diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/JavaScopeDeriver.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/JavaScopeDeriver.java
deleted file mode 100644
index d35abf0..0000000
--- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/JavaScopeDeriver.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package org.apache.maven.shared.dependency.graph.internal.maven30;
-
-/*
- * 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.dependency.graph.internal.maven30.ConflictResolver.ScopeContext;
-import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ScopeDeriver;
-import org.sonatype.aether.RepositoryException;
-import org.sonatype.aether.util.artifact.JavaScopes;
-
-/**
- * This class is a copy of their homonymous in the Eclipse Aether library, adapted to work with Sonatype Aether.
- * 
- * @author Gabriel Belingueres
- * @since 3.1.0
- */
-public class JavaScopeDeriver
-    extends ScopeDeriver
-{
-
-    @Override
-    public void deriveScope( ScopeContext context )
-        throws RepositoryException
-    {
-        context.setDerivedScope( getDerivedScope( context.getParentScope(), context.getChildScope() ) );
-    }
-
-    private String getDerivedScope( String parentScope, String childScope )
-    {
-        String derivedScope;
-
-        if ( JavaScopes.SYSTEM.equals( childScope ) || JavaScopes.TEST.equals( childScope ) )
-        {
-            derivedScope = childScope;
-        }
-        else if ( parentScope == null || parentScope.length() <= 0 || JavaScopes.COMPILE.equals( parentScope ) )
-        {
-            derivedScope = childScope;
-        }
-        else if ( JavaScopes.TEST.equals( parentScope ) || JavaScopes.RUNTIME.equals( parentScope ) )
-        {
-            derivedScope = parentScope;
-        }
-        else if ( JavaScopes.SYSTEM.equals( parentScope ) || JavaScopes.PROVIDED.equals( parentScope ) )
-        {
-            derivedScope = JavaScopes.PROVIDED;
-        }
-        else
-        {
-            derivedScope = JavaScopes.RUNTIME;
-        }
-
-        return derivedScope;
-    }
-
-}
diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/JavaScopeSelector.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/JavaScopeSelector.java
deleted file mode 100644
index 1950a92..0000000
--- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/JavaScopeSelector.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package org.apache.maven.shared.dependency.graph.internal.maven30;
-
-/*
- * 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 java.util.HashSet;
-import java.util.Set;
-
-import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ConflictContext;
-import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ConflictItem;
-import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ScopeSelector;
-import org.sonatype.aether.RepositoryException;
-import org.sonatype.aether.util.artifact.JavaScopes;
-
-/**
- * This class is a copy of their homonymous in the Eclipse Aether library, adapted to work with Sonatype Aether.
- * 
- * @author Gabriel Belingueres
- * @since 3.1.0
- */
-public final class JavaScopeSelector
-    extends ScopeSelector
-{
-
-    @Override
-    public void selectScope( ConflictContext context )
-        throws RepositoryException
-    {
-        String scope = context.getWinner().getDependency().getScope();
-        if ( !JavaScopes.SYSTEM.equals( scope ) )
-        {
-            scope = chooseEffectiveScope( context.getItems() );
-        }
-        context.setScope( scope );
-    }
-
-    private String chooseEffectiveScope( Collection<ConflictItem> items )
-    {
-        Set<String> scopes = new HashSet<>();
-        for ( ConflictItem item : items )
-        {
-            if ( item.getDepth() <= 1 )
-            {
-                return item.getDependency().getScope();
-            }
-            scopes.addAll( item.getScopes() );
-        }
-        return chooseEffectiveScope( scopes );
-    }
-
-    private String chooseEffectiveScope( Set<String> scopes )
-    {
-        if ( scopes.size() > 1 )
-        {
-            scopes.remove( JavaScopes.SYSTEM );
-        }
-
-        String effectiveScope = "";
-
-        if ( scopes.size() == 1 )
-        {
-            effectiveScope = scopes.iterator().next();
-        }
-        else if ( scopes.contains( JavaScopes.COMPILE ) )
-        {
-            effectiveScope = JavaScopes.COMPILE;
-        }
-        else if ( scopes.contains( JavaScopes.RUNTIME ) )
-        {
-            effectiveScope = JavaScopes.RUNTIME;
-        }
-        else if ( scopes.contains( JavaScopes.PROVIDED ) )
-        {
-            effectiveScope = JavaScopes.PROVIDED;
-        }
-        else if ( scopes.contains( JavaScopes.TEST ) )
-        {
-            effectiveScope = JavaScopes.TEST;
-        }
-
-        return effectiveScope;
-    }
-
-
-}
diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/Maven3DirectScopeDependencySelector.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/Maven3DirectScopeDependencySelector.java
deleted file mode 100644
index 9373b90..0000000
--- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/Maven3DirectScopeDependencySelector.java
+++ /dev/null
@@ -1,132 +0,0 @@
-package org.apache.maven.shared.dependency.graph.internal.maven30;
-
-/*
- * 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.sonatype.aether.collection.DependencyCollectionContext;
-import org.sonatype.aether.collection.DependencySelector;
-import org.sonatype.aether.graph.Dependency;
-
-/**
- * A dependency selector that excludes dependencies of an specific Scope which occur beyond level one of the dependency
- * graph.
- * 
- * @see Dependency#getScope()
- * @author Gabriel Belingueres
- * @since 3.1.0
- */
-public class Maven3DirectScopeDependencySelector
-    implements DependencySelector
-{
-
-    private final String scope;
-
-    private final int depth;
-
-    public Maven3DirectScopeDependencySelector( String scope )
-    {
-        this( scope, 0 );
-    }
-
-    private Maven3DirectScopeDependencySelector( String scope, int depth )
-    {
-        if ( scope == null )
-        {
-            throw new IllegalArgumentException( "scope is null!" );
-        }
-        this.scope = scope;
-        this.depth = depth;
-    }
-
-    /**
-     * Decides whether the specified dependency should be included in the dependency graph.
-     * 
-     * @param dependency The dependency to check, must not be {@code null}.
-     * @return {@code false} if the dependency should be excluded from the children of the current node, {@code true}
-     *         otherwise.
-     */
-    @Override
-    public boolean selectDependency( Dependency dependency )
-    {
-        return depth < 2 || !scope.equals( dependency.getScope() );
-    }
-
-    /**
-     * Derives a dependency selector for the specified collection context. When calculating the child selector,
-     * implementors are strongly advised to simply return the current instance if nothing changed to help save memory.
-     * 
-     * @param context The dependency collection context, must not be {@code null}.
-     * @return The dependency selector for the target node, must not be {@code null}.
-     */
-    @Override
-    public DependencySelector deriveChildSelector( DependencyCollectionContext context )
-    {
-        if ( depth >= 2 )
-        {
-            return this;
-        }
-
-        return new Maven3DirectScopeDependencySelector( scope, depth + 1 );
-    }
-
-    @Override
-    public int hashCode()
-    {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + depth;
-        result = prime * result + ( ( scope == null ) ? 0 : scope.hashCode() );
-        return result;
-    }
-
-    @Override
-    public boolean equals( Object obj )
-    {
-        if ( this == obj )
-        {
-            return true;
-        }
-        if ( obj == null )
-        {
-            return false;
-        }
-        if ( getClass() != obj.getClass() )
-        {
-            return false;
-        }
-        Maven3DirectScopeDependencySelector other = (Maven3DirectScopeDependencySelector) obj;
-        if ( depth != other.depth )
-        {
-            return false;
-        }
-        if ( scope == null )
-        {
-            if ( other.scope != null )
-            {
-                return false;
-            }
-        }
-        else if ( !scope.equals( other.scope ) )
-        {
-            return false;
-        }
-        return true;
-    }
-
-}
diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/NearestVersionSelector.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/NearestVersionSelector.java
deleted file mode 100644
index 31af5b8..0000000
--- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/NearestVersionSelector.java
+++ /dev/null
@@ -1,176 +0,0 @@
-package org.apache.maven.shared.dependency.graph.internal.maven30;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-
-import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ConflictContext;
-import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ConflictItem;
-import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.VersionSelector;
-import org.sonatype.aether.RepositoryException;
-import org.sonatype.aether.collection.UnsolvableVersionConflictException;
-import org.sonatype.aether.graph.DependencyFilter;
-import org.sonatype.aether.graph.DependencyNode;
-import org.sonatype.aether.util.graph.PathRecordingDependencyVisitor;
-import org.sonatype.aether.version.Version;
-import org.sonatype.aether.version.VersionConstraint;
-
-/**
- * This class is a copy of their homonymous in the Eclipse Aether library, adapted to work with Sonatype Aether.
- * 
- * @author Gabriel Belingueres
- * @since 3.1.0
- */
-public final class NearestVersionSelector
-    extends VersionSelector
-{
-
-    @Override
-    public void selectVersion( ConflictContext context )
-        throws RepositoryException
-    {
-        ConflictGroup group = new ConflictGroup();
-        for ( ConflictItem item : context.getItems() )
-        {
-            DependencyNode node = item.getNode();
-            VersionConstraint constraint = node.getVersionConstraint();
-
-            boolean backtrack = false;
-            boolean hardConstraint = !constraint.getRanges().isEmpty();
-//            boolean hardConstraint = constraint.getRange() != null;
-
-            if ( hardConstraint )
-            {
-                if ( group.constraints.add( constraint ) )
-                {
-                    if ( group.winner != null && !constraint.containsVersion( group.winner.getNode().getVersion() ) )
-                    {
-                        backtrack = true;
-                    }
-                }
-            }
-
-            if ( isAcceptable( group, node.getVersion() ) )
-            {
-                group.candidates.add( item );
-
-                if ( backtrack )
-                {
-                    backtrack( group, context );
-                }
-                else if ( group.winner == null || isNearer( item, group.winner ) )
-                {
-                    group.winner = item;
-                }
-            }
-            else if ( backtrack )
-            {
-                backtrack( group, context );
-            }
-        }
-        context.setWinner( group.winner );
-    }
-
-    private void backtrack( ConflictGroup group, ConflictContext context )
-        throws UnsolvableVersionConflictException
-    {
-        group.winner = null;
-
-        for ( Iterator<ConflictItem> it = group.candidates.iterator(); it.hasNext(); )
-        {
-            ConflictItem candidate = it.next();
-
-            if ( !isAcceptable( group, candidate.getNode().getVersion() ) )
-            {
-                it.remove();
-            }
-            else if ( group.winner == null || isNearer( candidate, group.winner ) )
-            {
-                group.winner = candidate;
-            }
-        }
-
-        if ( group.winner == null )
-        {
-            throw newFailure( context );
-        }
-    }
-
-    private boolean isAcceptable( ConflictGroup group, Version version )
-    {
-        for ( VersionConstraint constraint : group.constraints )
-        {
-            if ( !constraint.containsVersion( version ) )
-            {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private boolean isNearer( ConflictItem item1, ConflictItem item2 )
-    {
-        if ( item1.isSibling( item2 ) )
-        {
-            return item1.getNode().getVersion().compareTo( item2.getNode().getVersion() ) > 0;
-        }
-        else
-        {
-            return item1.getDepth() < item2.getDepth();
-        }
-    }
-
-    private UnsolvableVersionConflictException newFailure( final ConflictContext context )
-    {
-        DependencyFilter filter = ( node, parents ) -> context.isIncluded( node );
-        PathRecordingDependencyVisitor visitor = new PathRecordingDependencyVisitor( filter );
-        context.getRoot().accept( visitor );
-        return new UnsolvableVersionConflictException( visitor.getPaths(), context.conflictId );
-//        return new UnsolvableVersionConflictException( visitor.getPaths() );
-    }
-
-    static final class ConflictGroup
-    {
-
-        final Collection<VersionConstraint> constraints;
-
-        final Collection<ConflictItem> candidates;
-
-        ConflictItem winner;
-
-        ConflictGroup()
-        {
-            constraints = new HashSet<>();
-            candidates = new ArrayList<>( 64 );
-        }
-
-        @Override
-        public String toString()
-        {
-            return String.valueOf( winner );
-        }
-
-    }
-
-
-}
diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/SimpleOptionalitySelector.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/SimpleOptionalitySelector.java
deleted file mode 100644
index d63df0b..0000000
--- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/SimpleOptionalitySelector.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package org.apache.maven.shared.dependency.graph.internal.maven30;
-
-/*
- * 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.shared.dependency.graph.internal.maven30.ConflictResolver.ConflictContext;
-import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ConflictItem;
-import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.OptionalitySelector;
-import org.sonatype.aether.RepositoryException;
-
-/**
- * This class is a copy of their homonymous in the Eclipse Aether library, adapted to work with Sonatype Aether.
- * 
- * @author Gabriel Belingueres
- * @since 3.1.0
- */
-public class SimpleOptionalitySelector
-    extends OptionalitySelector
-{
-
-    @Override
-    public void selectOptionality( ConflictContext context )
-        throws RepositoryException
-    {
-        boolean optional = chooseEffectiveOptionality( context.getItems() );
-        context.setOptional( optional );
-    }
-
-    private boolean chooseEffectiveOptionality( Collection<ConflictItem> items )
-    {
-        boolean optional = true;
-        for ( ConflictItem item : items )
-        {
-            if ( item.getDepth() <= 1 )
-            {
-                return item.getDependency().isOptional();
-            }
-            if ( ( item.getOptionalities() & ConflictItem.OPTIONAL_FALSE ) != 0 )
-            {
-                optional = false;
-            }
-        }
-        return optional;
-    }
-
-}
\ No newline at end of file
diff --git a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/VerboseJavaScopeSelector.java b/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/VerboseJavaScopeSelector.java
deleted file mode 100644
index 85b660d..0000000
--- a/src/main/java/org/apache/maven/shared/dependency/graph/internal/maven30/VerboseJavaScopeSelector.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package org.apache.maven.shared.dependency.graph.internal.maven30;
-
-/*
- * 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.Arrays;
-import java.util.Comparator;
-import java.util.List;
-
-import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ConflictContext;
-import org.apache.maven.shared.dependency.graph.internal.maven30.ConflictResolver.ScopeSelector;
-import org.sonatype.aether.RepositoryException;
-
-/**
- * A JavaScopeSelector that keeps track of reduced scopes
- * 
- */
-public class VerboseJavaScopeSelector extends ScopeSelector
-{
-    public static final String REDUCED_SCOPE = "REDUCED_SCOPE";
-    
-    private final ScopeSelector scopeSelector = new JavaScopeSelector();
-
-    @Override
-    public void selectScope( ConflictContext context )
-        throws RepositoryException
-    {
-        scopeSelector.selectScope( context );
-        
-        context.getItems().stream()
-            .flatMap( i -> i.getScopes().stream() )
-            .distinct()
-            .max( new ScopeComparator() )
-            .filter( s -> s != context.getScope() )
-            .ifPresent( s -> context.getWinner().getNode().setData( REDUCED_SCOPE, s ) );
-    }
-    
-    static class ScopeComparator implements Comparator<String>
-    {
-        List<String> orderedScopes = Arrays.asList( "compile", "runtime", "provided", "test" );
-
-        @Override
-        public int compare( String lhs, String rhs )
-        {
-            return orderedScopes.indexOf( rhs ) - orderedScopes.indexOf( lhs );
-        }
-    }    
-}
