You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ti...@apache.org on 2019/02/28 06:24:36 UTC

[maven-surefire] branch SUREFIRE-1585-tibor2 updated (6916415 -> d1d2a20)

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

tibordigana pushed a change to branch SUREFIRE-1585-tibor2
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git.


 discard 6916415  [SUREFIRE-1585] Align JUnit Platform version at runtime
 discard 828d9a3  [SUREFIRE-1585] Align JUnit Platform version at runtime
 discard 1081e1a  [SUREFIRE-1585] Align JUnit Platform version at runtime
 discard 47d4ff3  [SUREFIRE-1585] Align JUnit Platform version at runtime
 discard c03e5aa  [SUREFIRE-1585] Align JUnit Platform version at runtime
 discard e72bd19  [SUREFIRE-1585] Align JUnit Platform version at runtime
 discard 36f777c  [SUREFIRE-1585] Align JUnit Platform version at runtime
 discard f33943f  [SUREFIRE-1585] Align JUnit Platform version at runtime
    omit afdc189  [SUREFIRE-1585] Align JUnit Platform version at runtime
     add 275087c  next version 3.0.0-SNAPSHOT
     add 3316bea  temporarily removed deployment
     new 0feaf30  [SUREFIRE-1585] Align JUnit Platform version at runtime
     new d1d2a20  [SUREFIRE-1585] Align JUnit Platform version at runtime

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (6916415)
            \
             N -- N -- N   refs/heads/SUREFIRE-1585-tibor2 (d1d2a20)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

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


Summary of changes:
 Jenkinsfile                                        |  2 +-
 maven-failsafe-plugin/pom.xml                      | 10 +++++-----
 maven-surefire-common/pom.xml                      |  2 +-
 maven-surefire-plugin/pom.xml                      |  2 +-
 maven-surefire-report-plugin/pom.xml               |  2 +-
 pom.xml                                            |  2 +-
 surefire-api/pom.xml                               |  6 +++---
 surefire-booter/pom.xml                            |  2 +-
 surefire-grouper/pom.xml                           |  2 +-
 surefire-its/pom.xml                               |  2 +-
 surefire-logger-api/pom.xml                        |  4 ++--
 surefire-providers/common-java5/pom.xml            |  6 +++---
 surefire-providers/common-junit3/pom.xml           |  2 +-
 surefire-providers/common-junit4/pom.xml           |  2 +-
 surefire-providers/common-junit48/pom.xml          |  2 +-
 surefire-providers/pom.xml                         |  2 +-
 surefire-providers/surefire-junit-platform/pom.xml |  2 +-
 surefire-providers/surefire-junit3/pom.xml         |  2 +-
 surefire-providers/surefire-junit4/pom.xml         |  2 +-
 surefire-providers/surefire-junit47/pom.xml        |  2 +-
 surefire-providers/surefire-testng-utils/pom.xml   |  2 +-
 surefire-providers/surefire-testng/pom.xml         |  2 +-
 surefire-report-parser/pom.xml                     |  6 +++---
 surefire-shadefire/pom.xml                         |  2 +-
 24 files changed, 35 insertions(+), 35 deletions(-)


[maven-surefire] 01/02: [SUREFIRE-1585] Align JUnit Platform version at runtime

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

tibordigana pushed a commit to branch SUREFIRE-1585-tibor2
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git

commit 0feaf301a2f820d6878e8af80f54411478ac3237
Author: tibordigana <ti...@apache.org>
AuthorDate: Fri Feb 1 06:03:27 2019 +0100

    [SUREFIRE-1585] Align JUnit Platform version at runtime
---
 maven-surefire-common/pom.xml                      |    8 +-
 .../plugin/surefire/AbstractSurefireMojo.java      |  352 ++++--
 .../apache/maven/plugin/surefire/ProviderInfo.java |    2 +-
 .../surefire/SurefireDependencyResolver.java       |  103 +-
 .../maven/plugin/surefire/TestClassPath.java       |   34 +-
 .../AbstractSurefireMojoJava7PlusTest.java         |    5 +-
 .../plugin/surefire/AbstractSurefireMojoTest.java  | 1271 +++++++++++++++++++-
 .../surefire/SurefireDependencyResolverTest.java   |    8 +-
 .../src/site/apt/examples/junit-platform.apt.vm    |  110 +-
 pom.xml                                            |   39 +-
 .../maven/surefire/its/JUnitPlatformEnginesIT.java |    8 +-
 .../maven/surefire/its/jiras/Surefire1585IT.java   |   54 +
 .../resources/surefire-1585-junit4-vintage/pom.xml |   61 +
 .../src/test/java/JUnit4Test.java                  |   26 +-
 .../resources/surefire-1585-jupiter-api/pom.xml    |   54 +
 .../src/test/java/JupiterTest.java                 |   28 +-
 16 files changed, 1950 insertions(+), 213 deletions(-)

diff --git a/maven-surefire-common/pom.xml b/maven-surefire-common/pom.xml
index 57adfa9..6fe1024 100644
--- a/maven-surefire-common/pom.xml
+++ b/maven-surefire-common/pom.xml
@@ -81,6 +81,10 @@
             <artifactId>maven-common-artifact-filters</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.apache.maven.shared</groupId>
+            <artifactId>maven-artifact-transfer</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.codehaus.plexus</groupId>
             <artifactId>plexus-java</artifactId>
         </dependency>
@@ -165,8 +169,8 @@
                             </artifactSet>
                             <relocations>
                                 <relocation>
-                                    <pattern>org.apache.maven.shared</pattern>
-                                    <shadedPattern>org.apache.maven.surefire.shade.common.org.apache.maven.shared</shadedPattern>
+                                    <pattern>org.apache.maven.shared.utils</pattern>
+                                    <shadedPattern>org.apache.maven.surefire.shade.common.org.apache.maven.shared.utils</shadedPattern>
                                 </relocation>
                                 <relocation>
                                     <pattern>org.apache.commons.io</pattern>
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
index 7c76ef1..ba7f1e0 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
@@ -21,8 +21,12 @@ package org.apache.maven.plugin.surefire;
  */
 
 import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
 import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.model.Dependency;
 import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.repository.RepositorySystem;
 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
 import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
@@ -50,6 +54,7 @@ import org.apache.maven.plugin.surefire.util.DirectoryScanner;
 import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.shared.artifact.filter.PatternIncludesArtifactFilter;
+import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver;
 import org.apache.maven.shared.utils.io.FileUtils;
 import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
 import org.apache.maven.surefire.booter.Classpath;
@@ -90,6 +95,7 @@ import java.math.BigDecimal;
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -112,6 +118,7 @@ import static java.util.Collections.singletonList;
 import static java.util.Collections.singletonMap;
 import static org.apache.commons.lang3.StringUtils.substringBeforeLast;
 import static org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS;
+import static org.apache.maven.artifact.ArtifactUtils.artifactMapByVersionlessId;
 import static org.apache.maven.plugin.surefire.SurefireDependencyResolver.isWithinVersionSpec;
 import static org.apache.maven.plugin.surefire.util.DependencyScanner.filter;
 import static org.apache.maven.plugin.surefire.SurefireHelper.replaceThreadNumberPlaceholders;
@@ -478,15 +485,6 @@ public abstract class AbstractSurefireMojo
     private String junitArtifactName;
 
     /**
-     * Allows you to specify the name of the JUnit Platform artifact.
-     * If not set, {@code org.junit.platform:junit-platform-engine} will be used.
-     *
-     * @since 2.22.0
-     */
-    @Parameter( property = "junitPlatformArtifactName", defaultValue = "org.junit.platform:junit-platform-engine" )
-    private String junitPlatformArtifactName;
-
-    /**
      * Allows you to specify the name of the TestNG artifact. If not set, {@code org.testng:testng} will be used.
      *
      * @since 2.3.1
@@ -663,6 +661,9 @@ public abstract class AbstractSurefireMojo
     @Parameter( defaultValue = "${project.pluginArtifactRepositories}", readonly = true, required = true )
     private List<ArtifactRepository> remoteRepositories;
 
+    @Parameter( defaultValue = "${project.remoteArtifactRepositories}", required = true, readonly = true )
+    private List<ArtifactRepository> projectRemoteRepositories;
+
     /**
      * Flag to disable the generation of report files in xml format.
      *
@@ -737,6 +738,9 @@ public abstract class AbstractSurefireMojo
     @Component
     private RepositorySystem repositorySystem;
 
+    @Component
+    private DependencyResolver dependencyResolver;
+
     private Artifact surefireBooterArtifact;
 
     private Toolchain toolchain;
@@ -798,7 +802,7 @@ public abstract class AbstractSurefireMojo
      */
     protected Artifact getMojoArtifact()
     {
-        return pluginDescriptor.getPluginArtifact();
+        return getPluginDescriptor().getPluginArtifact();
     }
 
     private String getDefaultExcludes()
@@ -806,7 +810,7 @@ public abstract class AbstractSurefireMojo
         return "**/*$*";
     }
 
-    private SurefireDependencyResolver dependencyResolver;
+    private SurefireDependencyResolver surefireDependencyResolver;
 
     private TestListResolver specificTests;
 
@@ -842,6 +846,11 @@ public abstract class AbstractSurefireMojo
         }
     }
 
+    void setLogger( Logger logger )
+    {
+        this.logger = logger;
+    }
+
     @Nonnull
     protected final PluginConsoleLogger getConsoleLogger()
     {
@@ -860,9 +869,22 @@ public abstract class AbstractSurefireMojo
 
     private void setupStuff()
     {
-        createDependencyResolver();
-        surefireBooterArtifact = getSurefireBooterArtifact();
-        toolchain = getToolchain();
+        surefireDependencyResolver = new SurefireDependencyResolver( getRepositorySystem(),
+                getConsoleLogger(), getLocalRepository(),
+                getRemoteRepositories(),
+                getProjectRemoteRepositories(),
+                getPluginName(), getDependencyResolver() );
+
+        surefireBooterArtifact = getBooterArtifact();
+        if ( surefireBooterArtifact == null )
+        {
+            throw new RuntimeException( "Unable to locate surefire-booter in the list of plugin artifacts" );
+        }
+
+        if ( getToolchainManager() != null )
+        {
+            toolchain = getToolchainManager().getToolchainFromBuildContext( "jdk", getSession() );
+        }
     }
 
     @Nonnull
@@ -983,7 +1005,8 @@ public abstract class AbstractSurefireMojo
     private void executeAfterPreconditionsChecked( @Nonnull DefaultScanResult scanResult )
         throws MojoExecutionException, MojoFailureException
     {
-        List<ProviderInfo> providers = createProviders();
+        TestClassPath testClasspath = generateTestClasspath();
+        List<ProviderInfo> providers = createProviders( testClasspath );
 
         RunResult current = noTestsRun();
 
@@ -992,7 +1015,7 @@ public abstract class AbstractSurefireMojo
         {
             try
             {
-                current = current.aggregate( executeProvider( provider, scanResult ) );
+                current = current.aggregate( executeProvider( provider, scanResult, testClasspath ) );
             }
             catch ( SurefireBooterForkException | SurefireExecutionException | TestSetFailedException e )
             {
@@ -1011,21 +1034,13 @@ public abstract class AbstractSurefireMojo
         handleSummary( current, firstForkException );
     }
 
-    private void createDependencyResolver()
-    {
-        dependencyResolver = new SurefireDependencyResolver( getRepositorySystem(),
-                                                                   getConsoleLogger(), getLocalRepository(),
-                                                                   getRemoteRepositories(),
-                                                                   getPluginName() );
-    }
-
-    protected List<ProviderInfo> createProviders()
+    protected List<ProviderInfo> createProviders( TestClassPath testClasspath )
         throws MojoExecutionException
     {
         Artifact junitDepArtifact = getJunitDepArtifact();
         return new ProviderList( new DynamicProviderInfo( null ),
                               new TestNgProviderInfo( getTestNgArtifact() ),
-                              new JUnitPlatformProviderInfo( getJunitPlatformArtifact() ),
+                              new JUnitPlatformProviderInfo( getJunitPlatformArtifact(), testClasspath ),
                               new JUnitCoreProviderInfo( getJunitArtifact(), junitDepArtifact ),
                               new JUnit4ProviderInfo( getJunitArtifact(), junitDepArtifact ),
                               new JUnit3ProviderInfo() )
@@ -1117,7 +1132,8 @@ public abstract class AbstractSurefireMojo
     }
 
     @Nonnull
-    private RunResult executeProvider( @Nonnull ProviderInfo provider, @Nonnull DefaultScanResult scanResult )
+    private RunResult executeProvider( @Nonnull ProviderInfo provider, @Nonnull DefaultScanResult scanResult,
+                                       @Nonnull TestClassPath testClasspathWrapper )
         throws MojoExecutionException, MojoFailureException, SurefireExecutionException, SurefireBooterForkException,
         TestSetFailedException
     {
@@ -1132,8 +1148,8 @@ public abstract class AbstractSurefireMojo
         {
             createCopyAndReplaceForkNumPlaceholder( effectiveProperties, 1 ).copyToSystemProperties();
 
-            InPluginVMSurefireStarter surefireStarter =
-                createInprocessStarter( provider, classLoaderConfiguration, runOrderParameters, scanResult, platform );
+            InPluginVMSurefireStarter surefireStarter = createInprocessStarter( provider, classLoaderConfiguration,
+                    runOrderParameters, scanResult, platform, testClasspathWrapper );
             return surefireStarter.runSuitesInProcess( scanResult );
         }
         else
@@ -1149,7 +1165,8 @@ public abstract class AbstractSurefireMojo
             try
             {
                 forkStarter = createForkStarter( provider, forkConfiguration, classLoaderConfiguration,
-                                                       runOrderParameters, getConsoleLogger(), scanResult, platform );
+                                                       runOrderParameters, getConsoleLogger(), scanResult, platform,
+                                                       testClasspathWrapper );
 
                 return forkStarter.run( effectiveProperties, scanResult );
             }
@@ -1214,16 +1231,14 @@ public abstract class AbstractSurefireMojo
         this.repositorySystem = repositorySystem;
     }
 
-    final Toolchain getToolchain()
+    public DependencyResolver getDependencyResolver()
     {
-        Toolchain tc = null;
-
-        if ( getToolchainManager() != null )
-        {
-            tc = getToolchainManager().getToolchainFromBuildContext( "jdk", getSession() );
-        }
+        return dependencyResolver;
+    }
 
-        return tc;
+    public void setDependencyResolver( DependencyResolver dependencyResolver )
+    {
+        this.dependencyResolver = dependencyResolver;
     }
 
     private boolean existsModuleDescriptor()
@@ -1688,7 +1703,7 @@ public abstract class AbstractSurefireMojo
         return h;
     }
 
-    public File getStatisticsFile( String configurationHash )
+    private File getStatisticsFile( String configurationHash )
     {
         return new File( getBasedir(), ".surefire-" + configurationHash );
     }
@@ -1696,7 +1711,8 @@ public abstract class AbstractSurefireMojo
     private StartupConfiguration createStartupConfiguration( @Nonnull ProviderInfo provider, boolean isInprocess,
                                                              @Nonnull ClassLoaderConfiguration classLoaderConfiguration,
                                                              @Nonnull DefaultScanResult scanResult,
-                                                             @Nonnull Platform platform )
+                                                             @Nonnull Platform platform,
+                                                             @Nonnull TestClassPath testClasspathWrapper )
         throws MojoExecutionException
     {
         try
@@ -1714,11 +1730,12 @@ public abstract class AbstractSurefireMojo
                         .toString();
 
                 return newStartupConfigWithModularPath( classLoaderConfiguration, providerArtifacts, providerName,
-                        getModuleDescriptor(), scanResult, javaHome );
+                        getModuleDescriptor(), scanResult, javaHome, testClasspathWrapper );
             }
             else
             {
-                return newStartupConfigWithClasspath( classLoaderConfiguration, providerArtifacts, providerName );
+                return newStartupConfigWithClasspath( classLoaderConfiguration, providerArtifacts, providerName,
+                        testClasspathWrapper );
             }
         }
         catch ( IOException e )
@@ -1729,13 +1746,10 @@ public abstract class AbstractSurefireMojo
 
     private StartupConfiguration newStartupConfigWithClasspath(
             @Nonnull ClassLoaderConfiguration classLoaderConfiguration, @Nonnull Set<Artifact> providerArtifacts,
-            @Nonnull String providerName )
+            @Nonnull String providerName, @Nonnull TestClassPath testClasspathWrapper )
     {
-        TestClassPath testClasspathWrapper = generateTestClasspath();
         Classpath testClasspath = testClasspathWrapper.toClasspath();
 
-        testClasspathWrapper.avoidArtifactDuplicates( providerArtifacts );
-
         Classpath providerClasspath = ClasspathCache.getCachedClassPath( providerName );
         if ( providerClasspath == null )
         {
@@ -1769,8 +1783,8 @@ public abstract class AbstractSurefireMojo
             boolean contains = false;
             for ( Artifact providerArtifact : providerArtifacts )
             {
-                if ( providerArtifact.getGroupId().equals( inPluginArtifact.getGroupId() )
-                        && providerArtifact.getArtifactId().equals( inPluginArtifact.getArtifactId() ) )
+                if ( hasGroupArtifactId( providerArtifact.getGroupId(), providerArtifact.getArtifactId(),
+                        inPluginArtifact ) )
                 {
                     contains = true;
                     break;
@@ -1784,6 +1798,11 @@ public abstract class AbstractSurefireMojo
         return result;
     }
 
+    private static boolean hasGroupArtifactId( String groupId, String artifactId, Artifact artifact )
+    {
+        return groupId.equals( artifact.getGroupId() ) && artifactId.equals( artifact.getArtifactId() );
+    }
+
     private static Classpath createInProcClasspath( Classpath providerClasspath, Set<Artifact> newArtifacts )
     {
         Classpath inprocClasspath = providerClasspath.clone();
@@ -1806,14 +1825,11 @@ public abstract class AbstractSurefireMojo
     private StartupConfiguration newStartupConfigWithModularPath(
             @Nonnull ClassLoaderConfiguration classLoaderConfiguration, @Nonnull Set<Artifact> providerArtifacts,
             @Nonnull String providerName, @Nonnull File moduleDescriptor, @Nonnull DefaultScanResult scanResult,
-            @Nonnull String javaHome )
+            @Nonnull String javaHome, @Nonnull TestClassPath testClasspathWrapper )
             throws IOException
     {
-        TestClassPath testClasspathWrapper = generateTestClasspath();
         Classpath testClasspath = testClasspathWrapper.toClasspath();
 
-        testClasspathWrapper.avoidArtifactDuplicates( providerArtifacts );
-
         Classpath providerClasspath = ClasspathCache.getCachedClassPath( providerName );
         if ( providerClasspath == null )
         {
@@ -2123,14 +2139,19 @@ public abstract class AbstractSurefireMojo
         return getProjectArtifactMap().get( "junit:junit-dep" );
     }
 
-
     private Artifact getJunitPlatformArtifact()
     {
-        Artifact artifact = getProjectArtifactMap().get( getJunitPlatformArtifactName() );
-        Artifact projectArtifact = project.getArtifact();
-        String projectArtifactName = projectArtifact.getGroupId() + ":" + projectArtifact.getArtifactId();
+        Artifact artifact = getProjectArtifactMap().get( "org.junit.platform:junit-platform-commons" );
+        if ( artifact == null )
+        {
+            artifact = getPluginArtifactMap().get( "org.junit.platform:junit-platform-engine" );
+        }
 
-        if ( artifact == null && projectArtifactName.equals( getJunitPlatformArtifactName() ) )
+        Artifact projectArtifact = project.getArtifact();
+        String projectGroupId = projectArtifact.getGroupId();
+        if ( artifact == null && ( "org.junit.platform".equals( projectGroupId )
+                || "org.junit.jupiter".equals( projectGroupId )
+                || "org.junit.vintage".equals( projectGroupId ) ) )
         {
             artifact = projectArtifact;
         }
@@ -2141,11 +2162,12 @@ public abstract class AbstractSurefireMojo
     private ForkStarter createForkStarter( @Nonnull ProviderInfo provider, @Nonnull ForkConfiguration forkConfiguration,
                                            @Nonnull ClassLoaderConfiguration classLoaderConfiguration,
                                            @Nonnull RunOrderParameters runOrderParameters, @Nonnull ConsoleLogger log,
-                                           @Nonnull DefaultScanResult scanResult, @Nonnull Platform platform )
+                                           @Nonnull DefaultScanResult scanResult, @Nonnull Platform platform,
+                                           @Nonnull TestClassPath testClasspathWrapper )
         throws MojoExecutionException, MojoFailureException
     {
-        StartupConfiguration startupConfiguration =
-                createStartupConfiguration( provider, false, classLoaderConfiguration, scanResult, platform );
+        StartupConfiguration startupConfiguration = createStartupConfiguration( provider, false,
+                classLoaderConfiguration, scanResult, platform, testClasspathWrapper );
         String configChecksum = getConfigChecksum();
         StartupReportConfiguration startupReportConfiguration = getStartupReportConfiguration( configChecksum, true );
         ProviderConfiguration providerConfiguration = createProviderConfiguration( runOrderParameters );
@@ -2157,11 +2179,12 @@ public abstract class AbstractSurefireMojo
                                                               @Nonnull ClassLoaderConfiguration classLoaderConfig,
                                                               @Nonnull RunOrderParameters runOrderParameters,
                                                               @Nonnull DefaultScanResult scanResult,
-                                                              @Nonnull Platform platform )
+                                                              @Nonnull Platform platform,
+                                                              @Nonnull TestClassPath testClasspathWrapper )
         throws MojoExecutionException, MojoFailureException
     {
-        StartupConfiguration startupConfiguration =
-                createStartupConfiguration( provider, true, classLoaderConfig, scanResult, platform );
+        StartupConfiguration startupConfiguration = createStartupConfiguration( provider, true, classLoaderConfig,
+                scanResult, platform, testClasspathWrapper );
         String configChecksum = getConfigChecksum();
         StartupReportConfiguration startupReportConfiguration = getStartupReportConfiguration( configChecksum, false );
         ProviderConfiguration providerConfiguration = createProviderConfiguration( runOrderParameters );
@@ -2353,16 +2376,6 @@ public abstract class AbstractSurefireMojo
         return new JdkAttributes( jvmToUse, isBuiltInJava9AtLeast() );
     }
 
-    private Artifact getSurefireBooterArtifact()
-    {
-        Artifact artifact = getBooterArtifact();
-        if ( artifact == null )
-        {
-            throw new RuntimeException( "Unable to locate surefire-booter in the list of plugin artifacts" );
-        }
-        return artifact;
-    }
-
     /**
      * Where surefire stores its own temp files
      *
@@ -2451,6 +2464,7 @@ public abstract class AbstractSurefireMojo
         checksum.add( isParallelOptimized() );
         checksum.add( isTrimStackTrace() );
         checksum.add( getRemoteRepositories() );
+        checksum.add( getProjectRemoteRepositories() );
         checksum.add( isDisableXmlReport() );
         checksum.add( isUseSystemClassLoader() );
         checksum.add( isUseManifestOnlyJar() );
@@ -2504,7 +2518,7 @@ public abstract class AbstractSurefireMojo
      */
     private TestClassPath generateTestClasspath()
     {
-        @SuppressWarnings( "unchecked" ) Set<Artifact> classpathArtifacts = getProject().getArtifacts();
+        Set<Artifact> classpathArtifacts = getProject().getArtifacts();
 
         if ( getClasspathDependencyScopeExclude() != null && !getClasspathDependencyScopeExclude().isEmpty() )
         {
@@ -2520,7 +2534,7 @@ public abstract class AbstractSurefireMojo
         }
 
         return new TestClassPath( classpathArtifacts, getClassesDirectory(),
-                getTestClassesDirectory(), getAdditionalClasspathElements(), getConsoleLogger() );
+                getTestClassesDirectory(), getAdditionalClasspathElements() );
     }
 
     /**
@@ -2561,7 +2575,9 @@ public abstract class AbstractSurefireMojo
         if ( existing == null )
         {
             List<String> items = new ArrayList<>();
-            for ( Artifact artifact : dependencyResolver.resolveArtifact( surefireArtifact ).getArtifacts() )
+            Set<Artifact> booterArtifacts =
+                    surefireDependencyResolver.resolvePluginArtifact( surefireArtifact ).getArtifacts();
+            for ( Artifact artifact : booterArtifacts )
             {
                 getConsoleLogger().debug(
                     "Adding to " + getPluginName() + " booter test classpath: " + artifact.getFile().getAbsolutePath()
@@ -2665,7 +2681,7 @@ public abstract class AbstractSurefireMojo
                                                             + "is picking up an old junit version" );
                     }
                     throw new MojoFailureException( "groups/excludedGroups require TestNG, JUnit48+ or JUnit 5 "
-                            + "on project test classpath" );
+                            + "(a specific engine required on classpath) on project test classpath" );
                 }
             }
 
@@ -2789,7 +2805,7 @@ public abstract class AbstractSurefireMojo
         {
             Artifact surefireArtifact = getBooterArtifact();
             String version = surefireArtifact.getBaseVersion();
-            return dependencyResolver.getProviderClasspath( "surefire-testng", version );
+            return surefireDependencyResolver.getProviderClasspath( "surefire-testng", version );
         }
     }
 
@@ -2820,7 +2836,7 @@ public abstract class AbstractSurefireMojo
             // add the JUnit provider as default - it doesn't require JUnit to be present,
             // since it supports POJO tests.
             String version = surefireBooterArtifact.getBaseVersion();
-            return dependencyResolver.getProviderClasspath( "surefire-junit3", version );
+            return surefireDependencyResolver.getProviderClasspath( "surefire-junit3", version );
         }
     }
 
@@ -2859,18 +2875,23 @@ public abstract class AbstractSurefireMojo
         public Set<Artifact> getProviderClasspath()
         {
             String version = surefireBooterArtifact.getBaseVersion();
-            return dependencyResolver.getProviderClasspath( "surefire-junit4", version );
+            return surefireDependencyResolver.getProviderClasspath( "surefire-junit4", version );
         }
     }
 
     final class JUnitPlatformProviderInfo
         implements ProviderInfo
     {
-        private final Artifact junitArtifact;
+        private static final String PROVIDER_DEP_GID = "org.junit.platform";
+        private static final String PROVIDER_DEP_AID = "junit-platform-launcher";
 
-        JUnitPlatformProviderInfo( Artifact junitArtifact )
+        private final Artifact junitPlatformArtifact;
+        private final TestClassPath testClasspath;
+
+        JUnitPlatformProviderInfo( Artifact junitPlatformArtifact, TestClassPath testClasspath )
         {
-            this.junitArtifact = junitArtifact;
+            this.junitPlatformArtifact = junitPlatformArtifact;
+            this.testClasspath = testClasspath;
         }
 
         @Override
@@ -2883,7 +2904,7 @@ public abstract class AbstractSurefireMojo
         @Override
         public boolean isApplicable()
         {
-            return junitArtifact != null;
+            return junitPlatformArtifact != null;
         }
 
         @Override
@@ -2894,10 +2915,134 @@ public abstract class AbstractSurefireMojo
 
         @Override
         @Nonnull
-        public Set<Artifact> getProviderClasspath()
+        public Set<Artifact> getProviderClasspath() throws MojoExecutionException
         {
-            String version = surefireBooterArtifact.getBaseVersion();
-            return dependencyResolver.getProviderClasspath( "surefire-junit-platform", version );
+            String surefireVersion = surefireBooterArtifact.getBaseVersion();
+            Map<String, Artifact> providerArtifacts =
+                    surefireDependencyResolver.getProviderClasspathAsMap( "surefire-junit-platform", surefireVersion );
+            Map<String, Artifact> testDependencies = testClasspath.getTestDependencies();
+
+            if ( hasDependencyPlatformEngine( testDependencies ) )
+            {
+                String filterTestDependency = "org.junit.platform:junit-platform-engine";
+                getConsoleLogger().debug( "Test dependencies contain " + filterTestDependency );
+                narrowProviderDependencies( filterTestDependency, providerArtifacts, testDependencies );
+            }
+            else
+            {
+                ProjectBuildingRequest request = getSession().getProjectBuildingRequest();
+                Collection<Dependency> pluginDependencies = getPluginDescriptor().getPlugin().getDependencies();
+                Set<Artifact> engines =
+                        surefireDependencyResolver.resolvePluginDependencies( request, pluginDependencies );
+                if ( hasDependencyPlatformEngine( engines ) )
+                {
+                    Map<String, Artifact> engineArtifacts = artifactMapByVersionlessId( engines );
+                    providerArtifacts.putAll( engineArtifacts );
+                    alignVersions( providerArtifacts, engineArtifacts );
+                }
+                else if ( hasDependencyJupiterAPI( testDependencies ) )
+                {
+                    String engineGroupId = "org.junit.jupiter";
+                    String engineArtifactId = "junit-jupiter-engine";
+                    String engineCoordinates = engineGroupId + ":" + engineArtifactId;
+                    String api = "org.junit.jupiter:junit-jupiter-api";
+                    getConsoleLogger().debug( "Test dependencies contain " + api + ". Resolving " + engineCoordinates );
+                    String engineVersion = testDependencies.get( api ).getBaseVersion();
+                    addEngineByApi( engineGroupId, engineArtifactId, engineVersion,
+                            providerArtifacts, testDependencies );
+                }
+            }
+            providerArtifacts.keySet().removeAll( testDependencies.keySet() );
+            return new LinkedHashSet<>( providerArtifacts.values() );
+        }
+
+        private void addEngineByApi( String engineGroupId, String engineArtifactId, String engineVersion,
+                                     Map<String, Artifact> providerArtifacts, Map<String, Artifact> testDependencies )
+        {
+            providerArtifacts.keySet().removeAll( testDependencies.keySet() );
+            for ( Artifact dep : resolve( engineGroupId, engineArtifactId, engineVersion, null, "jar" ) )
+            {
+                String key = dep.getGroupId() + ":" + dep.getArtifactId();
+                if ( !testDependencies.containsKey( key ) )
+                {
+                    providerArtifacts.put( key, dep );
+                }
+            }
+            alignVersions( providerArtifacts, testDependencies );
+        }
+
+        private void narrowProviderDependencies( String filterTestDependency,
+                                                 Map<String, Artifact> providerArtifacts,
+                                                 Map<String, Artifact> testDependencies )
+        {
+            Artifact engine = testDependencies.get( filterTestDependency );
+            String groupId = engine.getGroupId();
+            String artifactId = engine.getArtifactId();
+            String version = engine.getBaseVersion();
+            String classifier = engine.getClassifier();
+            String type = engine.getType();
+            for ( Artifact engineDep : resolve( groupId, artifactId, version, classifier, type ) )
+            {
+                providerArtifacts.remove( engineDep.getGroupId() + ":" + engineDep.getArtifactId() );
+                getConsoleLogger().debug( "Removed artifact " + engineDep
+                        + " from provider. Already appears in test classpath." );
+            }
+            alignVersions( providerArtifacts, testDependencies );
+        }
+
+        private void alignVersions( Map<String, Artifact> providerArtifacts,
+                                    Map<String, Artifact> referencedDependencies )
+        {
+            String version = referencedDependencies.get( "org.junit.platform:junit-platform-commons" ).getBaseVersion();
+            for ( Artifact launcherArtifact : resolve( PROVIDER_DEP_GID, PROVIDER_DEP_AID, version, null, "jar" ) )
+            {
+                String key = launcherArtifact.getGroupId() + ":" + launcherArtifact.getArtifactId();
+                if ( providerArtifacts.containsKey( key ) )
+                {
+                    providerArtifacts.put( key, launcherArtifact );
+                }
+            }
+        }
+
+        private Set<Artifact> resolve( String g, String a, String v, String c, String t )
+        {
+            ArtifactHandler handler = junitPlatformArtifact.getArtifactHandler();
+            Artifact artifact = new DefaultArtifact( g, a, v, null, t, c, handler );
+            getConsoleLogger().debug( "Resolving artifact " + g + ":" + a + ":" + v );
+            Set<Artifact> r = surefireDependencyResolver.resolveProjectArtifact( artifact ).getArtifacts();
+            getConsoleLogger().debug( "Resolved artifact " + g + ":" + a + ":" + v + " to " + r );
+            return r;
+        }
+
+        private boolean hasDependencyJupiterAPI( Map<String, Artifact> dependencies )
+        {
+            return dependencies.containsKey( "org.junit.jupiter:junit-jupiter-api" )
+                    || hasGroupArtifactId( "org.junit.jupiter", "junit-jupiter-api", getProject().getArtifact() );
+        }
+
+        private boolean hasDependencyPlatformEngine( Map<String, Artifact> dependencies )
+        {
+            return dependencies.containsKey( "org.junit.platform:junit-platform-engine" )
+                    || hasGroupArtifactId( "org.junit.platform", "junit-platform-engine", getProject().getArtifact() );
+        }
+
+        private boolean hasDependencyPlatformEngine( Collection<Artifact> dependencies )
+        {
+            if ( hasGroupArtifactId( "org.junit.platform", "junit-platform-engine", getProject().getArtifact() ) )
+            {
+                return true;
+            }
+
+            for ( Artifact dependency : dependencies )
+            {
+                if ( dependency.getGroupId().equals( "org.junit.platform" )
+                        && dependency.getArtifactId().equals( "junit-platform-engine" ) )
+                {
+                    return true;
+                }
+            }
+
+            return false;
         }
     }
 
@@ -2945,7 +3090,7 @@ public abstract class AbstractSurefireMojo
         public Set<Artifact> getProviderClasspath()
         {
             String version = surefireBooterArtifact.getBaseVersion();
-            return dependencyResolver.getProviderClasspath( "surefire-junit47", version );
+            return surefireDependencyResolver.getProviderClasspath( "surefire-junit47", version );
         }
     }
 
@@ -2993,7 +3138,7 @@ public abstract class AbstractSurefireMojo
         @Nonnull
         public Set<Artifact> getProviderClasspath()
         {
-            return dependencyResolver.addProviderToClasspath( getPluginArtifactMap(), getMojoArtifact(),
+            return surefireDependencyResolver.addProviderToClasspath( getPluginArtifactMap(), getMojoArtifact(),
                     getCommonArtifact(), getApiArtifact(), getLoggerApiArtifact() );
         }
     }
@@ -3176,7 +3321,6 @@ public abstract class AbstractSurefireMojo
         this.projectArtifactMap = projectArtifactMap;
     }
 
-
     public String getReportNameSuffix()
     {
         return reportNameSuffix;
@@ -3305,17 +3449,6 @@ public abstract class AbstractSurefireMojo
         this.junitArtifactName = junitArtifactName;
     }
 
-    public String getJunitPlatformArtifactName()
-    {
-        return junitPlatformArtifactName;
-    }
-
-    @SuppressWarnings( "UnusedDeclaration" )
-    public void setJunitPlatformArtifactName( String junitPlatformArtifactName )
-    {
-        this.junitPlatformArtifactName = junitPlatformArtifactName;
-    }
-
     public String getTestNGArtifactName()
     {
         return testNGArtifactName;
@@ -3423,6 +3556,17 @@ public abstract class AbstractSurefireMojo
         this.trimStackTrace = trimStackTrace;
     }
 
+    public List<ArtifactRepository> getProjectRemoteRepositories()
+    {
+        return projectRemoteRepositories;
+    }
+
+    @SuppressWarnings( "UnusedDeclaration" )
+    public void setProjectRemoteRepositories( List<ArtifactRepository> projectRemoteRepositories )
+    {
+        this.projectRemoteRepositories = projectRemoteRepositories;
+    }
+
     public List<ArtifactRepository> getRemoteRepositories()
     {
         return remoteRepositories;
@@ -3518,6 +3662,12 @@ public abstract class AbstractSurefireMojo
         this.dependenciesToScan = dependenciesToScan;
     }
 
+    @SuppressWarnings( "UnusedDeclaration" )
+    void setPluginDescriptor( PluginDescriptor pluginDescriptor )
+    {
+        this.pluginDescriptor = pluginDescriptor;
+    }
+
     public PluginDescriptor getPluginDescriptor()
     {
         return pluginDescriptor;
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ProviderInfo.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ProviderInfo.java
index cb63cc1..fea74fd 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ProviderInfo.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ProviderInfo.java
@@ -36,7 +36,7 @@ public interface ProviderInfo
     boolean isApplicable();
 
     @Nonnull
-    Set<Artifact> getProviderClasspath();
+    Set<Artifact> getProviderClasspath() throws MojoExecutionException;
 
     void addProviderProperties() throws MojoExecutionException;
 }
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireDependencyResolver.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireDependencyResolver.java
index b255f38..170107c 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireDependencyResolver.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/SurefireDependencyResolver.java
@@ -19,6 +19,7 @@ package org.apache.maven.plugin.surefire;
  * under the License.
  */
 
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -29,20 +30,29 @@ import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
-import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
 import org.apache.maven.artifact.versioning.OverConstrainedVersionException;
 import org.apache.maven.artifact.versioning.VersionRange;
 import org.apache.maven.model.Dependency;
+import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
+import org.apache.maven.project.ProjectBuildingRequest;
 import org.apache.maven.repository.RepositorySystem;
+import org.apache.maven.shared.artifact.filter.resolve.ScopeFilter;
+import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult;
+import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver;
+import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
-import static java.util.Collections.singletonList;
-import static org.apache.maven.artifact.Artifact.SCOPE_TEST;
+import static java.util.Arrays.asList;
+import static org.apache.maven.artifact.Artifact.SCOPE_COMPILE;
+import static org.apache.maven.artifact.Artifact.SCOPE_COMPILE_PLUS_RUNTIME;
+import static org.apache.maven.artifact.Artifact.SCOPE_RUNTIME;
+import static org.apache.maven.artifact.ArtifactUtils.artifactMapByVersionlessId;
 import static org.apache.maven.artifact.versioning.VersionRange.createFromVersionSpec;
 
 /**
@@ -76,19 +86,27 @@ final class SurefireDependencyResolver
 
     private final ArtifactRepository localRepository;
 
-    private final List<ArtifactRepository> remoteRepositories;
+    private final List<ArtifactRepository> pluginRemoteRepositories;
+
+    private final List<ArtifactRepository> projectRemoteRepositories;
 
     private final String pluginName;
 
+    private final DependencyResolver depencencyResolver;
+
     SurefireDependencyResolver( RepositorySystem repositorySystem, ConsoleLogger log,
                                 ArtifactRepository localRepository,
-                                List<ArtifactRepository> remoteRepositories, String pluginName )
+                                List<ArtifactRepository> pluginRemoteRepositories,
+                                List<ArtifactRepository> projectRemoteRepositories, String pluginName,
+                                DependencyResolver depencencyResolver )
     {
         this.repositorySystem = repositorySystem;
         this.log = log;
         this.localRepository = localRepository;
-        this.remoteRepositories = remoteRepositories;
+        this.pluginRemoteRepositories = pluginRemoteRepositories;
+        this.projectRemoteRepositories = projectRemoteRepositories;
         this.pluginName = pluginName;
+        this.depencencyResolver = depencencyResolver;
     }
 
     static boolean isWithinVersionSpec( @Nullable Artifact artifact, @Nonnull String versionSpec )
@@ -115,23 +133,46 @@ final class SurefireDependencyResolver
         }
     }
 
-    ArtifactResolutionResult resolveArtifact( Artifact providerArtifact )
+    Set<Artifact> resolvePluginDependencies( ProjectBuildingRequest request, Collection<Dependency> pluginDependencies )
+            throws MojoExecutionException
     {
-        return resolveArtifact( providerArtifact, null );
+        try
+        {
+            Iterable<ArtifactResult> resolvedPluginDependencies = depencencyResolver.resolveDependencies( request,
+                    pluginDependencies, null, ScopeFilter.including( SCOPE_COMPILE, SCOPE_RUNTIME ) );
+
+            Set<Artifact> resolved = new LinkedHashSet<>();
+            for ( ArtifactResult resolvedPluginDependency : resolvedPluginDependencies )
+            {
+                resolved.add( resolvedPluginDependency.getArtifact() );
+            }
+            return resolved;
+        }
+        catch ( DependencyResolverException e )
+        {
+            throw new MojoExecutionException( e.getLocalizedMessage(), e );
+        }
     }
 
-    private ArtifactResolutionResult resolveArtifact( Artifact providerArtifact, @Nullable Artifact excludeArtifact )
+    ArtifactResolutionResult resolvePluginArtifact( Artifact artifact )
+    {
+        return resolveArtifact( artifact, pluginRemoteRepositories );
+    }
+
+    ArtifactResolutionResult resolveProjectArtifact( Artifact artifact )
+    {
+        return resolveArtifact( artifact, projectRemoteRepositories );
+    }
+
+    private ArtifactResolutionResult resolveArtifact( Artifact artifact, List<ArtifactRepository> repositories )
     {
         ArtifactResolutionRequest request = new ArtifactResolutionRequest()
-                                                    .setArtifact( providerArtifact )
-                                                    .setRemoteRepositories( remoteRepositories )
-                                                    .setLocalRepository( localRepository )
-                                                    .setResolveTransitively( true );
-        if ( excludeArtifact != null )
-        {
-            String pattern = excludeArtifact.getGroupId() + ":" + excludeArtifact.getArtifactId();
-            request.setCollectionFilter( new ExcludesArtifactFilter( singletonList( pattern ) ) );
-        }
+                .setArtifact( artifact )
+                .setLocalRepository( localRepository )
+                .setResolveTransitively( true )
+                .setCollectionFilter( new RuntimeArtifactFilter() )
+                .setRemoteRepositories( repositories );
+
         return repositorySystem.resolve( request );
     }
 
@@ -142,7 +183,7 @@ final class SurefireDependencyResolver
 
         Artifact providerArtifact = repositorySystem.createDependencyArtifact( provider );
 
-        ArtifactResolutionResult result = resolveArtifact( providerArtifact );
+        ArtifactResolutionResult result = resolvePluginArtifact( providerArtifact );
 
         if ( log.isDebugEnabled() )
         {
@@ -157,17 +198,23 @@ final class SurefireDependencyResolver
         return orderProviderArtifacts( result.getArtifacts() );
     }
 
+    @Nonnull
+    Map<String, Artifact> getProviderClasspathAsMap( String providerArtifactId, String providerVersion )
+    {
+        return artifactMapByVersionlessId( getProviderClasspath( providerArtifactId, providerVersion ) );
+    }
+
     Set<Artifact> addProviderToClasspath( Map<String, Artifact> pluginArtifactMap, Artifact mojoPluginArtifact,
                                           Artifact surefireCommon, Artifact surefireApi, Artifact surefireLoggerApi )
     {
         Set<Artifact> providerArtifacts = new LinkedHashSet<>();
-        ArtifactResolutionResult artifactResolutionResult = resolveArtifact( mojoPluginArtifact );
+        ArtifactResolutionResult artifactResolutionResult = resolvePluginArtifact( mojoPluginArtifact );
         for ( Artifact artifact : pluginArtifactMap.values() )
         {
             if ( !artifactResolutionResult.getArtifacts().contains( artifact ) )
             {
                 providerArtifacts.add( artifact );
-                for ( Artifact dependency : resolveArtifact( artifact ).getArtifacts() )
+                for ( Artifact dependency : resolvePluginArtifact( artifact ).getArtifacts() )
                 {
                     String groupId = dependency.getGroupId();
                     String artifactId = dependency.getArtifactId();
@@ -219,7 +266,19 @@ final class SurefireDependencyResolver
         dependency.setArtifactId( providerArtifactId );
         dependency.setVersion( providerVersion );
         dependency.setType( "jar" );
-        dependency.setScope( SCOPE_TEST );
         return dependency;
     }
+
+    static class RuntimeArtifactFilter implements ArtifactFilter
+    {
+        private static final Collection<String> SCOPES =
+                asList( SCOPE_COMPILE, SCOPE_COMPILE_PLUS_RUNTIME, SCOPE_RUNTIME );
+
+        @Override
+        public boolean include( Artifact artifact )
+        {
+            String scope = artifact.getScope();
+            return !artifact.isOptional() && ( scope == null || SCOPES.contains( scope ) );
+        }
+    }
 }
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/TestClassPath.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/TestClassPath.java
index ee8fadb..3a37816 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/TestClassPath.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/TestClassPath.java
@@ -20,14 +20,13 @@ package org.apache.maven.plugin.surefire;
  */
 
 import org.apache.maven.artifact.Artifact;
-import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
 import org.apache.maven.surefire.booter.Classpath;
 
 import java.io.File;
 import java.util.ArrayList;
-import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Set;
+import java.util.Map;
 
 import static java.util.Collections.addAll;
 import static org.apache.maven.shared.utils.StringUtils.split;
@@ -38,45 +37,26 @@ final class TestClassPath
     private final File classesDirectory;
     private final File testClassesDirectory;
     private final String[] additionalClasspathElements;
-    private final ConsoleLogger logger;
 
     TestClassPath( Iterable<Artifact> artifacts,
                    File classesDirectory,
                    File testClassesDirectory,
-                   String[] additionalClasspathElements,
-                   ConsoleLogger logger )
+                   String[] additionalClasspathElements )
     {
         this.artifacts = artifacts;
         this.classesDirectory = classesDirectory;
         this.testClassesDirectory = testClassesDirectory;
         this.additionalClasspathElements = additionalClasspathElements;
-        this.logger = logger;
     }
 
-    void avoidArtifactDuplicates( Set<Artifact> providerArtifacts )
+    Map<String, Artifact> getTestDependencies()
     {
+        Map<String, Artifact> artifactMapping = new LinkedHashMap<>();
         for ( Artifact artifact : artifacts )
         {
-            Iterator<Artifact> it = providerArtifacts.iterator();
-            while ( it.hasNext() )
-            {
-                Artifact providerArtifact = it.next();
-                String classifier1 = providerArtifact.getClassifier();
-                String classifier2 = artifact.getClassifier();
-                if ( providerArtifact.getGroupId().equals( artifact.getGroupId() )
-                        && providerArtifact.getArtifactId().equals( artifact.getArtifactId() )
-                        && providerArtifact.getType().equals( artifact.getType() )
-                        && ( classifier1 == null ? classifier2 == null : classifier1.equals( classifier2 ) ) )
-                {
-                    it.remove();
-                    if ( logger.isDebugEnabled() )
-                    {
-                        logger.debug( "Removed artifact " + providerArtifact + " from provider. "
-                                + "Already appears in test classpath." );
-                    }
-                }
-            }
+            artifactMapping.put( artifact.getGroupId() + ":" + artifact.getArtifactId(), artifact );
         }
+        return artifactMapping;
     }
 
     Classpath toClasspath()
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoJava7PlusTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoJava7PlusTest.java
index 0f9ee80..2d268bc 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoJava7PlusTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoJava7PlusTest.java
@@ -108,7 +108,7 @@ public class AbstractSurefireMojoJava7PlusTest
 
         TestClassPath testClasspath =
                 new TestClassPath( asList( modular, nonModular, junit, hamcrest ), classesDir, testClassesDir,
-                        null, null );
+                        null );
 
         doReturn( testClasspath ).when( mojo, "generateTestClasspath" );
         doReturn( 1 ).when( mojo, "getEffectiveForkCount" );
@@ -171,11 +171,10 @@ public class AbstractSurefireMojoJava7PlusTest
 
         StartupConfiguration conf = invokeMethod( mojo, "newStartupConfigWithModularPath",
                 classLoaderConfiguration, providerClasspath, "org.asf.Provider", moduleInfo, scanResult,
-                "" );
+                "", testClasspath );
 
         verify( mojo, times( 1 ) ).effectiveIsEnableAssertions();
         verify( mojo, times( 1 ) ).isChildDelegation();
-        verifyPrivate( mojo, times( 1 ) ).invoke( "generateTestClasspath" );
         verify( mojo, times( 1 ) ).getEffectiveForkCount();
         verify( mojo, times( 1 ) ).getTestClassesDirectory();
         verify( scanResult, times( 1 ) ).getClasses();
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java
index a6fc708..080f2b5 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/AbstractSurefireMojoTest.java
@@ -22,9 +22,22 @@ package org.apache.maven.plugin.surefire;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.DefaultArtifact;
 import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
 import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.plugin.surefire.AbstractSurefireMojo.JUnitPlatformProviderInfo;
 import org.apache.maven.plugin.surefire.log.PluginConsoleLogger;
 import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.ProjectBuildingRequest;
+import org.apache.maven.repository.RepositorySystem;
+import org.apache.maven.shared.artifact.filter.resolve.TransformableFilter;
+import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult;
+import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver;
 import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
 import org.apache.maven.surefire.booter.Classpath;
 import org.apache.maven.surefire.booter.StartupConfiguration;
@@ -33,7 +46,10 @@ import org.codehaus.plexus.logging.Logger;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatchers;
 import org.mockito.Mock;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
 
@@ -41,6 +57,7 @@ import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
@@ -50,13 +67,14 @@ import java.util.Set;
 
 import static java.io.File.separatorChar;
 import static java.util.Arrays.asList;
-import static java.util.Collections.singleton;
+import static java.util.Collections.*;
 import static org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS;
 import static org.apache.maven.artifact.versioning.VersionRange.createFromVersion;
 import static org.apache.maven.artifact.versioning.VersionRange.createFromVersionSpec;
 import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
+import static org.fest.assertions.MapAssert.entry;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.verify;
@@ -247,7 +265,7 @@ public class AbstractSurefireMojoTest
         File classesDir = mockFile( "classes" );
         File testClassesDir = mockFile( "test-classes" );
         TestClassPath testClasspath =
-                new TestClassPath( asList( junit, hamcrest ), classesDir, testClassesDir, null, null );
+                new TestClassPath( asList( junit, hamcrest ), classesDir, testClassesDir, null );
 
         doReturn( testClasspath ).when( mojo, "generateTestClasspath" );
         doReturn( 1 ).when( mojo, "getEffectiveForkCount" );
@@ -267,11 +285,10 @@ public class AbstractSurefireMojoTest
         when( mojo.getConsoleLogger() ).thenReturn( new PluginConsoleLogger( logger ) );
 
         StartupConfiguration conf = invokeMethod( mojo, "newStartupConfigWithClasspath",
-                classLoaderConfiguration, providerArtifacts, "org.asf.Provider" );
+                classLoaderConfiguration, providerArtifacts, "org.asf.Provider", testClasspath );
 
         verify( mojo, times( 1 ) ).effectiveIsEnableAssertions();
         verify( mojo, times( 1 ) ).isChildDelegation();
-        verifyPrivate( mojo, times( 1 ) ).invoke( "generateTestClasspath" );
         verify( mojo, times( 1 ) ).getEffectiveForkCount();
         ArgumentCaptor<String> argument = ArgumentCaptor.forClass( String.class );
         verify( logger, times( 6 ) ).debug( argument.capture() );
@@ -360,9 +377,1214 @@ public class AbstractSurefireMojoTest
                 .isDirectory();
     }
 
+    @Test
+    public void shouldSmartlyResolveJUnit5ProviderWithJUnit4() throws Exception
+    {
+        MavenProject mavenProject = new MavenProject();
+        mavenProject.setArtifact( new DefaultArtifact( "dummy", "pom", createFromVersion( "1.0.0" ),
+                null, "jar", null, mock( ArtifactHandler.class ) ) );
+        mojo.setProject( mavenProject );
+
+        final VersionRange surefireVersion = createFromVersion( "1" );
+
+        Artifact junitPlatformArtifact = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+
+        Artifact testClasspathJUnit = new DefaultArtifact( "junit", "junit", createFromVersion( "4.12" ), null, "jar",
+                null, mock( ArtifactHandler.class ) );
+
+        Iterable<Artifact> testArtifacts = singleton( testClasspathJUnit );
+
+        File classesDirectory = new File( "target/classes" );
+
+        File testClassesDirectory = new File( "target/test-classes" );
+
+        TestClassPath testClasspathWrapper =
+                new TestClassPath( testArtifacts, classesDirectory, testClassesDirectory, null );
+
+        Artifact forkedBooter = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-booter", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+
+        mojo.setPluginArtifactMap( singletonMap( "org.apache.maven.surefire:surefire-booter", forkedBooter ) );
+        mojo.setRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        mojo.setProjectRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        RepositorySystem repositorySystem = mock( RepositorySystem.class );
+        final Artifact surefireProvider = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        when( repositorySystem.createDependencyArtifact( any( Dependency.class ) ) ).thenAnswer( new Answer<Artifact>()
+        {
+            @Override
+            public Artifact answer( InvocationOnMock invocation )
+            {
+                Dependency provider = (Dependency) invocation.getArguments()[0];
+                assertThat( provider.getGroupId() ).isEqualTo( "org.apache.maven.surefire" );
+                assertThat( provider.getArtifactId() ).isEqualTo( "surefire-junit-platform" );
+                return surefireProvider;
+            }
+        } );
+        final ArtifactResolutionResult surefireProviderResolutionResult = mock( ArtifactResolutionResult.class );
+        final ArtifactResolutionResult junit4ResolutionResult = mock( ArtifactResolutionResult.class );
+        when( repositorySystem.resolve( any( ArtifactResolutionRequest.class ) ) )
+                .thenAnswer( new Answer<ArtifactResolutionResult>()
+                {
+                    @Override
+                    public ArtifactResolutionResult answer( InvocationOnMock invocation )
+                    {
+                        ArtifactResolutionRequest req = (ArtifactResolutionRequest) invocation.getArguments()[0];
+                        Artifact artifact = req.getArtifact();
+                        if ( artifact == surefireProvider )
+                        {
+                            return surefireProviderResolutionResult;
+                        }
+                        else if ( artifact.getGroupId().equals( "junit" )
+                                && artifact.getArtifactId().equals( "junit" )
+                                && artifact.getVersion().equals( "4.12" ) )
+                        {
+                            return junit4ResolutionResult;
+                        }
+                        else
+                        {
+                            fail();
+                            return null;
+                        }
+                    }
+                } );
+
+        DependencyResolver dependencyResolver = mock( DependencyResolver.class );
+        when( dependencyResolver.resolveDependencies( any( ProjectBuildingRequest.class ),
+                ArgumentMatchers.<Dependency>anyCollection(), isNull( Collection.class ),
+                any( TransformableFilter.class ) ) )
+                .thenAnswer( new Answer<Object>()
+                {
+                    @Override
+                    public Object answer( InvocationOnMock invocation )
+                    {
+                        Collection deps = (Collection) invocation.getArguments()[1];
+                        assertThat( deps ).isEmpty();
+                        return emptySet();
+                    }
+                } );
+
+        Artifact java5 = new DefaultArtifact( "org.apache.maven.surefire", "common-java5",
+                surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact launcher = new DefaultArtifact( "org.junit.platform", "junit-platform-launcher",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact apiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact engine = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact commons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact opentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Set<Artifact> providerArtifacts = new HashSet<>();
+        providerArtifacts.add( surefireProvider );
+        providerArtifacts.add( java5 );
+        providerArtifacts.add( launcher );
+        providerArtifacts.add( apiguardian );
+        providerArtifacts.add( engine );
+        providerArtifacts.add( commons );
+        providerArtifacts.add( opentest4j );
+
+        when( surefireProviderResolutionResult.getArtifacts() )
+                .thenReturn( providerArtifacts );
+
+        Artifact junit = new DefaultArtifact( "junit", "junit",
+                createFromVersion( "4.12" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact hamcrest = new DefaultArtifact( "org.hamcrest", "hamcrest-core",
+                createFromVersion( "1.3" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Set<Artifact> junitArtifacts = new HashSet<>();
+        junitArtifacts.add( junit );
+        junitArtifacts.add( hamcrest );
+        when( junit4ResolutionResult.getArtifacts() )
+                .thenReturn( junitArtifacts );
+
+        mojo.setRepositorySystem( repositorySystem );
+        mojo.setLogger( mock( Logger.class ) );
+        mojo.setDependencyResolver( dependencyResolver );
+
+        invokeMethod( mojo, "setupStuff" );
+
+        MavenSession session = mock( MavenSession.class );
+        mojo.setSession( session );
+        when( session.getProjectBuildingRequest() )
+                .thenReturn( mock( ProjectBuildingRequest.class ) );
+
+        PluginDescriptor pluginDescriptor = mock( PluginDescriptor.class );
+        mojo.setPluginDescriptor( pluginDescriptor );
+        Plugin p = mock( Plugin.class );
+        when( pluginDescriptor.getPlugin() )
+                .thenReturn( p );
+        when( p.getDependencies() )
+                .thenReturn( Collections.<Dependency>emptyList() );
+
+        JUnitPlatformProviderInfo prov =
+                mojo.createJUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
+
+        Artifact expectedProvider = new DefaultArtifact( "org.apache.maven.surefire", "surefire-junit-platform",
+                surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact expectedCommonJava5 = new DefaultArtifact( "org.apache.maven.surefire", "common-java5",
+                surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact expectedLauncher = new DefaultArtifact( "org.junit.platform", "junit-platform-launcher",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact expectedApiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact expectedJUnit5Engine = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact expectedOpentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact expectedPlatformCommons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        assertThat( prov.getProviderClasspath() )
+                .hasSize( 7 )
+                .containsOnly( expectedProvider, expectedCommonJava5, expectedLauncher, expectedApiguardian,
+                        expectedJUnit5Engine, expectedOpentest4j, expectedPlatformCommons );
+
+        assertThat( testClasspathWrapper.getTestDependencies() )
+                .hasSize( 1 )
+                .includes( entry( "junit:junit", testClasspathJUnit ) );
+    }
+
+    @Test
+    public void shouldSmartlyResolveJUnit5ProviderWithVintage() throws Exception
+    {
+        MavenProject mavenProject = new MavenProject();
+        mavenProject.setArtifact( new DefaultArtifact( "dummy", "pom", createFromVersion( "1.0.0" ),
+                null, "jar", null, mock( ArtifactHandler.class ) ) );
+        mojo.setProject( mavenProject );
+
+        final VersionRange surefireVersion = createFromVersion( "1" );
+
+        Artifact junitPlatformArtifact = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathSomeTestArtifact = new DefaultArtifact( "third.party", "artifact",
+                createFromVersion( "1.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathVintage = new DefaultArtifact( "org.junit.vintage", "junit-vintage-engine",
+                createFromVersion( "5.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathApiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathPlatformEng = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        Artifact testClasspathJUnit4 = new DefaultArtifact( "junit", "junit",
+                createFromVersion( "4.12" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        Artifact testClasspathHamcrest = new DefaultArtifact( "org.hamcrest", "hamcrest-core",
+                createFromVersion( "1.3" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathOpentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathCommons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        Iterable<Artifact> testArtifacts = asList( testClasspathSomeTestArtifact, testClasspathVintage,
+                testClasspathApiguardian, testClasspathPlatformEng, testClasspathJUnit4, testClasspathHamcrest,
+                testClasspathOpentest4j, testClasspathCommons );
+
+        File classesDirectory = new File( "target/classes" );
+
+        File testClassesDirectory = new File( "target/test-classes" );
+
+        TestClassPath testClasspathWrapper =
+                new TestClassPath( testArtifacts, classesDirectory, testClassesDirectory, null );
+
+        Artifact forkedBooter = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-booter", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+
+        mojo.setPluginArtifactMap( singletonMap( "org.apache.maven.surefire:surefire-booter", forkedBooter ) );
+        mojo.setRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        mojo.setProjectRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        RepositorySystem repositorySystem = mock( RepositorySystem.class );
+        final Artifact surefireProvider = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        when( repositorySystem.createDependencyArtifact( any( Dependency.class ) ) ).thenAnswer( new Answer<Artifact>()
+        {
+            @Override
+            public Artifact answer( InvocationOnMock invocation )
+            {
+                Dependency provider = (Dependency) invocation.getArguments()[0];
+                assertThat( provider.getGroupId() ).isEqualTo( "org.apache.maven.surefire" );
+                assertThat( provider.getArtifactId() ).isEqualTo( "surefire-junit-platform" );
+                return surefireProvider;
+            }
+        } );
+        final ArtifactResolutionResult surefireProviderResolutionResult = mock( ArtifactResolutionResult.class );
+        final ArtifactResolutionResult junit4ResolutionResult = mock( ArtifactResolutionResult.class );
+        when( repositorySystem.resolve( any( ArtifactResolutionRequest.class ) ) )
+                .thenAnswer( new Answer<ArtifactResolutionResult>()
+                {
+                    @Override
+                    public ArtifactResolutionResult answer( InvocationOnMock invocation )
+                    {
+                        ArtifactResolutionRequest req = (ArtifactResolutionRequest) invocation.getArguments()[0];
+                        Artifact resolvable = req.getArtifact();
+                        if ( resolvable == surefireProvider )
+                        {
+                            return surefireProviderResolutionResult;
+                        }
+                        else if ( "org.junit.platform".equals( resolvable.getGroupId() )
+                                && "junit-platform-engine".equals( resolvable.getArtifactId() )
+                                && "1.4.0".equals( resolvable.getVersion() ) )
+                        {
+                            return createVintageEngineResolutionResult();
+                        }
+                        else if ( "org.junit.platform".equals( resolvable.getGroupId() )
+                                && "junit-platform-launcher".equals( resolvable.getArtifactId() )
+                                && "1.4.0".equals( resolvable.getVersion() ) )
+                        {
+                            return createExpectedJUnitPlatformLauncherResolutionResult();
+                        }
+                        else
+                        {
+                            fail();
+                            return null;
+                        }
+                    }
+                } );
+
+        Artifact java5 = new DefaultArtifact( "org.apache.maven.surefire", "common-java5",
+                surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact launcher = new DefaultArtifact( "org.junit.platform", "junit-platform-launcher",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact apiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact engine = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact commons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact opentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Set<Artifact> providerArtifacts = new HashSet<>();
+        providerArtifacts.add( surefireProvider );
+        providerArtifacts.add( java5 );
+        providerArtifacts.add( launcher );
+        providerArtifacts.add( apiguardian );
+        providerArtifacts.add( engine );
+        providerArtifacts.add( commons );
+        providerArtifacts.add( opentest4j );
+
+        when( surefireProviderResolutionResult.getArtifacts() )
+                .thenReturn( providerArtifacts );
+
+        Artifact junit = new DefaultArtifact( "junit", "junit",
+                createFromVersion( "4.12" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact hamcrest = new DefaultArtifact( "org.hamcrest", "hamcrest-core",
+                createFromVersion( "1.3" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Set<Artifact> junitArtifacts = new HashSet<>();
+        junitArtifacts.add( junit );
+        junitArtifacts.add( hamcrest );
+        when( junit4ResolutionResult.getArtifacts() )
+                .thenReturn( junitArtifacts );
+
+        mojo.setRepositorySystem( repositorySystem );
+        mojo.setLogger( mock( Logger.class ) );
+
+        invokeMethod( mojo, "setupStuff" );
+        JUnitPlatformProviderInfo prov =
+                mojo.createJUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
+
+        Artifact expectedProvider = new DefaultArtifact( "org.apache.maven.surefire", "surefire-junit-platform",
+                surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact expectedCommonJava5 = new DefaultArtifact( "org.apache.maven.surefire", "common-java5",
+                surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact expectedLauncher = new DefaultArtifact( "org.junit.platform", "junit-platform-launcher",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        assertThat( prov.getProviderClasspath() )
+                .hasSize( 3 )
+                .containsOnly( expectedProvider, expectedCommonJava5, expectedLauncher );
+
+        assertThat( testClasspathWrapper.getTestDependencies() )
+                .hasSize( 8 )
+                .includes( entry(  "third.party:artifact", testClasspathSomeTestArtifact ),
+                        entry(  "org.junit.vintage:junit-vintage-engine", testClasspathVintage ),
+                        entry(  "org.apiguardian:apiguardian-api", testClasspathApiguardian ),
+                        entry(  "org.junit.platform:junit-platform-engine", testClasspathPlatformEng ),
+                        entry(  "junit:junit", testClasspathJUnit4 ),
+                        entry(  "org.hamcrest:hamcrest-core", testClasspathHamcrest ),
+                        entry(  "org.opentest4j:opentest4j", testClasspathOpentest4j ),
+                        entry( "org.junit.platform:junit-platform-commons", testClasspathCommons ) );
+    }
+
+    @Test
+    public void shouldSmartlyResolveJUnit5ProviderWithJUnit5Commons() throws Exception
+    {
+        MavenProject mavenProject = new MavenProject();
+        mavenProject.setArtifact( new DefaultArtifact( "dummy", "pom", createFromVersion( "1.0.0" ),
+                null, "jar", null, mock( ArtifactHandler.class ) ) );
+        mojo.setProject( mavenProject );
+
+        final VersionRange surefireVersion = createFromVersion( "1" );
+
+        Artifact junitPlatformArtifact = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathSomeTestArtifact = new DefaultArtifact( "third.party", "artifact",
+                createFromVersion( "1.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathCommons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathApiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        Iterable<Artifact> testArtifacts =
+                asList( testClasspathSomeTestArtifact, testClasspathApiguardian, testClasspathCommons );
+
+        File classesDirectory = new File( "target/classes" );
+
+        File testClassesDirectory = new File( "target/test-classes" );
+
+        TestClassPath testClasspathWrapper =
+                new TestClassPath( testArtifacts, classesDirectory, testClassesDirectory, null );
+
+        Artifact forkedBooter = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-booter", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+
+        mojo.setPluginArtifactMap( singletonMap( "org.apache.maven.surefire:surefire-booter", forkedBooter ) );
+        mojo.setRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        mojo.setProjectRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        RepositorySystem repositorySystem = mock( RepositorySystem.class );
+        final Artifact surefireProvider = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        when( repositorySystem.createDependencyArtifact( any( Dependency.class ) ) ).thenAnswer( new Answer<Artifact>()
+        {
+            @Override
+            public Artifact answer( InvocationOnMock invocation )
+            {
+                Dependency provider = (Dependency) invocation.getArguments()[0];
+                assertThat( provider.getGroupId() ).isEqualTo( "org.apache.maven.surefire" );
+                assertThat( provider.getArtifactId() ).isEqualTo( "surefire-junit-platform" );
+                return surefireProvider;
+            }
+        } );
+
+        when( repositorySystem.resolve( any( ArtifactResolutionRequest.class ) ) )
+                .thenAnswer( new Answer<ArtifactResolutionResult>()
+                {
+                    @Override
+                    public ArtifactResolutionResult answer( InvocationOnMock invocation )
+                    {
+                        ArtifactResolutionRequest req = (ArtifactResolutionRequest) invocation.getArguments()[0];
+                        Artifact resolvable = req.getArtifact();
+                        if ( resolvable == surefireProvider )
+                        {
+                            return createSurefireProviderResolutionResult( surefireVersion );
+                        }
+                        else
+                        {
+                            fail();
+                            return null;
+                        }
+                    }
+                } );
+
+        DependencyResolver dependencyResolver = mock( DependencyResolver.class );
+        when( dependencyResolver.resolveDependencies( any( ProjectBuildingRequest.class ),
+                ArgumentMatchers.<Dependency>anyCollection(), isNull( Collection.class ),
+                any( TransformableFilter.class ) ) )
+                .thenAnswer( new Answer<Object>()
+                {
+                    @Override
+                    public Object answer( InvocationOnMock invocation )
+                    {
+                        Collection deps = (Collection) invocation.getArguments()[1];
+                        assertThat( deps ).isEmpty();
+                        return emptySet();
+                    }
+                } );
+
+        mojo.setRepositorySystem( repositorySystem );
+        mojo.setLogger( mock( Logger.class ) );
+        mojo.setDependencyResolver( dependencyResolver );
+
+        invokeMethod( mojo, "setupStuff" );
+
+        MavenSession session = mock( MavenSession.class );
+        mojo.setSession( session );
+        when( session.getProjectBuildingRequest() )
+                .thenReturn( mock( ProjectBuildingRequest.class ) );
+
+        PluginDescriptor pluginDescriptor = mock( PluginDescriptor.class );
+        mojo.setPluginDescriptor( pluginDescriptor );
+        Plugin p = mock( Plugin.class );
+        when( pluginDescriptor.getPlugin() )
+                .thenReturn( p );
+        when( p.getDependencies() )
+                .thenReturn( Collections.<Dependency>emptyList() );
+
+        JUnitPlatformProviderInfo prov =
+                mojo.createJUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
+        Set<Artifact> resolvedProviderArtifacts = prov.getProviderClasspath();
+
+        Artifact provider = new DefaultArtifact( "org.apache.maven.surefire", "surefire-junit-platform",
+                surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact java5 = new DefaultArtifact( "org.apache.maven.surefire", "common-java5",
+                surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact launcher = new DefaultArtifact( "org.junit.platform", "junit-platform-launcher",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact engine = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact opentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        assertThat( resolvedProviderArtifacts )
+                .hasSize( 5 )
+                .containsOnly( provider, java5, launcher, engine, opentest4j );
+
+        assertThat( testClasspathWrapper.getTestDependencies() )
+                .hasSize( 3 )
+                .includes( entry( "third.party:artifact", testClasspathSomeTestArtifact ),
+                        entry( "org.junit.platform:junit-platform-commons", testClasspathCommons ),
+                        entry( "org.apiguardian:apiguardian-api", testClasspathApiguardian ) );
+    }
+
+    @Test
+    public void shouldSmartlyResolveJUnit5ProviderWithJUnit5Engine() throws Exception
+    {
+        MavenProject mavenProject = new MavenProject();
+        mavenProject.setArtifact( new DefaultArtifact( "dummy", "pom", createFromVersion( "1.0.0" ),
+                null, "jar", null, mock( ArtifactHandler.class ) ) );
+        mojo.setProject( mavenProject );
+
+        final VersionRange surefireVersion = createFromVersion( "1" );
+
+        Artifact junitPlatformArtifact = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathSomeTestArtifact = new DefaultArtifact( "third.party", "artifact",
+                createFromVersion( "1.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathJUnit5 = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathApiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathCommons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathOpentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        Iterable<Artifact> testArtifacts = asList( testClasspathSomeTestArtifact, testClasspathJUnit5,
+                testClasspathApiguardian, testClasspathCommons, testClasspathOpentest4j );
+
+        File classesDirectory = new File( "target/classes" );
+
+        File testClassesDirectory = new File( "target/test-classes" );
+
+        TestClassPath testClasspathWrapper =
+                new TestClassPath( testArtifacts, classesDirectory, testClassesDirectory, null );
+
+        Artifact forkedBooter = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-booter", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+
+        mojo.setPluginArtifactMap( singletonMap( "org.apache.maven.surefire:surefire-booter", forkedBooter ) );
+        mojo.setRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        mojo.setProjectRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        RepositorySystem repositorySystem = mock( RepositorySystem.class );
+        final Artifact surefireProvider = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        when( repositorySystem.createDependencyArtifact( any( Dependency.class ) ) ).thenAnswer( new Answer<Artifact>()
+        {
+            @Override
+            public Artifact answer( InvocationOnMock invocation )
+            {
+                Dependency provider = (Dependency) invocation.getArguments()[0];
+                assertThat( provider.getGroupId() ).isEqualTo( "org.apache.maven.surefire" );
+                assertThat( provider.getArtifactId() ).isEqualTo( "surefire-junit-platform" );
+                return surefireProvider;
+            }
+        } );
+
+        when( repositorySystem.resolve( any( ArtifactResolutionRequest.class ) ) )
+                .thenAnswer( new Answer<ArtifactResolutionResult>()
+                {
+                    @Override
+                    public ArtifactResolutionResult answer( InvocationOnMock invocation )
+                    {
+                        ArtifactResolutionRequest req = (ArtifactResolutionRequest) invocation.getArguments()[0];
+                        Artifact resolvable = req.getArtifact();
+                        if ( resolvable == surefireProvider )
+                        {
+                            return createSurefireProviderResolutionResult( surefireVersion );
+                        }
+                        else if ( resolvable.equals( testClasspathJUnit5 )  )
+                        {
+                            return createResolutionResult( testClasspathJUnit5, testClasspathApiguardian,
+                                    testClasspathCommons, testClasspathOpentest4j );
+                        }
+                        else if ( "org.junit.platform".equals( resolvable.getGroupId() )
+                                && "junit-platform-launcher".equals( resolvable.getArtifactId() )
+                                && "1.4.0".equals( resolvable.getVersion() ) )
+                        {
+                            return createExpectedJUnitPlatformLauncherResolutionResult();
+                        }
+                        else
+                        {
+                            fail();
+                            return null;
+                        }
+                    }
+                } );
+
+        mojo.setRepositorySystem( repositorySystem );
+        mojo.setLogger( mock( Logger.class ) );
+
+        invokeMethod( mojo, "setupStuff" );
+        JUnitPlatformProviderInfo prov =
+                mojo.createJUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
+        Set<Artifact> resolvedProviderArtifacts = prov.getProviderClasspath();
+
+        Artifact java5 = new DefaultArtifact( "org.apache.maven.surefire", "common-java5",
+                surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact launcher = new DefaultArtifact( "org.junit.platform", "junit-platform-launcher",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        assertThat( resolvedProviderArtifacts )
+                .hasSize( 3 )
+                .containsOnly( surefireProvider, java5, launcher );
+
+        assertThat( testClasspathWrapper.getTestDependencies() )
+                .hasSize( 5 )
+                .includes( entry( "third.party:artifact", testClasspathSomeTestArtifact ),
+                        entry( "org.junit.platform:junit-platform-engine", testClasspathJUnit5 ),
+                        entry( "org.apiguardian:apiguardian-api", testClasspathApiguardian ),
+                        entry( "org.junit.platform:junit-platform-commons", testClasspathCommons ),
+                        entry( "org.opentest4j:opentest4j", testClasspathOpentest4j ) );
+    }
+
+    @Test
+    public void shouldSmartlyResolveJUnit5ProviderWithJupiterApi() throws Exception
+    {
+        MavenProject mavenProject = new MavenProject();
+        mavenProject.setArtifact( new DefaultArtifact( "dummy", "pom", createFromVersion( "1.0.0" ),
+                null, "jar", null, mock( ArtifactHandler.class ) ) );
+        mojo.setProject( mavenProject );
+
+        final VersionRange surefireVersion = createFromVersion( "1" );
+
+        Artifact junitPlatformArtifact = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathSomeTestArtifact = new DefaultArtifact( "third.party", "artifact",
+                createFromVersion( "1.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathJupiterApi = new DefaultArtifact( "org.junit.jupiter", "junit-jupiter-api",
+                createFromVersion( "5.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathApiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathCommons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathOpentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        Iterable<Artifact> testArtifacts = asList( testClasspathSomeTestArtifact, testClasspathJupiterApi,
+                testClasspathApiguardian, testClasspathCommons, testClasspathOpentest4j );
+
+        File classesDirectory = new File( "target/classes" );
+
+        File testClassesDirectory = new File( "target/test-classes" );
+
+        TestClassPath testClasspathWrapper =
+                new TestClassPath( testArtifacts, classesDirectory, testClassesDirectory, null );
+
+        Artifact forkedBooter = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-booter", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+
+        mojo.setPluginArtifactMap( singletonMap( "org.apache.maven.surefire:surefire-booter", forkedBooter ) );
+        mojo.setRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        mojo.setProjectRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        RepositorySystem repositorySystem = mock( RepositorySystem.class );
+        final Artifact surefireProvider = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        when( repositorySystem.createDependencyArtifact( any( Dependency.class ) ) ).thenAnswer( new Answer<Artifact>()
+        {
+            @Override
+            public Artifact answer( InvocationOnMock invocation )
+            {
+                Dependency provider = (Dependency) invocation.getArguments()[0];
+                assertThat( provider.getGroupId() ).isEqualTo( "org.apache.maven.surefire" );
+                assertThat( provider.getArtifactId() ).isEqualTo( "surefire-junit-platform" );
+                return surefireProvider;
+            }
+        } );
+
+        when( repositorySystem.resolve( any( ArtifactResolutionRequest.class ) ) )
+                .thenAnswer( new Answer<ArtifactResolutionResult>()
+                {
+                    @Override
+                    public ArtifactResolutionResult answer( InvocationOnMock invocation )
+                    {
+                        ArtifactResolutionRequest req = (ArtifactResolutionRequest) invocation.getArguments()[0];
+                        Artifact resolvable = req.getArtifact();
+                        if ( resolvable == surefireProvider )
+                        {
+                            return createSurefireProviderResolutionResult( surefireVersion );
+                        }
+                        else if ( resolvable.equals( testClasspathJupiterApi )  )
+                        {
+                            return createResolutionResult( testClasspathJupiterApi, testClasspathApiguardian,
+                                    testClasspathCommons, testClasspathOpentest4j );
+                        }
+                        else if ( "org.junit.platform".equals( resolvable.getGroupId() )
+                                && "junit-platform-launcher".equals( resolvable.getArtifactId() )
+                                && "1.4.0".equals( resolvable.getVersion() ) )
+                        {
+                            return createExpectedJUnitPlatformLauncherResolutionResult();
+                        }
+                        else if ( "org.junit.jupiter".equals( resolvable.getGroupId() )
+                                && "junit-jupiter-engine".equals( resolvable.getArtifactId() )
+                                && "5.4.0".equals( resolvable.getVersion() ) )
+                        {
+                            return createJupiterEngineResolutionResult();
+                        }
+                        else
+                        {
+                            fail();
+                            return null;
+                        }
+                    }
+                } );
+
+        DependencyResolver dependencyResolver = mock( DependencyResolver.class );
+        when( dependencyResolver.resolveDependencies( any( ProjectBuildingRequest.class ),
+                ArgumentMatchers.<Dependency>anyCollection(), isNull( Collection.class ),
+                any( TransformableFilter.class ) ) )
+                .thenAnswer( new Answer<Object>()
+                {
+                    @Override
+                    public Object answer( InvocationOnMock invocation )
+                    {
+                        Collection deps = (Collection) invocation.getArguments()[1];
+                        assertThat( deps ).isEmpty();
+                        return emptySet();
+                    }
+                } );
+
+        mojo.setRepositorySystem( repositorySystem );
+        mojo.setLogger( mock( Logger.class ) );
+        mojo.setDependencyResolver( dependencyResolver );
+
+        invokeMethod( mojo, "setupStuff" );
+
+        MavenSession session = mock( MavenSession.class );
+        mojo.setSession( session );
+        when( session.getProjectBuildingRequest() )
+                .thenReturn( mock( ProjectBuildingRequest.class ) );
+
+        PluginDescriptor pluginDescriptor = mock( PluginDescriptor.class );
+        mojo.setPluginDescriptor( pluginDescriptor );
+        Plugin p = mock( Plugin.class );
+        when( pluginDescriptor.getPlugin() )
+                .thenReturn( p );
+        when( p.getDependencies() )
+                .thenReturn( Collections.<Dependency>emptyList() );
+
+        JUnitPlatformProviderInfo prov =
+                mojo.createJUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
+        Set<Artifact> resolvedProviderArtifacts = prov.getProviderClasspath();
+
+        Artifact java5 = new DefaultArtifact( "org.apache.maven.surefire", "common-java5",
+                surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact launcher = new DefaultArtifact( "org.junit.platform", "junit-platform-launcher",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact jupiterEngine = new DefaultArtifact( "org.junit.jupiter", "junit-jupiter-engine",
+                createFromVersion( "5.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact platformEngine = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        assertThat( resolvedProviderArtifacts )
+                .hasSize( 5 )
+                .containsOnly( surefireProvider, java5, launcher, jupiterEngine, platformEngine );
+
+        assertThat( testClasspathWrapper.getTestDependencies() )
+                .hasSize( 5 )
+                .includes( entry( "third.party:artifact", testClasspathSomeTestArtifact ),
+                        entry( "org.junit.jupiter:junit-jupiter-api", testClasspathJupiterApi ),
+                        entry( "org.apiguardian:apiguardian-api", testClasspathApiguardian ),
+                        entry( "org.junit.platform:junit-platform-commons", testClasspathCommons ),
+                        entry( "org.opentest4j:opentest4j", testClasspathOpentest4j ) );
+    }
+
+    @Test
+    public void shouldSmartlyResolveJUnit5ProviderWithJupiterEngine() throws Exception
+    {
+        MavenProject mavenProject = new MavenProject();
+        mavenProject.setArtifact( new DefaultArtifact( "dummy", "pom", createFromVersion( "1.0.0" ),
+                null, "jar", null, mock( ArtifactHandler.class ) ) );
+        mojo.setProject( mavenProject );
+
+        final VersionRange surefireVersion = createFromVersion( "1" );
+
+        Artifact junitPlatformArtifact = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathSomeTestArtifact = new DefaultArtifact( "third.party", "artifact",
+                createFromVersion( "1.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathJupiterEngine = new DefaultArtifact( "org.junit.jupiter", "junit-jupiter-engine",
+                createFromVersion( "5.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathPlatformEngine = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathJupiterApi = new DefaultArtifact( "org.junit.jupiter", "junit-jupiter-api",
+                createFromVersion( "5.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathApiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathCommons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathOpentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        Iterable<Artifact> testArtifacts = asList( testClasspathSomeTestArtifact, testClasspathJupiterEngine,
+                testClasspathPlatformEngine, testClasspathJupiterApi, testClasspathApiguardian, testClasspathCommons,
+                testClasspathOpentest4j );
+
+        File classesDirectory = new File( "target/classes" );
+
+        File testClassesDirectory = new File( "target/test-classes" );
+
+        TestClassPath testClasspathWrapper =
+                new TestClassPath( testArtifacts, classesDirectory, testClassesDirectory, null );
+
+        Artifact forkedBooter = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-booter", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+
+        mojo.setPluginArtifactMap( singletonMap( "org.apache.maven.surefire:surefire-booter", forkedBooter ) );
+        mojo.setRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        mojo.setProjectRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        RepositorySystem repositorySystem = mock( RepositorySystem.class );
+        final Artifact surefireProvider = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        when( repositorySystem.createDependencyArtifact( any( Dependency.class ) ) ).thenAnswer( new Answer<Artifact>()
+        {
+            @Override
+            public Artifact answer( InvocationOnMock invocation )
+            {
+                Dependency provider = (Dependency) invocation.getArguments()[0];
+                assertThat( provider.getGroupId() ).isEqualTo( "org.apache.maven.surefire" );
+                assertThat( provider.getArtifactId() ).isEqualTo( "surefire-junit-platform" );
+                return surefireProvider;
+            }
+        } );
+
+        when( repositorySystem.resolve( any( ArtifactResolutionRequest.class ) ) )
+                .thenAnswer( new Answer<ArtifactResolutionResult>()
+                {
+                    @Override
+                    public ArtifactResolutionResult answer( InvocationOnMock invocation )
+                    {
+                        ArtifactResolutionRequest req = (ArtifactResolutionRequest) invocation.getArguments()[0];
+                        Artifact resolvable = req.getArtifact();
+                        if ( resolvable == surefireProvider )
+                        {
+                            return createSurefireProviderResolutionResult( surefireVersion );
+                        }
+                        else if ( resolvable.equals( testClasspathJupiterApi )  )
+                        {
+                            return createResolutionResult( testClasspathJupiterApi, testClasspathApiguardian,
+                                    testClasspathCommons, testClasspathOpentest4j );
+                        }
+                        else if ( "org.junit.platform".equals( resolvable.getGroupId() )
+                                && "junit-platform-launcher".equals( resolvable.getArtifactId() )
+                                && "1.4.0".equals( resolvable.getVersion() ) )
+                        {
+                            return createExpectedJUnitPlatformLauncherResolutionResult();
+                        }
+                        else if ( "org.junit.platform".equals( resolvable.getGroupId() )
+                                && "junit-platform-engine".equals( resolvable.getArtifactId() )
+                                && "1.4.0".equals( resolvable.getVersion() ) )
+                        {
+                            return createVintageEngineResolutionResult();
+                        }
+                        else
+                        {
+                            fail();
+                            return null;
+                        }
+                    }
+                } );
+
+        mojo.setRepositorySystem( repositorySystem );
+        mojo.setLogger( mock( Logger.class ) );
+
+        invokeMethod( mojo, "setupStuff" );
+        JUnitPlatformProviderInfo prov =
+                mojo.createJUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
+        Set<Artifact> resolvedProviderArtifacts = prov.getProviderClasspath();
+
+        Artifact java5 = new DefaultArtifact( "org.apache.maven.surefire", "common-java5",
+                surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact launcher = new DefaultArtifact( "org.junit.platform", "junit-platform-launcher",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        assertThat( resolvedProviderArtifacts )
+                .hasSize( 3 )
+                .containsOnly( surefireProvider, java5, launcher );
+
+        assertThat( testClasspathWrapper.getTestDependencies() )
+                .hasSize( 7 )
+                .includes( entry( "third.party:artifact", testClasspathSomeTestArtifact ),
+                        entry( "org.junit.jupiter:junit-jupiter-engine", testClasspathJupiterEngine ),
+                        entry( "org.junit.platform:junit-platform-engine", testClasspathPlatformEngine ),
+                        entry( "org.junit.jupiter:junit-jupiter-api", testClasspathJupiterApi ),
+                        entry( "org.apiguardian:apiguardian-api", testClasspathApiguardian ),
+                        entry( "org.junit.platform:junit-platform-commons", testClasspathCommons ),
+                        entry( "org.opentest4j:opentest4j", testClasspathOpentest4j ) );
+    }
+
+    @Test
+    public void shouldSmartlyResolveJUnit5ProviderWithJupiterEngineInPluginDependencies() throws Exception
+    {
+
+        final VersionRange surefireVersion = createFromVersion( "1" );
+
+        final Artifact plugin = new DefaultArtifact( "org.apache.maven.surefire", "maven-surefire-plugin",
+                surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact forkedBooter = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-booter", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact pluginDepJupiterEngine = new DefaultArtifact( "org.junit.jupiter", "junit-jupiter-engine",
+                createFromVersion( "5.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact pluginDepPlatformEngine = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact pluginDepJupiterApi = new DefaultArtifact( "org.junit.jupiter", "junit-jupiter-api",
+                createFromVersion( "5.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact pluginDepApiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact pluginDepCommons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact pluginDepOpentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        Map<String, Artifact> pluginDependencies = new HashMap<>();
+        pluginDependencies.put( "org.apache.maven.surefire:maven-surefire-plugin", plugin );
+        pluginDependencies.put( "org.apache.maven.surefire:surefire-booter", forkedBooter );
+        pluginDependencies.put( "org.junit.jupiter:junit-jupiter-engine", pluginDepJupiterEngine );
+        pluginDependencies.put( "org.junit.platform:junit-platform-engine", pluginDepPlatformEngine );
+        pluginDependencies.put( "org.junit.jupiter:junit-jupiter-api", pluginDepJupiterApi );
+        pluginDependencies.put( "org.apiguardian:apiguardian-api", pluginDepApiguardian );
+        pluginDependencies.put( "org.junit.platform:junit-platform-commons", pluginDepCommons );
+        pluginDependencies.put( "org.opentest4j:opentest4j", pluginDepOpentest4j );
+        mojo.setPluginArtifactMap( pluginDependencies );
+
+        MavenProject mavenProject = new MavenProject();
+        mavenProject.setArtifact( new DefaultArtifact( "dummy", "pom", createFromVersion( "1.0.0" ),
+                null, "jar", null, mock( ArtifactHandler.class ) ) );
+        mojo.setProject( mavenProject );
+
+        Artifact junitPlatformArtifact = new DefaultArtifact( "g", "a",
+                createFromVersion( "0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathSomeTestArtifact = new DefaultArtifact( "third.party", "artifact",
+                createFromVersion( "1.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathJupiterApi = new DefaultArtifact( "org.junit.jupiter", "junit-jupiter-api",
+                createFromVersion( "5.3.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathApiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathCommons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        final Artifact testClasspathOpentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        Iterable<Artifact> testArtifacts = asList( testClasspathSomeTestArtifact, testClasspathJupiterApi,
+                testClasspathApiguardian, testClasspathCommons, testClasspathOpentest4j );
+
+        File classesDirectory = new File( "target/classes" );
+
+        File testClassesDirectory = new File( "target/test-classes" );
+
+        TestClassPath testClasspathWrapper =
+                new TestClassPath( testArtifacts, classesDirectory, testClassesDirectory, null );
+
+        mojo.setRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        mojo.setProjectRemoteRepositories( Collections.<ArtifactRepository>emptyList() );
+        RepositorySystem repositorySystem = mock( RepositorySystem.class );
+        final Artifact surefireProvider = new DefaultArtifact( "org.apache.maven.surefire",
+                "surefire-junit-platform", surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        when( repositorySystem.createDependencyArtifact( any( Dependency.class ) ) ).thenAnswer( new Answer<Artifact>()
+        {
+            @Override
+            public Artifact answer( InvocationOnMock invocation )
+            {
+                Dependency provider = (Dependency) invocation.getArguments()[0];
+                assertThat( provider.getGroupId() ).isEqualTo( "org.apache.maven.surefire" );
+                assertThat( provider.getArtifactId() ).isEqualTo( "surefire-junit-platform" );
+                return surefireProvider;
+            }
+        } );
+
+        when( repositorySystem.resolve( any( ArtifactResolutionRequest.class ) ) )
+                .thenAnswer( new Answer<ArtifactResolutionResult>()
+                {
+                    @Override
+                    public ArtifactResolutionResult answer( InvocationOnMock invocation )
+                    {
+                        ArtifactResolutionRequest req = (ArtifactResolutionRequest) invocation.getArguments()[0];
+                        Artifact resolvable = req.getArtifact();
+                        if ( resolvable == surefireProvider )
+                        {
+                            return createSurefireProviderResolutionResult( surefireVersion );
+                        }
+                        else if ( "org.junit.platform".equals( resolvable.getGroupId() )
+                                && "junit-platform-launcher".equals( resolvable.getArtifactId() )
+                                && "1.4.0".equals( resolvable.getVersion() ) )
+                        {
+                            return createExpectedJUnitPlatformLauncherResolutionResult();
+                        }
+                        else if ( "org.apache.maven.surefire".equals( resolvable.getGroupId() )
+                                && "maven-surefire-plugin".equals( resolvable.getArtifactId() )
+                                && "1".equals( resolvable.getVersion() ) )
+                        {
+                            Set<Artifact> pluginItself = new HashSet<>();
+                            pluginItself.add( plugin );
+                            pluginItself.add( forkedBooter );
+                            ArtifactResolutionResult launcherResolutionResult = mock( ArtifactResolutionResult.class );
+                            when( launcherResolutionResult.getArtifacts() )
+                                    .thenReturn( pluginItself );
+                            return launcherResolutionResult;
+                        }
+                        else
+                        {
+                            fail();
+                            return null;
+                        }
+                    }
+                } );
+
+        DependencyResolver dependencyResolver = mock( DependencyResolver.class );
+        when( dependencyResolver.resolveDependencies( any( ProjectBuildingRequest.class ),
+                ArgumentMatchers.<Dependency>anyCollection(), isNull( Collection.class ),
+                any( TransformableFilter.class ) ) )
+                .thenAnswer( new Answer<Object>()
+                {
+                    @Override
+                    public Object answer( InvocationOnMock invocation )
+                    {
+                        Collection deps = (Collection) invocation.getArguments()[1];
+                        assertThat( deps ).hasSize( 1 );
+                        Dependency resolvable = (Dependency) deps.iterator().next();
+                        if ( "org.junit.jupiter".equals( resolvable.getGroupId() )
+                                && "junit-jupiter-engine".equals( resolvable.getArtifactId() )
+                                && "5.4.0".equals( resolvable.getVersion() ) )
+                        {
+                            Set<ArtifactResult> resolvedPluginDeps = new HashSet<>();
+                            resolvedPluginDeps.add( toArtifactResult( pluginDepJupiterEngine ) );
+                            resolvedPluginDeps.add( toArtifactResult( pluginDepPlatformEngine ) );
+                            resolvedPluginDeps.add( toArtifactResult( pluginDepJupiterApi ) );
+                            resolvedPluginDeps.add( toArtifactResult( pluginDepApiguardian ) );
+                            resolvedPluginDeps.add( toArtifactResult( pluginDepCommons ) );
+                            resolvedPluginDeps.add( toArtifactResult( pluginDepOpentest4j ) );
+                            return resolvedPluginDeps;
+                        }
+                        else
+                        {
+                            fail();
+                            return null;
+                        }
+                    }
+                } );
+
+        mojo.setRepositorySystem( repositorySystem );
+        mojo.setLogger( mock( Logger.class ) );
+        mojo.setDependencyResolver( dependencyResolver );
+
+        invokeMethod( mojo, "setupStuff" );
+
+        JUnitPlatformProviderInfo prov =
+                mojo.createJUnitPlatformProviderInfo( junitPlatformArtifact, testClasspathWrapper );
+
+        MavenSession session = mock( MavenSession.class );
+        mojo.setSession( session );
+        when( session.getProjectBuildingRequest() )
+                .thenReturn( mock( ProjectBuildingRequest.class ) );
+
+        PluginDescriptor pluginDescriptor = mock( PluginDescriptor.class );
+        mojo.setPluginDescriptor( pluginDescriptor );
+        Plugin p = mock( Plugin.class );
+        when( pluginDescriptor.getPlugin() )
+                .thenReturn( p );
+        List<Dependency> directPluginDependencies = toDependencies( pluginDepJupiterEngine );
+        when( p.getDependencies() )
+                .thenReturn( directPluginDependencies );
+
+        Set<Artifact> resolvedProviderArtifacts = prov.getProviderClasspath();
+
+        Artifact java5 = new DefaultArtifact( "org.apache.maven.surefire", "common-java5",
+                surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact launcher = new DefaultArtifact( "org.junit.platform", "junit-platform-launcher",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact jupiterEngine = new DefaultArtifact( "org.junit.jupiter", "junit-jupiter-engine",
+                createFromVersion( "5.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact platformEngine = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        assertThat( resolvedProviderArtifacts )
+                .hasSize( 5 )
+                .containsOnly( surefireProvider, java5, launcher, jupiterEngine, platformEngine );
+
+        assertThat( testClasspathWrapper.getTestDependencies() )
+                .hasSize( 5 )
+                .includes( entry( "third.party:artifact", testClasspathSomeTestArtifact ),
+                        entry( "org.junit.jupiter:junit-jupiter-api", testClasspathJupiterApi ),
+                        entry( "org.apiguardian:apiguardian-api", testClasspathApiguardian ),
+                        entry( "org.junit.platform:junit-platform-commons", testClasspathCommons ),
+                        entry( "org.opentest4j:opentest4j", testClasspathOpentest4j ) );
+    }
+
+    private static ArtifactResolutionResult createJUnitPlatformLauncherResolutionResult(
+            Artifact junit5Engine, Artifact apiguardian, Artifact commons, Artifact opentest4j )
+    {
+        ArtifactResolutionResult launcherResolutionResult = mock( ArtifactResolutionResult.class );
+        Set<Artifact> resolvedLauncherArtifacts = new HashSet<>();
+        Artifact launcher = new DefaultArtifact( "org.junit.platform", "junit-platform-launcher",
+                commons.getVersionRange(), null, "jar", null, mock( ArtifactHandler.class ) );
+        resolvedLauncherArtifacts.add( launcher );
+        resolvedLauncherArtifacts.add( apiguardian );
+        resolvedLauncherArtifacts.add( junit5Engine );
+        resolvedLauncherArtifacts.add( commons );
+        resolvedLauncherArtifacts.add( opentest4j );
+        resolvedLauncherArtifacts.remove( null );
+        when( launcherResolutionResult.getArtifacts() )
+                .thenReturn( resolvedLauncherArtifacts );
+        return launcherResolutionResult;
+    }
+
+    private static ArtifactResolutionResult createVintageEngineResolutionResult()
+    {
+        ArtifactResolutionResult launcherResolutionResult = mock( ArtifactResolutionResult.class );
+        Set<Artifact> resolvedLauncherArtifacts = new HashSet<>();
+        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.junit.vintage", "junit-vintage-engine",
+                createFromVersion( "5.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
+        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.junit.jupiter", "junit-jupiter-api",
+                createFromVersion( "5.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
+        resolvedLauncherArtifacts.add( new DefaultArtifact( "junit", "junit",
+                createFromVersion( "4.12" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
+        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.hamcrest", "hamcrest-core",
+                createFromVersion( "1.3" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
+        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
+        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
+        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
+        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
+        when( launcherResolutionResult.getArtifacts() )
+                .thenReturn( resolvedLauncherArtifacts );
+        return launcherResolutionResult;
+    }
+
+    private static ArtifactResolutionResult createJupiterEngineResolutionResult()
+    {
+        ArtifactResolutionResult launcherResolutionResult = mock( ArtifactResolutionResult.class );
+        Set<Artifact> resolvedLauncherArtifacts = new HashSet<>();
+        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.junit.jupiter", "junit-jupiter-engine",
+                createFromVersion( "5.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
+        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.junit.jupiter", "junit-jupiter-api",
+                createFromVersion( "5.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
+        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
+        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
+        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
+        resolvedLauncherArtifacts.add( new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) ) );
+        when( launcherResolutionResult.getArtifacts() )
+                .thenReturn( resolvedLauncherArtifacts );
+        return launcherResolutionResult;
+    }
+
+    private static ArtifactResolutionResult createExpectedJUnitPlatformLauncherResolutionResult()
+    {
+        Artifact engine = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact commons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.4.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact apiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact opentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        return createJUnitPlatformLauncherResolutionResult( engine, apiguardian, commons, opentest4j );
+    }
+
+    private static ArtifactResolutionResult createResolutionResult( Artifact... artifacts )
+    {
+        ArtifactResolutionResult testClasspathCommonsResolutionResult = mock( ArtifactResolutionResult.class );
+        Set<Artifact> resolvedCommonsArtifacts = new HashSet<>();
+        Collections.addAll( resolvedCommonsArtifacts, artifacts );
+        when( testClasspathCommonsResolutionResult.getArtifacts() )
+                .thenReturn( resolvedCommonsArtifacts );
+        return testClasspathCommonsResolutionResult;
+    }
+
+    private static ArtifactResolutionResult createSurefireProviderResolutionResult( VersionRange surefireVersion )
+    {
+        ArtifactResolutionResult surefirePlatformResolutionResult = mock( ArtifactResolutionResult.class );
+
+        Artifact provider = new DefaultArtifact( "org.apache.maven.surefire", "surefire-junit-platform",
+                surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact java5 = new DefaultArtifact( "org.apache.maven.surefire", "common-java5",
+                surefireVersion, null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact launcher = new DefaultArtifact( "org.junit.platform", "junit-platform-launcher",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact apiguardian = new DefaultArtifact( "org.apiguardian", "apiguardian-api",
+                createFromVersion( "1.0.0" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact engine = new DefaultArtifact( "org.junit.platform", "junit-platform-engine",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact commons = new DefaultArtifact( "org.junit.platform", "junit-platform-commons",
+                createFromVersion( "1.3.2" ), null, "jar", null, mock( ArtifactHandler.class ) );
+        Artifact opentest4j = new DefaultArtifact( "org.opentest4j", "opentest4j",
+                createFromVersion( "1.1.1" ), null, "jar", null, mock( ArtifactHandler.class ) );
+
+        Set<Artifact> providerArtifacts = new HashSet<>();
+        providerArtifacts.add( provider );
+        providerArtifacts.add( java5 );
+        providerArtifacts.add( launcher );
+        providerArtifacts.add( apiguardian );
+        providerArtifacts.add( engine );
+        providerArtifacts.add( commons );
+        providerArtifacts.add( opentest4j );
+
+        when( surefirePlatformResolutionResult.getArtifacts() )
+                .thenReturn( providerArtifacts );
+        return surefirePlatformResolutionResult;
+    }
+
     public static class Mojo
             extends AbstractSurefireMojo
     {
+        private JUnitPlatformProviderInfo createJUnitPlatformProviderInfo( Artifact providerArtifact,
+                                                                           TestClassPath testClasspathWrapper )
+        {
+            return new JUnitPlatformProviderInfo( providerArtifact, testClasspathWrapper );
+        }
+
+        @Override
+        protected void logDebugOrCliShowErrors( String s )
+        {
+            // do nothing
+        }
+
         @Override
         protected String getPluginName()
         {
@@ -726,7 +1948,8 @@ public class AbstractSurefireMojoTest
         @Override
         protected Artifact getMojoArtifact()
         {
-            return null;
+            return new DefaultArtifact( "org.apache.maven.surefire", "maven-surefire-plugin", createFromVersion( "1" ),
+                    null, "jar", null, mock( ArtifactHandler.class ) );
         }
     }
 
@@ -736,4 +1959,38 @@ public class AbstractSurefireMojoTest
         when( f.getAbsolutePath() ).thenReturn( absolutePath );
         return f;
     }
+
+    private static Dependency toDependency( Artifact artifact )
+    {
+        Dependency dependency = new Dependency();
+        dependency.setGroupId( artifact.getGroupId() );
+        dependency.setArtifactId( artifact.getArtifactId() );
+        dependency.setVersion( artifact.getBaseVersion() );
+        dependency.setType( "jar" );
+        return dependency;
+    }
+
+    private static List<Dependency> toDependencies( Artifact... artifacts )
+    {
+        List<Dependency> dependencies = new ArrayList<>();
+        for ( Artifact artifact : artifacts )
+        {
+            dependencies.add( toDependency( artifact) );
+        }
+        return dependencies;
+    }
+
+    private static ArtifactResult toArtifactResult( final Artifact artifact )
+    {
+        class AR implements ArtifactResult
+        {
+
+            @Override
+            public Artifact getArtifact()
+            {
+                return artifact;
+            }
+        }
+        return new AR();
+    }
 }
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireDependencyResolverTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireDependencyResolverTest.java
index ab57aef..fdb1bbe 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireDependencyResolverTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SurefireDependencyResolverTest.java
@@ -145,9 +145,9 @@ public class SurefireDependencyResolverTest
                 } );
 
         SurefireDependencyResolver surefireDependencyResolver =
-                new SurefireDependencyResolver( repositorySystem, null, null, null, null );
+                new SurefireDependencyResolver( repositorySystem, null, null, null, null, null, null );
 
-        ArtifactResolutionResult actualResult = surefireDependencyResolver.resolveArtifact( provider );
+        ArtifactResolutionResult actualResult = surefireDependencyResolver.resolvePluginArtifact( provider );
 
         assertThat( actualResult )
                 .isSameAs( expectedResult );
@@ -243,7 +243,7 @@ public class SurefireDependencyResolverTest
         ConsoleLogger log = mock( ConsoleLogger.class );
 
         SurefireDependencyResolver surefireDependencyResolver =
-                new SurefireDependencyResolver( repositorySystem, log, null, null, null );
+                new SurefireDependencyResolver( repositorySystem, log, null, null, null, null, null );
 
         when( log.isDebugEnabled() )
                 .thenReturn( true );
@@ -349,7 +349,7 @@ public class SurefireDependencyResolverTest
                 } );
 
         SurefireDependencyResolver surefireDependencyResolver =
-                new SurefireDependencyResolver( repositorySystem, null, null, null, null );
+                new SurefireDependencyResolver( repositorySystem, null, null, null, null, null, null );
 
         Map<String, Artifact> pluginArtifactsMapping = new HashMap<>();
         pluginArtifactsMapping.put( plugin.getGroupId() + ":" + plugin.getArtifactId(), plugin );
diff --git a/maven-surefire-plugin/src/site/apt/examples/junit-platform.apt.vm b/maven-surefire-plugin/src/site/apt/examples/junit-platform.apt.vm
index 4258387..1a11987 100644
--- a/maven-surefire-plugin/src/site/apt/examples/junit-platform.apt.vm
+++ b/maven-surefire-plugin/src/site/apt/examples/junit-platform.apt.vm
@@ -40,7 +40,7 @@ Using JUnit 5 Platform
     <dependency>
         <groupId>org.junit.jupiter</groupId>
         <artifactId>junit-jupiter-engine</artifactId>
-        <version>5.3.2</version>
+        <version>5.4.0</version>
         <scope>test</scope>
     </dependency>
     [...]
@@ -63,7 +63,7 @@ Using JUnit 5 Platform
     <dependency>
         <groupId>org.junit.vintage</groupId>
         <artifactId>junit-vintage-engine</artifactId>
-        <version>5.3.2</version>
+        <version>5.4.0</version>
         <scope>test</scope>
     </dependency>
     [...]
@@ -74,6 +74,112 @@ Using JUnit 5 Platform
   see the {{{https://junit.org/junit5/}JUnit 5 web site}}
   and the {{{https://junit.org/junit5/docs/current/user-guide/}JUnit 5 User Guide}}.
 
+* Smart Resolution of Jupiter Engine and Vintage Engine for JUnit4 (since plugin version 3.0.0-M4)
+
+  JUnit5 API artifact and your test sources become isolated from engine.
+
+  Normally the developer does not want to access internal classes of JUnit5 engine (e.g. <<<5.4.0>>>). In this example
+  the POM has only Jupiter API dependency in test classpath.
+
++---+
+<dependencies>
+    [...]
+    <dependency>
+        <groupId>org.junit.jupiter</groupId>
+        <artifactId>junit-jupiter-api</artifactId>
+        <version>5.4.0</version>
+        <scope>test</scope>
+    </dependency>
+    [...]
+</dependencies>
+...
+<build>
+    <plugins>
+        [...]
+        <plugin>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>${project.artifactId}</artifactId>
+            <version>${project.version}</version>
+            [... configuration or goals and executions ...]
+        </plugin>
+        [...]
+    </plugins>
+</build>
+...
++---+
+
+  In the following example the engine artifact appears in plugin dependencies and the engine is resolved by the plugin
+  and downloaded from a remote repository for plugins. You may want to update the version of engine with fixed bugs in
+  <<<5.3.2>>> but the API version <<<5.3.0>>> stays intact!
+
++---+
+<dependencies>
+    [...]
+    <dependency>
+        <groupId>org.junit.jupiter</groupId>
+        <artifactId>junit-jupiter-api</artifactId>
+        <version>5.3.0</version>
+        <scope>test</scope>
+    </dependency>
+    [...]
+</dependencies>
+...
+<build>
+    <plugins>
+        [...]
+        <plugin>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>${project.artifactId}</artifactId>
+            <version>${project.version}</version>
+            <dependencies>
+                <dependency>
+                    <groupId>org.junit.jupiter</groupId>
+                    <artifactId>junit-jupiter-engine</artifactId>
+                    <version>5.3.2</version>
+                </dependency>
+            </dependencies>
+        </plugin>
+        [...]
+    </plugins>
+</build>
+...
++---+
+
+
+  Similar with JUnit4 in test dependencies of your project POM. The Vintage engine artifact is in plugin dependencies.
+
++---+
+<dependencies>
+    [...]
+    <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.12</version>
+        <scope>test</scope>
+    </dependency>
+    [...]
+</dependencies>
+...
+<build>
+    <plugins>
+        ...
+        <plugin>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>${project.artifactId}</artifactId>
+            <version>${project.version}</version>
+            <dependencies>
+                <dependency>
+                    <groupId>org.junit.vintage</groupId>
+                    <artifactId>junit-vintage-engine</artifactId>
+                    <version>5.4.0</version>
+                </dependency>
+            </dependencies>
+        </plugin>
+    </plugins>
+</build>
+...
++---+
+
 * Provider Selection
 
    If nothing is configured, Surefire detects which JUnit version to use by the following algorithm:
diff --git a/pom.xml b/pom.xml
index 5f841c4..ebba975 100644
--- a/pom.xml
+++ b/pom.xml
@@ -191,16 +191,53 @@
         <groupId>org.apache.maven</groupId>
         <artifactId>maven-toolchain</artifactId>
         <version>3.0-alpha-2</version>
+        <exclusions>
+          <exclusion>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-core</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-compat</artifactId>
+          </exclusion>
+        </exclusions>
       </dependency>
       <dependency>
         <groupId>org.apache.maven.shared</groupId>
         <artifactId>maven-common-artifact-filters</artifactId>
-        <version>3.0.1</version>
+        <version>3.1.0</version>
         <exclusions>
           <exclusion>
             <groupId>org.apache.maven.shared</groupId>
             <artifactId>maven-plugin-testing-harness</artifactId>
           </exclusion>
+          <exclusion>
+            <groupId>org.apache.maven.shared</groupId>
+            <artifactId>maven-shared-utils</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.maven.shared</groupId>
+        <artifactId>maven-artifact-transfer</artifactId>
+        <version>0.10.1</version>
+        <exclusions>
+          <exclusion>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-core</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-artifact</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-component-annotations</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-utils</artifactId>
+          </exclusion>
         </exclusions>
       </dependency>
       <dependency>
diff --git a/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnitPlatformEnginesIT.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnitPlatformEnginesIT.java
index 6147c2f..af8f366 100644
--- a/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnitPlatformEnginesIT.java
+++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/JUnitPlatformEnginesIT.java
@@ -59,13 +59,13 @@ public class JUnitPlatformEnginesIT
     @Parameters(name = "{0}")
     public static Iterable<Object[]> regexVersions()
     {
-        ArrayList<Object[]> args = new ArrayList<Object[]>();
+        ArrayList<Object[]> args = new ArrayList<>();
         args.add( new Object[] { "1.0.3", "5.0.3", "1.0.0", "1.0.0" } );
         args.add( new Object[] { "1.1.1", "5.1.1", "1.0.0", "1.0.0" } );
         args.add( new Object[] { "1.2.0", "5.2.0", "1.1.0", "1.0.0" } );
         args.add( new Object[] { "1.3.2", "5.3.2", "1.1.1", "1.0.0" } );
         args.add( new Object[] { "1.4.0-SNAPSHOT", "5.4.0-SNAPSHOT", "1.1.1", "1.0.0" } );
-        args.add( new Object[] { "1.4.0-RC1", "5.4.0-RC1", "1.1.1", "1.0.0" } );
+        args.add( new Object[] { "1.4.0-RC2", "5.4.0-RC2", "1.1.1", "1.0.0" } );
         return args;
     }
 
@@ -124,7 +124,7 @@ public class JUnitPlatformEnginesIT
                 regex( toRegex( "*surefire-api-*.jar*" ) ),
                 regex( toRegex( "*surefire-logger-api-*.jar*" ) ),
                 regex( toRegex( "*common-java5-*.jar*" ) ),
-                regex( toRegex( "*junit-platform-launcher-1.3.2.jar*" ) )
+                regex( toRegex( "*junit-platform-launcher-" + platform + ".jar*" ) )
         ) );
 
         lines = validator.loadLogLines( startsWith( "[DEBUG] boot(compact) classpath" ) );
@@ -148,7 +148,7 @@ public class JUnitPlatformEnginesIT
                 regex( toRegex( "*opentest4j-" + opentest + ".jar*" ) ),
                 regex( toRegex( "*junit-jupiter-api-" + jupiter + ".jar*" ) ),
                 regex( toRegex( "*surefire-junit-platform-*.jar*" ) ),
-                regex( toRegex(  "*junit-platform-launcher-1.3.2.jar*" ) )
+                regex( toRegex(  "*junit-platform-launcher-" + platform + ".jar*" ) )
         ) );
     }
 
diff --git a/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1585IT.java b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1585IT.java
new file mode 100644
index 0000000..12e175f
--- /dev/null
+++ b/surefire-its/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1585IT.java
@@ -0,0 +1,54 @@
+package org.apache.maven.surefire.its.jiras;
+
+/*
+ * 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.surefire.its.fixture.SurefireJUnit4IntegrationTestCase;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.apache.maven.surefire.its.fixture.HelperAssertions.assumeJavaVersion;
+
+public class Surefire1585IT
+        extends SurefireJUnit4IntegrationTestCase
+{
+    @Before
+    public void setUp()
+    {
+        assumeJavaVersion( 1.8d );
+    }
+
+    @Test
+    public void shouldRunWithJupiterApi()
+    {
+        unpack( "surefire-1585-jupiter-api" )
+                .debugLogging()
+                .executeTest()
+                .verifyErrorFree( 1 );
+    }
+
+    @Test
+    public void shouldRunWithVintage()
+    {
+        unpack( "surefire-1585-junit4-vintage" )
+                .debugLogging()
+                .executeTest()
+                .verifyErrorFree( 1 );
+    }
+}
diff --git a/surefire-its/src/test/resources/surefire-1585-junit4-vintage/pom.xml b/surefire-its/src/test/resources/surefire-1585-junit4-vintage/pom.xml
new file mode 100644
index 0000000..7bdf148
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-1585-junit4-vintage/pom.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.apache.maven.plugins.surefire</groupId>
+    <artifactId>surefire-1585-junit4-vintage-it</artifactId>
+    <version>1.0</version>
+
+    <properties>
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>1.8</maven.compiler.target>
+        <junit.vintage.version>5.4.0</junit.vintage.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.12</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>${surefire.version}</version>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.junit.vintage</groupId>
+                        <artifactId>junit-vintage-engine</artifactId>
+                        <version>${junit.vintage.version}</version>
+                    </dependency>
+                </dependencies>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ProviderInfo.java b/surefire-its/src/test/resources/surefire-1585-junit4-vintage/src/test/java/JUnit4Test.java
similarity index 64%
copy from maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ProviderInfo.java
copy to surefire-its/src/test/resources/surefire-1585-junit4-vintage/src/test/java/JUnit4Test.java
index cb63cc1..d0c1ff4 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ProviderInfo.java
+++ b/surefire-its/src/test/resources/surefire-1585-junit4-vintage/src/test/java/JUnit4Test.java
@@ -1,5 +1,3 @@
-package org.apache.maven.plugin.surefire;
-
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -19,24 +17,12 @@ package org.apache.maven.plugin.surefire;
  * under the License.
  */
 
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.plugin.MojoExecutionException;
-
-import javax.annotation.Nonnull;
-import java.util.Set;
+import org.junit.Test;
 
-/**
- * @author Kristian Rosenvold
- */
-public interface ProviderInfo
+public class JUnit4Test
 {
-    @Nonnull
-    String getProviderName();
-
-    boolean isApplicable();
-
-    @Nonnull
-    Set<Artifact> getProviderClasspath();
-
-    void addProviderProperties() throws MojoExecutionException;
+    @Test
+    public void test()
+    {
+    }
 }
diff --git a/surefire-its/src/test/resources/surefire-1585-jupiter-api/pom.xml b/surefire-its/src/test/resources/surefire-1585-jupiter-api/pom.xml
new file mode 100644
index 0000000..652ae49
--- /dev/null
+++ b/surefire-its/src/test/resources/surefire-1585-jupiter-api/pom.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.apache.maven.plugins.surefire</groupId>
+    <artifactId>surefire-1585-jupiter-api-it</artifactId>
+    <version>1.0</version>
+
+    <properties>
+        <maven.compiler.source>1.8</maven.compiler.source>
+        <maven.compiler.target>1.8</maven.compiler.target>
+        <junit.jupiter.version>5.4.0</junit.jupiter.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-api</artifactId>
+            <version>${junit.jupiter.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>${surefire.version}</version>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ProviderInfo.java b/surefire-its/src/test/resources/surefire-1585-jupiter-api/src/test/java/JupiterTest.java
similarity index 64%
copy from maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ProviderInfo.java
copy to surefire-its/src/test/resources/surefire-1585-jupiter-api/src/test/java/JupiterTest.java
index cb63cc1..398141c 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ProviderInfo.java
+++ b/surefire-its/src/test/resources/surefire-1585-jupiter-api/src/test/java/JupiterTest.java
@@ -1,5 +1,3 @@
-package org.apache.maven.plugin.surefire;
-
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -19,24 +17,16 @@ package org.apache.maven.plugin.surefire;
  * under the License.
  */
 
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.plugin.MojoExecutionException;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
-import javax.annotation.Nonnull;
-import java.util.Set;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
 
-/**
- * @author Kristian Rosenvold
- */
-public interface ProviderInfo
+class JupiterTest
 {
-    @Nonnull
-    String getProviderName();
-
-    boolean isApplicable();
-
-    @Nonnull
-    Set<Artifact> getProviderClasspath();
-
-    void addProviderProperties() throws MojoExecutionException;
+    @Test
+    void test( TestInfo info )
+    {
+        assertEquals( "test(TestInfo)", info.getDisplayName(), "display name mismatch" );
+    }
 }


[maven-surefire] 02/02: [SUREFIRE-1585] Align JUnit Platform version at runtime

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

tibordigana pushed a commit to branch SUREFIRE-1585-tibor2
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git

commit d1d2a20d1b737eeda182bce69a989ae3d2fb3df8
Author: tibordigana <ti...@apache.org>
AuthorDate: Thu Feb 28 07:23:42 2019 +0100

    [SUREFIRE-1585] Align JUnit Platform version at runtime
---
 maven-failsafe-plugin/pom.xml           | 8 ++++----
 surefire-api/pom.xml                    | 4 ++--
 surefire-providers/common-java5/pom.xml | 4 ++--
 surefire-report-parser/pom.xml          | 4 ++--
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/maven-failsafe-plugin/pom.xml b/maven-failsafe-plugin/pom.xml
index c947b54..ccf282d 100644
--- a/maven-failsafe-plugin/pom.xml
+++ b/maven-failsafe-plugin/pom.xml
@@ -208,16 +208,16 @@
                             </artifactSet>
                             <relocations>
                                 <relocation>
-                                    <pattern>org.apache.maven.shared</pattern>
-                                    <shadedPattern>org.apache.maven.surefire.shade.org.apache.maven.shared</shadedPattern>
+                                    <pattern>org.apache.maven.shared.utils</pattern>
+                                    <shadedPattern>org.apache.maven.surefire.shade.failsafe.org.apache.maven.shared.utils</shadedPattern>
                                 </relocation>
                                 <relocation>
                                     <pattern>org.apache.commons.io</pattern>
-                                    <shadedPattern>org.apache.maven.surefire.shade.org.apache.commons.io</shadedPattern>
+                                    <shadedPattern>org.apache.maven.surefire.shade.failsafe.org.apache.commons.io</shadedPattern>
                                 </relocation>
                                 <relocation>
                                     <pattern>org.apache.commons.lang3</pattern>
-                                    <shadedPattern>org.apache.maven.surefire.shade.org.apache.commons.lang3</shadedPattern>
+                                    <shadedPattern>org.apache.maven.surefire.shade.failsafe.org.apache.commons.lang3</shadedPattern>
                                 </relocation>
                             </relocations>
                         </configuration>
diff --git a/surefire-api/pom.xml b/surefire-api/pom.xml
index e751eae..eee3879 100644
--- a/surefire-api/pom.xml
+++ b/surefire-api/pom.xml
@@ -82,8 +82,8 @@
               </artifactSet>
               <relocations>
                 <relocation>
-                  <pattern>org.apache.maven.shared</pattern>
-                  <shadedPattern>org.apache.maven.surefire.shade.api.org.apache.maven.shared</shadedPattern>
+                  <pattern>org.apache.maven.shared.utils</pattern>
+                  <shadedPattern>org.apache.maven.surefire.shade.api.org.apache.maven.shared.utils</shadedPattern>
                 </relocation>
               </relocations>
             </configuration>
diff --git a/surefire-providers/common-java5/pom.xml b/surefire-providers/common-java5/pom.xml
index 361e1d6..ba44a98 100644
--- a/surefire-providers/common-java5/pom.xml
+++ b/surefire-providers/common-java5/pom.xml
@@ -57,8 +57,8 @@
               </artifactSet>
               <relocations>
                 <relocation>
-                  <pattern>org.apache.maven.shared</pattern>
-                  <shadedPattern>org.apache.maven.surefire.shade.java5.org.apache.maven.shared</shadedPattern>
+                  <pattern>org.apache.maven.shared.utils</pattern>
+                  <shadedPattern>org.apache.maven.surefire.shade.java5.org.apache.maven.shared.utils</shadedPattern>
                 </relocation>
               </relocations>
             </configuration>
diff --git a/surefire-report-parser/pom.xml b/surefire-report-parser/pom.xml
index a700523..8c3f767 100644
--- a/surefire-report-parser/pom.xml
+++ b/surefire-report-parser/pom.xml
@@ -85,8 +85,8 @@
               </artifactSet>
               <relocations>
                 <relocation>
-                  <pattern>org.apache.maven.shared</pattern>
-                  <shadedPattern>org.apache.maven.surefire.shade.report.org.apache.maven.shared</shadedPattern>
+                  <pattern>org.apache.maven.shared.utils</pattern>
+                  <shadedPattern>org.apache.maven.surefire.shade.report.org.apache.maven.shared.utils</shadedPattern>
                 </relocation>
               </relocations>
             </configuration>