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 2021/04/06 13:11:15 UTC

[maven-surefire] branch SUREFIRE-1860 created (now 69b5773)

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

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


      at 69b5773  [SUREFIRE-1860] extend ReportEntry interface and SimpleReportEntry with mandatory properties runMode:String, id:long, forkId:int

This branch includes the following new commits:

     new 69b5773  [SUREFIRE-1860] extend ReportEntry interface and SimpleReportEntry with mandatory properties runMode:String, id:long, forkId:int

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


[maven-surefire] 01/01: [SUREFIRE-1860] extend ReportEntry interface and SimpleReportEntry with mandatory properties runMode:String, id:long, forkId:int

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

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

commit 69b577394c5d1ec35e18e6170d16706cf9a7d385
Author: tibordigana <ti...@gmail.com>
AuthorDate: Tue Apr 6 15:11:02 2021 +0200

    [SUREFIRE-1860] extend ReportEntry interface and SimpleReportEntry with mandatory properties runMode:String, id:long, forkId:int
---
 .../maven/plugin/surefire/CommonReflector.java     |   4 +-
 .../plugin/surefire/InPluginVMSurefireStarter.java |   2 +-
 .../plugin/surefire/booterclient/ForkStarter.java  |   2 +-
 .../surefire/booterclient/output/ForkClient.java   |  13 +--
 .../surefire/report/DefaultReporterFactory.java    |  16 ++-
 .../plugin/surefire/report/TestSetRunListener.java |   7 +-
 .../plugin/surefire/report/WrappedReportEntry.java |  19 ++++
 .../apache/maven/surefire/stream/EventDecoder.java |  27 ++---
 .../maven/plugin/surefire/CommonReflectorTest.java |   4 +-
 .../booterclient/ForkingRunListenerTest.java       |  24 +++--
 .../plugin/surefire/booterclient/MockReporter.java |  11 +-
 .../booterclient/TestSetMockReporterFactory.java   |   3 +-
 .../booterclient/output/ForkClientTest.java        |  86 ++++++++--------
 .../report/DefaultReporterFactoryTest.java         |   4 +-
 .../surefire/report/StatelessXmlReporterTest.java  |  48 ++++-----
 .../surefire/report/WrappedReportEntryTest.java    |  17 ++--
 .../runorder/RunEntryStatisticsMapTest.java        |  33 +++---
 .../surefire/api/booter/BaseProviderFactory.java   |  17 ----
 .../api/booter/ForkingReporterFactory.java         |  29 ++++--
 .../surefire/api/booter/ForkingRunListener.java    |  13 ++-
 .../surefire/api/provider/ProviderParameters.java  |  11 --
 ...nsoleReporter.java => AbstractRunListener.java} |  18 ++--
 .../api/report/CategorizedReportEntry.java         |  34 ++++---
 .../maven/surefire/api/report/ReportEntry.java     |  21 ++++
 .../maven/surefire/api/report/ReporterFactory.java |  22 +++-
 .../surefire/api/report/RunListenerContext.java    |  67 ++++++++++++
 .../surefire/api/report/SimpleReportEntry.java     | 113 +++++++++++++++------
 .../api/booter/ForkingRunListenerTest.java         |   5 +-
 .../apache/maven/surefire/booter/ForkedBooter.java |  10 +-
 .../surefire/booter/SurefireReflectorTest.java     |  46 ++++++++-
 .../surefire/common/junit4/JUnit4RunListener.java  |  50 +++++++--
 .../maven/surefire/common/junit4/MockReporter.java |   6 +-
 .../junitplatform/JUnitPlatformProvider.java       |   2 +-
 .../junitplatform/JUnitPlatformProviderTest.java   |   4 +-
 .../maven/surefire/junit/JUnit3Provider.java       |   2 +-
 .../junit/TestListenerInvocationHandler.java       |   8 +-
 .../maven/surefire/junit4/JUnit4Provider.java      |   3 +-
 .../junitcore/ClassesParallelRunListener.java      |   7 +-
 .../surefire/junitcore/ConcurrentRunListener.java  |  29 ++++--
 .../surefire/junitcore/JUnitCoreProvider.java      |  37 ++++---
 .../surefire/junitcore/JUnitCoreRunListener.java   |   6 +-
 .../junitcore/MethodsParallelRunListener.java      |   7 +-
 .../junitcore/NonConcurrentRunListener.java        |  15 +--
 .../junitcore/ConcurrentRunListenerTest.java       |  16 +--
 .../junitcore}/DefaultDirectConsoleReporter.java   |   4 +-
 .../maven/surefire/junitcore/JUnitCoreTester.java  |   9 +-
 .../maven/surefire/junitcore/MockReporter.java     |   7 +-
 .../maven/surefire/junitcore/Surefire746Test.java  |  10 +-
 .../junitcore/pc/ParallelComputerBuilderTest.java  |   2 +-
 .../junitcore/pc/ParallelComputerUtilTest.java     |   2 +-
 .../junitcore/pc/SchedulingStrategiesTest.java     |   2 +-
 .../maven/surefire/testng/TestNGProvider.java      |   2 +-
 52 files changed, 642 insertions(+), 314 deletions(-)

diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/CommonReflector.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/CommonReflector.java
index 989a524..6543ef5 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/CommonReflector.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/CommonReflector.java
@@ -66,8 +66,8 @@ public class CommonReflector
         }
     }
 
-    public Object createReportingReporterFactory( @Nonnull StartupReportConfiguration startupReportConfiguration,
-                                                  @Nonnull ConsoleLogger consoleLogger )
+    public Object createReporterFactory( @Nonnull StartupReportConfiguration startupReportConfiguration,
+                                         @Nonnull ConsoleLogger consoleLogger )
     {
         Class<?>[] args = { this.startupReportConfiguration, this.consoleLogger };
         Object src = createStartupReportConfiguration( startupReportConfiguration );
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/InPluginVMSurefireStarter.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/InPluginVMSurefireStarter.java
index 2e54e0d..ac34b33 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/InPluginVMSurefireStarter.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/InPluginVMSurefireStarter.java
@@ -80,7 +80,7 @@ public class InPluginVMSurefireStarter
 
         CommonReflector surefireReflector = new CommonReflector( testClassLoader );
 
-        Object factory = surefireReflector.createReportingReporterFactory( startupReportConfig, consoleLogger );
+        Object factory = surefireReflector.createReporterFactory( startupReportConfig, consoleLogger );
 
         try
         {
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java
index 200d2a8..21edc03 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java
@@ -770,7 +770,7 @@ public class ForkStarter
             ClassLoader unifiedClassLoader = classpathConfiguration.createMergedClassLoader();
 
             CommonReflector commonReflector = new CommonReflector( unifiedClassLoader );
-            Object reporterFactory = commonReflector.createReportingReporterFactory( startupReportConfiguration, log );
+            Object reporterFactory = commonReflector.createReporterFactory( startupReportConfiguration, log );
 
             ProviderFactory providerFactory =
                 new ProviderFactory( startupConfiguration, providerConfiguration, unifiedClassLoader, reporterFactory );
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClient.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClient.java
index a1e54b1..76862b0 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClient.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClient.java
@@ -132,10 +132,11 @@ public class ForkClient
         public void handle( RunMode runMode, TestSetReportEntry reportEntry )
         {
             testsInProgress.clear();
-            TestSetReportEntry entry = reportEntry( reportEntry.getSourceName(), reportEntry.getSourceText(),
-                    reportEntry.getName(), reportEntry.getNameText(),
-                    reportEntry.getGroup(), reportEntry.getStackTraceWriter(), reportEntry.getElapsed(),
-                    reportEntry.getMessage(), getTestVmSystemProperties() );
+            TestSetReportEntry entry = reportEntry( reportEntry.getRunMode(),
+                reportEntry.getTestRunId(), reportEntry.getSourceName(), reportEntry.getSourceText(),
+                reportEntry.getName(), reportEntry.getNameText(),
+                reportEntry.getGroup(), reportEntry.getStackTraceWriter(), reportEntry.getElapsed(),
+                reportEntry.getMessage(), getTestVmSystemProperties() );
             getTestSetReporter().testSetCompleted( entry );
         }
     }
@@ -340,7 +341,7 @@ public class ForkClient
     {
         if ( forkedProcessTimeoutInSeconds > 0 )
         {
-            final long forkedProcessTimeoutInMillis = 1000 * forkedProcessTimeoutInSeconds;
+            final long forkedProcessTimeoutInMillis = 1000L * forkedProcessTimeoutInSeconds;
             final long startedAt = testSetStartedAt.get();
             if ( startedAt > START_TIME_ZERO && currentTimeMillis - startedAt >= forkedProcessTimeoutInMillis )
             {
@@ -380,7 +381,7 @@ public class ForkClient
     {
         if ( testSetReporter == null )
         {
-            testSetReporter = defaultReporterFactory.createReporter();
+            testSetReporter = defaultReporterFactory.getRunListener();
         }
         return testSetReporter;
     }
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/DefaultReporterFactory.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/DefaultReporterFactory.java
index 7b0c18d..34aa915 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/DefaultReporterFactory.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/DefaultReporterFactory.java
@@ -23,6 +23,8 @@ import org.apache.maven.plugin.surefire.StartupReportConfiguration;
 import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
 import org.apache.maven.plugin.surefire.log.api.Level;
 import org.apache.maven.plugin.surefire.runorder.StatisticsReporter;
+import org.apache.maven.surefire.api.report.AbstractRunListener;
+import org.apache.maven.surefire.api.report.ConsoleStream;
 import org.apache.maven.surefire.shared.utils.logging.MessageBuilder;
 import org.apache.maven.surefire.extensions.ConsoleOutputReportEventListener;
 import org.apache.maven.surefire.extensions.StatelessReportEventListener;
@@ -97,7 +99,7 @@ public class DefaultReporterFactory
     }
 
     @Override
-    public RunListener createReporter()
+    public AbstractRunListener getRunListener()
     {
         TestSetRunListener testSetRunListener =
             new TestSetRunListener( createConsoleReporter(),
@@ -112,6 +114,18 @@ public class DefaultReporterFactory
         return testSetRunListener;
     }
 
+    @Override
+    public ConsoleLogger getConsoleLogger()
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public ConsoleStream getConsoleStream()
+    {
+        throw new UnsupportedOperationException();
+    }
+
     public File getReportsDirectory()
     {
         return reportConfiguration.getReportsDirectory();
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/TestSetRunListener.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/TestSetRunListener.java
index 15b7ed8..eb80632 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/TestSetRunListener.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/TestSetRunListener.java
@@ -27,6 +27,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
 
 import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
 import org.apache.maven.plugin.surefire.runorder.StatisticsReporter;
+import org.apache.maven.surefire.api.report.AbstractRunListener;
 import org.apache.maven.surefire.extensions.ConsoleOutputReportEventListener;
 import org.apache.maven.surefire.extensions.StatelessReportEventListener;
 import org.apache.maven.surefire.extensions.StatelessTestsetInfoConsoleReportEventListener;
@@ -51,7 +52,8 @@ import static java.util.Objects.requireNonNull;
  * @author Kristian Rosenvold
  */
 public class TestSetRunListener
-    implements RunListener, ConsoleOutputReceiver, ConsoleLogger
+    extends AbstractRunListener
+    implements ConsoleOutputReceiver, ConsoleLogger
 {
     private final Queue<TestMethodStats> testMethodStats = new ConcurrentLinkedQueue<>();
 
@@ -77,7 +79,7 @@ public class TestSetRunListener
 
     @SuppressWarnings( "checkstyle:parameternumber" )
     public TestSetRunListener( StatelessTestsetInfoConsoleReportEventListener<WrappedReportEntry, TestSetStats>
-                                           consoleReporter,
+                                       consoleReporter,
                                StatelessTestsetInfoFileReportEventListener<WrappedReportEntry, TestSetStats>
                                        fileReporter,
                                StatelessReportEventListener<WrappedReportEntry, TestSetStats> simpleXMLReporter,
@@ -85,6 +87,7 @@ public class TestSetRunListener
                                StatisticsReporter statisticsReporter, boolean trimStackTrace,
                                boolean isPlainFormat, boolean briefOrPlainFormat )
     {
+        super(  );
         this.consoleReporter = consoleReporter;
         this.fileReporter = fileReporter;
         this.statisticsReporter = statisticsReporter;
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/WrappedReportEntry.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/WrappedReportEntry.java
index 75b1f66..7339e04 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/WrappedReportEntry.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/WrappedReportEntry.java
@@ -20,9 +20,13 @@ package org.apache.maven.plugin.surefire.report;
  */
 
 import org.apache.maven.surefire.api.report.ReportEntry;
+import org.apache.maven.surefire.api.report.RunMode;
 import org.apache.maven.surefire.api.report.StackTraceWriter;
 import org.apache.maven.surefire.api.report.TestSetReportEntry;
 
+import javax.annotation.Nonnegative;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import java.util.Collections;
 import java.util.Map;
 
@@ -225,6 +229,21 @@ public class WrappedReportEntry
     }
 
     @Override
+    @Nonnull
+    public RunMode getRunMode()
+    {
+        return original.getRunMode();
+    }
+
+    @Override
+    @Nonnegative
+    @Nullable
+    public Long getTestRunId()
+    {
+        return original.getTestRunId();
+    }
+
+    @Override
     public Map<String, String> getSystemProperties()
     {
         return systemProperties;
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/surefire/stream/EventDecoder.java b/maven-surefire-common/src/main/java/org/apache/maven/surefire/stream/EventDecoder.java
index 02d8b7b..aff893b 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/surefire/stream/EventDecoder.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/surefire/stream/EventDecoder.java
@@ -312,35 +312,35 @@ public class EventDecoder extends AbstractStreamDecoder<Event, ForkedProcessEven
                 return new SystemPropertyEvent( runMode, key, value );
             case BOOTERCODE_TESTSET_STARTING:
                 checkArguments( runMode, memento, 10 );
-                return new TestsetStartingEvent( runMode, toReportEntry( memento.getData() ) );
+                return new TestsetStartingEvent( runMode, toReportEntry( runMode, , memento.getData() ) );
             case BOOTERCODE_TESTSET_COMPLETED:
                 checkArguments( runMode, memento, 10 );
-                return new TestsetCompletedEvent( runMode, toReportEntry( memento.getData() ) );
+                return new TestsetCompletedEvent( runMode, toReportEntry( runMode, , memento.getData() ) );
             case BOOTERCODE_TEST_STARTING:
                 checkArguments( runMode, memento, 10 );
-                return new TestStartingEvent( runMode, toReportEntry( memento.getData() ) );
+                return new TestStartingEvent( runMode, toReportEntry( runMode, , memento.getData() ) );
             case BOOTERCODE_TEST_SUCCEEDED:
                 checkArguments( runMode, memento, 10 );
-                return new TestSucceededEvent( runMode, toReportEntry( memento.getData() ) );
+                return new TestSucceededEvent( runMode, toReportEntry( runMode, , memento.getData() ) );
             case BOOTERCODE_TEST_FAILED:
                 checkArguments( runMode, memento, 10 );
-                return new TestFailedEvent( runMode, toReportEntry( memento.getData() ) );
+                return new TestFailedEvent( runMode, toReportEntry( runMode, , memento.getData() ) );
             case BOOTERCODE_TEST_SKIPPED:
                 checkArguments( runMode, memento, 10 );
-                return new TestSkippedEvent( runMode, toReportEntry( memento.getData() ) );
+                return new TestSkippedEvent( runMode, toReportEntry( runMode, , memento.getData() ) );
             case BOOTERCODE_TEST_ERROR:
                 checkArguments( runMode, memento, 10 );
-                return new TestErrorEvent( runMode, toReportEntry( memento.getData() ) );
+                return new TestErrorEvent( runMode, toReportEntry( runMode, , memento.getData() ) );
             case BOOTERCODE_TEST_ASSUMPTIONFAILURE:
                 checkArguments( runMode, memento, 10 );
-                return new TestAssumptionFailureEvent( runMode, toReportEntry( memento.getData() ) );
+                return new TestAssumptionFailureEvent( runMode, toReportEntry( runMode, , memento.getData() ) );
             default:
                 throw new IllegalArgumentException( "Missing a branch for the event type " + eventType );
         }
     }
 
     @Nonnull
-    private static TestSetReportEntry toReportEntry( List<Object> args )
+    private static TestSetReportEntry toReportEntry( RunMode runMode, Long testId, List<Object> args )
     {
         // ReportEntry:
         String source = (String) args.get( 0 );
@@ -354,7 +354,7 @@ public class EventDecoder extends AbstractStreamDecoder<Event, ForkedProcessEven
         String traceMessage = (String) args.get( 7 );
         String smartTrimmedStackTrace = (String) args.get( 8 );
         String stackTrace = (String) args.get( 9 );
-        return newReportEntry( source, sourceText, name, nameText, group, message, timeElapsed,
+        return newReportEntry( runMode, testId, source, sourceText, name, nameText, group, message, timeElapsed,
             traceMessage, smartTrimmedStackTrace, stackTrace );
     }
 
@@ -372,7 +372,8 @@ public class EventDecoder extends AbstractStreamDecoder<Event, ForkedProcessEven
         return exists ? new DeserializedStacktraceWriter( traceMessage, smartTrimmedStackTrace, stackTrace ) : null;
     }
 
-    static TestSetReportEntry newReportEntry( // ReportEntry:
+    static TestSetReportEntry newReportEntry( RunMode runMode, Long testId,
+                                              // ReportEntry:
                                               String source, String sourceText, String name,
                                               String nameText, String group, String message,
                                               Integer timeElapsed,
@@ -382,8 +383,8 @@ public class EventDecoder extends AbstractStreamDecoder<Event, ForkedProcessEven
         throws NumberFormatException
     {
         StackTraceWriter stackTraceWriter = toTrace( traceMessage, smartTrimmedStackTrace, stackTrace );
-        return reportEntry( source, sourceText, name, nameText, group, stackTraceWriter, timeElapsed, message,
-            Collections.<String, String>emptyMap() );
+        return reportEntry( runMode, testId, source, sourceText, name, nameText, group, stackTraceWriter,
+            timeElapsed, message, Collections.<String, String>emptyMap() );
     }
 
     private static Map<Segment, ForkedProcessEventType> segmentsToEvents()
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/CommonReflectorTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/CommonReflectorTest.java
index b1f3f79..efc7e7f 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/CommonReflectorTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/CommonReflectorTest.java
@@ -59,7 +59,7 @@ public class CommonReflectorTest
     private File reportsDirectory;
     private File statistics;
     private SurefireStatelessReporter xmlReporter;
-    private SurefireConsoleOutputReporter consoleOutputReporter = new SurefireConsoleOutputReporter();
+    private final SurefireConsoleOutputReporter consoleOutputReporter = new SurefireConsoleOutputReporter();
     private SurefireStatelessTestsetInfoReporter infoReporter = new SurefireStatelessTestsetInfoReporter();
 
     @Before
@@ -82,7 +82,7 @@ public class CommonReflectorTest
     public void createReportingReporterFactory()
     {
         CommonReflector reflector = new CommonReflector( Thread.currentThread().getContextClassLoader() );
-        DefaultReporterFactory factory = (DefaultReporterFactory) reflector.createReportingReporterFactory(
+        DefaultReporterFactory factory = (DefaultReporterFactory) reflector.createReporterFactory(
                 startupReportConfiguration, consoleLogger );
 
         assertThat( factory )
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkingRunListenerTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkingRunListenerTest.java
index 48eb35f..9a8a720 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkingRunListenerTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkingRunListenerTest.java
@@ -25,6 +25,7 @@ import org.apache.maven.plugin.surefire.booterclient.output.ForkClient;
 import org.apache.maven.plugin.surefire.extensions.EventConsumerThread;
 import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
 import org.apache.maven.surefire.api.booter.ForkingRunListener;
+import org.apache.maven.surefire.api.report.RunListenerContext;
 import org.apache.maven.surefire.booter.spi.EventChannelEncoder;
 import org.apache.maven.surefire.api.event.Event;
 import org.apache.maven.surefire.extensions.EventHandler;
@@ -57,6 +58,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
+import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
 import static org.apache.maven.surefire.api.util.internal.Channels.newBufferedChannel;
 import static org.apache.maven.surefire.api.util.internal.Channels.newChannel;
 import static org.fest.assertions.Assertions.assertThat;
@@ -257,12 +259,12 @@ public class ForkingRunListenerTest
         reset();
         ReportEntry expected = createDefaultReportEntry();
         SimpleReportEntry secondExpected = createAnotherDefaultReportEntry();
+        RunListenerContext ctx = new RunListenerContext( NORMAL_RUN );
 
-        new ForkingRunListener( new EventChannelEncoder( newBufferedChannel( printStream ) ), false )
+        new ForkingRunListener( ctx, new EventChannelEncoder( newBufferedChannel( printStream ) ), false )
                 .testStarting( expected );
 
-        new ForkingRunListener(
-            new EventChannelEncoder( newBufferedChannel( anotherPrintStream ) ), false )
+        new ForkingRunListener( ctx, new EventChannelEncoder( newBufferedChannel( anotherPrintStream ) ), false )
                 .testSkipped( secondExpected );
 
         TestSetMockReporterFactory providerReporterFactory = new TestSetMockReporterFactory();
@@ -414,7 +416,8 @@ public class ForkingRunListenerTest
 
     private SimpleReportEntry createDefaultReportEntry( Map<String, String> sysProps )
     {
-        return new SimpleReportEntry( "com.abc.TestClass", null, "testMethod", null, null, 22, sysProps );
+        return new SimpleReportEntry( NORMAL_RUN, 1L,
+            "com.abc.TestClass", null, "testMethod", null, null, 22, sysProps );
     }
 
     private SimpleReportEntry createDefaultReportEntry()
@@ -424,7 +427,8 @@ public class ForkingRunListenerTest
 
     private SimpleReportEntry createAnotherDefaultReportEntry()
     {
-        return new SimpleReportEntry( "com.abc.AnotherTestClass", null, "testAnotherMethod", null, 42 );
+        return new SimpleReportEntry( NORMAL_RUN, 0L,
+            "com.abc.AnotherTestClass", null, "testAnotherMethod", null, 42 );
     }
 
     private SimpleReportEntry createReportEntryWithStackTrace()
@@ -437,7 +441,8 @@ public class ForkingRunListenerTest
         {
             StackTraceWriter stackTraceWriter =
                 new LegacyPojoStackTraceWriter( "org.apache.tests.TestClass", "testMethod11", e );
-            return new CategorizedReportEntry( "com.abc.TestClass", "testMethod", "aGroup", stackTraceWriter, 77 );
+            return new CategorizedReportEntry( NORMAL_RUN, 0,
+                "com.abc.TestClass", "testMethod", "aGroup", stackTraceWriter, 77 );
         }
     }
 
@@ -451,14 +456,16 @@ public class ForkingRunListenerTest
         {
             StackTraceWriter stackTraceWriter =
                 new LegacyPojoStackTraceWriter( "org.apache.tests.TestClass", "testMethod11", e );
-            return new CategorizedReportEntry( "com.abc.TestClass", "testMethod", "aGroup", stackTraceWriter, 77 );
+            return new CategorizedReportEntry( NORMAL_RUN, 0,
+                "com.abc.TestClass", "testMethod", "aGroup", stackTraceWriter, 77 );
         }
     }
 
     private RunListener createForkingRunListener()
     {
         WritableBufferedByteChannel channel = (WritableBufferedByteChannel) newChannel( printStream );
-        return new ForkingRunListener( new EventChannelEncoder( channel ), false );
+        RunListenerContext ctx = new RunListenerContext( NORMAL_RUN );
+        return new ForkingRunListener( ctx, new EventChannelEncoder( channel ), false );
     }
 
     private class StandardTestRun
@@ -500,7 +507,6 @@ public class ForkingRunListenerTest
             final ReportEntry firstData = getFirstData();
             assertEquals( expected.getSourceName(), firstData.getSourceName() );
             assertEquals( expected.getName(), firstData.getName() );
-            //noinspection deprecation
             assertEquals( expected.getElapsed(), firstData.getElapsed() );
             assertEquals( expected.getGroup(), firstData.getGroup() );
             if ( expected.getStackTraceWriter() != null )
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/MockReporter.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/MockReporter.java
index aab5731..55b5e14 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/MockReporter.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/MockReporter.java
@@ -20,9 +20,10 @@ package org.apache.maven.plugin.surefire.booterclient;
  */
 
 import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
+import org.apache.maven.surefire.api.report.AbstractRunListener;
 import org.apache.maven.surefire.api.report.ConsoleOutputReceiver;
 import org.apache.maven.surefire.api.report.ReportEntry;
-import org.apache.maven.surefire.api.report.RunListener;
+import org.apache.maven.surefire.api.report.RunListenerContext;
 import org.apache.maven.surefire.api.report.TestSetReportEntry;
 import org.apache.maven.surefire.api.report.RunMode;
 
@@ -34,7 +35,8 @@ import java.util.concurrent.atomic.AtomicInteger;
  * Internal tests use only.
  */
 public class MockReporter
-    implements RunListener, ConsoleLogger, ConsoleOutputReceiver
+    extends AbstractRunListener
+    implements ConsoleLogger, ConsoleOutputReceiver
 {
     private final List<String> events = new ArrayList<>();
 
@@ -74,6 +76,11 @@ public class MockReporter
 
     private final AtomicInteger testFailed = new AtomicInteger();
 
+    public MockReporter()
+    {
+        super( new RunListenerContext( RunMode.NORMAL_RUN ) );
+    }
+
     @Override
     public void testSetStarting( TestSetReportEntry report )
     {
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/TestSetMockReporterFactory.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/TestSetMockReporterFactory.java
index ace0e5d..38d3a1c 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/TestSetMockReporterFactory.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/TestSetMockReporterFactory.java
@@ -25,6 +25,7 @@ import org.apache.maven.plugin.surefire.extensions.SurefireStatelessReporter;
 import org.apache.maven.plugin.surefire.extensions.SurefireStatelessTestsetInfoReporter;
 import org.apache.maven.plugin.surefire.report.DefaultReporterFactory;
 import org.apache.maven.plugin.surefire.log.api.NullConsoleLogger;
+import org.apache.maven.surefire.api.report.AbstractRunListener;
 import org.apache.maven.surefire.api.report.RunListener;
 
 import java.io.File;
@@ -43,7 +44,7 @@ public class TestSetMockReporterFactory
     }
 
     @Override
-    public RunListener createReporter()
+    public AbstractRunListener getRunListener()
     {
         return new MockReporter();
     }
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClientTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClientTest.java
index a0b29cd..a97dbfc 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClientTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/output/ForkClientTest.java
@@ -478,14 +478,14 @@ public class ForkClientTest
         when( factory.getReportsDirectory() )
                 .thenReturn( new File( target, "surefire-reports" ) );
         MockReporter receiver = new MockReporter();
-        when( factory.createReporter() )
+        when( factory.getRunListener() )
                 .thenReturn( receiver );
         NotifiableTestStream notifiableTestStream = mock( NotifiableTestStream.class );
         ForkClient client = new ForkClient( factory, notifiableTestStream, 0 );
         client.handleEvent( new StandardStreamOutEvent( NORMAL_RUN, "msg" ) );
         verifyZeroInteractions( notifiableTestStream );
         verify( factory, times( 1 ) )
-                .createReporter();
+                .getRunListener();
         verifyNoMoreInteractions( factory );
         assertThat( client.getReporter() )
                 .isNotNull();
@@ -520,14 +520,14 @@ public class ForkClientTest
         when( factory.getReportsDirectory() )
                 .thenReturn( new File( target, "surefire-reports" ) );
         MockReporter receiver = new MockReporter();
-        when( factory.createReporter() )
+        when( factory.getRunListener() )
                 .thenReturn( receiver );
         NotifiableTestStream notifiableTestStream = mock( NotifiableTestStream.class );
         ForkClient client = new ForkClient( factory, notifiableTestStream, 0 );
         client.handleEvent( new StandardStreamOutWithNewLineEvent( NORMAL_RUN, "msg" ) );
         verifyZeroInteractions( notifiableTestStream );
         verify( factory, times( 1 ) )
-                .createReporter();
+                .getRunListener();
         verifyNoMoreInteractions( factory );
         assertThat( client.getReporter() )
                 .isNotNull();
@@ -562,14 +562,14 @@ public class ForkClientTest
         when( factory.getReportsDirectory() )
                 .thenReturn( new File( target, "surefire-reports" ) );
         MockReporter receiver = new MockReporter();
-        when( factory.createReporter() )
+        when( factory.getRunListener() )
                 .thenReturn( receiver );
         NotifiableTestStream notifiableTestStream = mock( NotifiableTestStream.class );
         ForkClient client = new ForkClient( factory, notifiableTestStream, 0 );
         client.handleEvent( new StandardStreamErrEvent( NORMAL_RUN, "msg" ) );
         verifyZeroInteractions( notifiableTestStream );
         verify( factory, times( 1 ) )
-                .createReporter();
+                .getRunListener();
         verifyNoMoreInteractions( factory );
         assertThat( client.getReporter() )
                 .isNotNull();
@@ -604,14 +604,14 @@ public class ForkClientTest
         when( factory.getReportsDirectory() )
                 .thenReturn( new File( target, "surefire-reports" ) );
         MockReporter receiver = new MockReporter();
-        when( factory.createReporter() )
+        when( factory.getRunListener() )
                 .thenReturn( receiver );
         NotifiableTestStream notifiableTestStream = mock( NotifiableTestStream.class );
         ForkClient client = new ForkClient( factory, notifiableTestStream, 0 );
         client.handleEvent( new StandardStreamErrWithNewLineEvent( NORMAL_RUN, "msg" ) );
         verifyZeroInteractions( notifiableTestStream );
         verify( factory, times( 1 ) )
-                .createReporter();
+                .getRunListener();
         verifyNoMoreInteractions( factory );
         assertThat( client.getReporter() )
                 .isNotNull();
@@ -642,7 +642,7 @@ public class ForkClientTest
     {
         DefaultReporterFactory factory = mock( DefaultReporterFactory.class );
         MockReporter receiver = new MockReporter();
-        when( factory.createReporter() )
+        when( factory.getRunListener() )
                 .thenReturn( receiver );
         NotifiableTestStream notifiableTestStream = mock( NotifiableTestStream.class );
         ForkClient client = new ForkClient( factory, notifiableTestStream, 0 );
@@ -652,7 +652,7 @@ public class ForkClientTest
         client.handleEvent( event );
         verifyZeroInteractions( notifiableTestStream );
         verify( factory, times( 1 ) )
-                .createReporter();
+                .getRunListener();
         verify( factory, times( 1 ) )
             .getReportsDirectory();
         verifyNoMoreInteractions( factory );
@@ -734,14 +734,14 @@ public class ForkClientTest
         when( factory.getReportsDirectory() )
                 .thenReturn( new File( target, "surefire-reports" ) );
         MockReporter receiver = new MockReporter();
-        when( factory.createReporter() )
+        when( factory.getRunListener() )
                 .thenReturn( receiver );
         NotifiableTestStream notifiableTestStream = mock( NotifiableTestStream.class );
         ForkClient client = new ForkClient( factory, notifiableTestStream, 0 );
         client.handleEvent( new ConsoleWarningEvent( "s1" ) );
         verifyZeroInteractions( notifiableTestStream );
         verify( factory, times( 1 ) )
-                .createReporter();
+                .getRunListener();
         verifyNoMoreInteractions( factory );
         assertThat( client.getReporter() )
                 .isNotNull();
@@ -776,14 +776,14 @@ public class ForkClientTest
         when( factory.getReportsDirectory() )
                 .thenReturn( new File( target, "surefire-reports" ) );
         MockReporter receiver = new MockReporter();
-        when( factory.createReporter() )
+        when( factory.getRunListener() )
                 .thenReturn( receiver );
         NotifiableTestStream notifiableTestStream = mock( NotifiableTestStream.class );
         ForkClient client = new ForkClient( factory, notifiableTestStream, 0 );
         client.handleEvent( new ConsoleDebugEvent( "s1" ) );
         verifyZeroInteractions( notifiableTestStream );
         verify( factory, times( 1 ) )
-                .createReporter();
+                .getRunListener();
         verifyNoMoreInteractions( factory );
         assertThat( client.getReporter() )
                 .isNotNull();
@@ -818,14 +818,14 @@ public class ForkClientTest
         when( factory.getReportsDirectory() )
                 .thenReturn( new File( target, "surefire-reports" ) );
         MockReporter receiver = new MockReporter();
-        when( factory.createReporter() )
+        when( factory.getRunListener() )
                 .thenReturn( receiver );
         NotifiableTestStream notifiableTestStream = mock( NotifiableTestStream.class );
         ForkClient client = new ForkClient( factory, notifiableTestStream, 0 );
         client.handleEvent( new ConsoleInfoEvent( "s1" ) );
         verifyZeroInteractions( notifiableTestStream );
         verify( factory, times( 1 ) )
-                .createReporter();
+                .getRunListener();
         verifyNoMoreInteractions( factory );
         assertThat( client.getReporter() )
                 .isNotNull();
@@ -860,7 +860,7 @@ public class ForkClientTest
         when( factory.getReportsDirectory() )
                 .thenReturn( new File( target, "surefire-reports" ) );
         MockReporter receiver = new MockReporter();
-        when( factory.createReporter() )
+        when( factory.getRunListener() )
                 .thenReturn( receiver );
         NotifiableTestStream notifiableTestStream = mock( NotifiableTestStream.class );
         ForkClient client = new ForkClient( factory, notifiableTestStream, 0 );
@@ -900,7 +900,7 @@ public class ForkClientTest
         when( factory.getReportsDirectory() )
                 .thenReturn( new File( target, "surefire-reports" ) );
         MockReporter receiver = new MockReporter();
-        when( factory.createReporter() )
+        when( factory.getRunListener() )
                 .thenReturn( receiver );
         NotifiableTestStream notifiableTestStream = mock( NotifiableTestStream.class );
 
@@ -933,7 +933,7 @@ public class ForkClientTest
         verify( notifiableTestStream )
                 .shutdown( Shutdown.KILL );
         verifyNoMoreInteractions( notifiableTestStream );
-        verify( factory ).createReporter();
+        verify( factory ).getRunListener();
         verifyNoMoreInteractions( factory );
         assertThat( client.getReporter() )
                 .isNotNull();
@@ -995,7 +995,7 @@ public class ForkClientTest
         when( factory.getReportsDirectory() )
                 .thenReturn( new File( target, "surefire-reports" ) );
         MockReporter receiver = new MockReporter();
-        when( factory.createReporter() )
+        when( factory.getRunListener() )
                 .thenReturn( receiver );
         NotifiableTestStream notifiableTestStream = mock( NotifiableTestStream.class );
 
@@ -1027,7 +1027,7 @@ public class ForkClientTest
         client.tryToTimeout( System.currentTimeMillis(), 1 );
 
         verifyZeroInteractions( notifiableTestStream );
-        verify( factory ).createReporter();
+        verify( factory ).getRunListener();
         verifyNoMoreInteractions( factory );
         assertThat( client.getReporter() )
                 .isNotNull();
@@ -1091,7 +1091,7 @@ public class ForkClientTest
         when( factory.getReportsDirectory() )
                 .thenReturn( new File( target, "surefire-reports" ) );
         MockReporter receiver = new MockReporter();
-        when( factory.createReporter() )
+        when( factory.getRunListener() )
                 .thenReturn( receiver );
         NotifiableTestStream notifiableTestStream = mock( NotifiableTestStream.class );
 
@@ -1120,7 +1120,7 @@ public class ForkClientTest
         client.handleEvent( new TestsetCompletedEvent( NORMAL_RUN, reportEntry ) );
 
         verifyZeroInteractions( notifiableTestStream );
-        verify( factory ).createReporter();
+        verify( factory ).getRunListener();
         verifyNoMoreInteractions( factory );
         assertThat( client.getReporter() )
                 .isNotNull();
@@ -1184,7 +1184,7 @@ public class ForkClientTest
         when( factory.getReportsDirectory() )
                 .thenReturn( new File( target, "surefire-reports" ) );
         MockReporter receiver = new MockReporter();
-        when( factory.createReporter() )
+        when( factory.getRunListener() )
                 .thenReturn( receiver );
         NotifiableTestStream notifiableTestStream = mock( NotifiableTestStream.class );
 
@@ -1213,7 +1213,7 @@ public class ForkClientTest
         client.handleEvent( new TestStartingEvent( NORMAL_RUN, reportEntry ) );
 
         verifyZeroInteractions( notifiableTestStream );
-        verify( factory ).createReporter();
+        verify( factory ).getRunListener();
         verifyNoMoreInteractions( factory );
         assertThat( client.hasTestsInProgress() )
                 .isTrue();
@@ -1278,7 +1278,7 @@ public class ForkClientTest
         when( factory.getReportsDirectory() )
                 .thenReturn( new File( target, "surefire-reports" ) );
         MockReporter receiver = new MockReporter();
-        when( factory.createReporter() )
+        when( factory.getRunListener() )
                 .thenReturn( receiver );
         NotifiableTestStream notifiableTestStream = mock( NotifiableTestStream.class );
 
@@ -1304,7 +1304,8 @@ public class ForkClientTest
         when( reportEntry.getStackTraceWriter() ).thenReturn( stackTraceWriter );
 
         ForkClient client = new ForkClient( factory, notifiableTestStream,  0 );
-        SimpleReportEntry testStarted = new SimpleReportEntry( reportEntry.getSourceName(), null, null, null );
+        SimpleReportEntry testStarted =
+            new SimpleReportEntry( NORMAL_RUN, 0L, reportEntry.getSourceName(), null, null, null );
         client.handleEvent( new TestStartingEvent( NORMAL_RUN, testStarted ) );
 
         assertThat( client.testsInProgress() )
@@ -1314,7 +1315,7 @@ public class ForkClientTest
         client.handleEvent( new TestSucceededEvent( NORMAL_RUN, reportEntry ) );
 
         verifyZeroInteractions( notifiableTestStream );
-        verify( factory ).createReporter();
+        verify( factory ).getRunListener();
         verifyNoMoreInteractions( factory );
         assertThat( client.getReporter() )
                 .isNotNull();
@@ -1382,7 +1383,7 @@ public class ForkClientTest
         when( factory.getReportsDirectory() )
                 .thenReturn( new File( target, "surefire-reports" ) );
         MockReporter receiver = new MockReporter();
-        when( factory.createReporter() )
+        when( factory.getRunListener() )
                 .thenReturn( receiver );
         NotifiableTestStream notifiableTestStream = mock( NotifiableTestStream.class );
 
@@ -1408,7 +1409,8 @@ public class ForkClientTest
         when( reportEntry.getStackTraceWriter() ).thenReturn( stackTraceWriter );
 
         ForkClient client = new ForkClient( factory, notifiableTestStream, 0 );
-        SimpleReportEntry testClass = new SimpleReportEntry( reportEntry.getSourceName(), null, null, null );
+        SimpleReportEntry testClass =
+            new SimpleReportEntry( NORMAL_RUN, 0L, reportEntry.getSourceName(), null, null, null );
         client.handleEvent( new TestStartingEvent( NORMAL_RUN, testClass ) );
 
         assertThat( client.testsInProgress() )
@@ -1418,7 +1420,7 @@ public class ForkClientTest
         client.handleEvent( new TestFailedEvent( NORMAL_RUN, reportEntry ) );
 
         verifyZeroInteractions( notifiableTestStream );
-        verify( factory ).createReporter();
+        verify( factory ).getRunListener();
         verifyNoMoreInteractions( factory );
         assertThat( client.getReporter() )
                 .isNotNull();
@@ -1492,7 +1494,7 @@ public class ForkClientTest
         when( factory.getReportsDirectory() )
                 .thenReturn( new File( target, "surefire-reports" ) );
         MockReporter receiver = new MockReporter();
-        when( factory.createReporter() )
+        when( factory.getRunListener() )
                 .thenReturn( receiver );
         NotifiableTestStream notifiableTestStream = mock( NotifiableTestStream.class );
 
@@ -1518,7 +1520,8 @@ public class ForkClientTest
         when( reportEntry.getStackTraceWriter() ).thenReturn( stackTraceWriter );
 
         ForkClient client = new ForkClient( factory, notifiableTestStream, 0 );
-        SimpleReportEntry testStarted = new SimpleReportEntry( reportEntry.getSourceName(), null, null, null );
+        SimpleReportEntry testStarted =
+            new SimpleReportEntry( NORMAL_RUN, 0L, reportEntry.getSourceName(), null, null, null );
         client.handleEvent( new TestStartingEvent( NORMAL_RUN, testStarted ) );
 
         assertThat( client.testsInProgress() )
@@ -1528,7 +1531,7 @@ public class ForkClientTest
         client.handleEvent( new TestSkippedEvent( NORMAL_RUN, reportEntry ) );
 
         verifyZeroInteractions( notifiableTestStream );
-        verify( factory ).createReporter();
+        verify( factory ).getRunListener();
         verifyNoMoreInteractions( factory );
         assertThat( client.getReporter() )
                 .isNotNull();
@@ -1600,7 +1603,7 @@ public class ForkClientTest
         when( factory.getReportsDirectory() )
                 .thenReturn( new File( target, "surefire-reports" ) );
         MockReporter receiver = new MockReporter();
-        when( factory.createReporter() )
+        when( factory.getRunListener() )
                 .thenReturn( receiver );
         NotifiableTestStream notifiableTestStream = mock( NotifiableTestStream.class );
 
@@ -1627,8 +1630,8 @@ public class ForkClientTest
         when( reportEntry.getStackTraceWriter() ).thenReturn( stackTraceWriter );
 
         ForkClient client = new ForkClient( factory, notifiableTestStream, 0 );
-        SimpleReportEntry testStarted =
-            new SimpleReportEntry( reportEntry.getSourceName(), reportEntry.getSourceText(), null, null );
+        SimpleReportEntry testStarted = new SimpleReportEntry( NORMAL_RUN, 0L, reportEntry.getSourceName(),
+            reportEntry.getSourceText(), null, null );
         client.handleEvent( new TestStartingEvent( NORMAL_RUN, testStarted ) );
 
         assertThat( client.testsInProgress() )
@@ -1638,7 +1641,7 @@ public class ForkClientTest
         client.handleEvent( new TestErrorEvent( NORMAL_RUN, reportEntry ) );
 
         verifyZeroInteractions( notifiableTestStream );
-        verify( factory ).createReporter();
+        verify( factory ).getRunListener();
         verifyNoMoreInteractions( factory );
         assertThat( client.getReporter() )
                 .isNotNull();
@@ -1706,7 +1709,7 @@ public class ForkClientTest
         when( factory.getReportsDirectory() )
                 .thenReturn( new File( target, "surefire-reports" ) );
         MockReporter receiver = new MockReporter();
-        when( factory.createReporter() )
+        when( factory.getRunListener() )
                 .thenReturn( receiver );
         NotifiableTestStream notifiableTestStream = mock( NotifiableTestStream.class );
 
@@ -1733,7 +1736,8 @@ public class ForkClientTest
         when( reportEntry.getStackTraceWriter() ).thenReturn( stackTraceWriter );
 
         ForkClient client = new ForkClient( factory, notifiableTestStream, 0 );
-        SimpleReportEntry testStarted = new SimpleReportEntry( reportEntry.getSourceName(), null, null, null );
+        SimpleReportEntry testStarted =
+            new SimpleReportEntry( NORMAL_RUN, 0L, reportEntry.getSourceName(), null, null, null );
         client.handleEvent( new TestStartingEvent( NORMAL_RUN, testStarted ) );
 
         assertThat( client.testsInProgress() )
@@ -1743,7 +1747,7 @@ public class ForkClientTest
         client.handleEvent( new TestAssumptionFailureEvent( NORMAL_RUN, reportEntry ) );
 
         verifyZeroInteractions( notifiableTestStream );
-        verify( factory ).createReporter();
+        verify( factory ).getRunListener();
         verifyNoMoreInteractions( factory );
         assertThat( client.getReporter() )
                 .isNotNull();
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/DefaultReporterFactoryTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/DefaultReporterFactoryTest.java
index 14e4d82..ee198c9 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/DefaultReporterFactoryTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/DefaultReporterFactoryTest.java
@@ -286,7 +286,7 @@ public class DefaultReporterFactoryTest
 
         DefaultReporterFactory factory = new DefaultReporterFactory( reportConfig, reporter );
 
-        TestSetRunListener runListener = (TestSetRunListener) factory.createReporter();
+        TestSetRunListener runListener = (TestSetRunListener) factory.getRunListener();
 
         assertTrue( runListener.isDebugEnabled() );
         assertTrue( runListener.isInfoEnabled() );
@@ -358,7 +358,7 @@ public class DefaultReporterFactoryTest
         DefaultReporterFactory factory = new DefaultReporterFactory( reportConfig, reporter );
         assertEquals( reportsDirectory, factory.getReportsDirectory() );
 
-        TestSetRunListener runListener = (TestSetRunListener) factory.createReporter();
+        TestSetRunListener runListener = (TestSetRunListener) factory.getRunListener();
         Collection listeners = getInternalState( factory, "listeners" );
         assertEquals( 1, listeners.size() );
         assertTrue( listeners.contains( runListener ) );
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporterTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporterTest.java
index 35fad19..8aec095 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporterTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporterTest.java
@@ -43,6 +43,8 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
+import static org.apache.maven.surefire.api.report.RunMode.RERUN_TEST_AFTER_FAILURE;
 import static org.apache.maven.surefire.api.util.internal.ObjectUtils.systemProps;
 import static org.fest.assertions.Assertions.assertThat;
 import static org.mockito.Mockito.doThrow;
@@ -106,7 +108,8 @@ public class StatelessXmlReporterTest
                         false, false, false, false );
         reporter.cleanTestHistoryMap();
 
-        ReportEntry reportEntry = new SimpleReportEntry( getClass().getName(), null, getClass().getName(), null, 12 );
+        ReportEntry reportEntry = new SimpleReportEntry( NORMAL_RUN, 0L,
+            getClass().getName(), null, getClass().getName(), null, 12 );
         WrappedReportEntry testSetReportEntry = new WrappedReportEntry( reportEntry, ReportEntryType.SUCCESS,
                 12, null, null, systemProps() );
         stats.testSucceeded( testSetReportEntry );
@@ -121,7 +124,8 @@ public class StatelessXmlReporterTest
     public void testAllFieldsSerialized()
             throws IOException
     {
-        ReportEntry reportEntry = new SimpleReportEntry( getClass().getName(), null, TEST_ONE, null, 12 );
+        ReportEntry reportEntry = new SimpleReportEntry( NORMAL_RUN, 0L,
+            getClass().getName(), null, TEST_ONE, null, 12 );
         WrappedReportEntry testSetReportEntry =
                 new WrappedReportEntry( reportEntry, ReportEntryType.SUCCESS, 12, null, null, systemProps() );
         expectedReportFile = new File( reportDir, "TEST-" + getClass().getName() + ".xml" );
@@ -147,9 +151,9 @@ public class StatelessXmlReporterTest
         Utf8RecodingDeferredFileOutputStream stdErr = new Utf8RecodingDeferredFileOutputStream( "fds" );
 
         stdErr.write( stdErrPrefix + "?&-&amp;&#163;\u0020\u0000\u001F", false );
-        WrappedReportEntry t2 =
-                new WrappedReportEntry( new SimpleReportEntry( getClass().getName(), null, TEST_TWO, null,
-                        stackTraceWriter, 13 ), ReportEntryType.ERROR, 13, stdOut, stdErr );
+        WrappedReportEntry t2 = new WrappedReportEntry( new SimpleReportEntry( NORMAL_RUN, 0L,
+            getClass().getName(), null, TEST_TWO, null, stackTraceWriter, 13 ),
+            ReportEntryType.ERROR, 13, stdOut, stdErr );
 
         stats.testSucceeded( t2 );
         StatelessXmlReporter reporter = new StatelessXmlReporter( reportDir, null, false, 0,
@@ -190,7 +194,8 @@ public class StatelessXmlReporterTest
             throws IOException
     {
         WrappedReportEntry testSetReportEntry =
-                new WrappedReportEntry( new SimpleReportEntry( getClass().getName(), null, TEST_ONE, null, 12 ),
+                new WrappedReportEntry( new SimpleReportEntry( NORMAL_RUN, 0L,
+                    getClass().getName(), null, TEST_ONE, null, 12 ),
                         ReportEntryType.SUCCESS, 12, null, null, systemProps() );
         expectedReportFile = new File( reportDir, "TEST-" + getClass().getName() + ".xml" );
 
@@ -205,25 +210,22 @@ public class StatelessXmlReporterTest
         String secondRunOut = "second run out";
         String secondRunErr = "second run err";
 
-        WrappedReportEntry testTwoFirstError =
-                new WrappedReportEntry( new SimpleReportEntry( getClass().getName(), null, TEST_TWO, null,
-                        stackTraceWriterOne, 5 ), ReportEntryType.ERROR, 5, createStdOutput( firstRunOut ),
-                        createStdOutput( firstRunErr ) );
+        String cls = getClass().getName();
+        WrappedReportEntry testTwoFirstError = new WrappedReportEntry( new SimpleReportEntry( NORMAL_RUN, 0L,
+            cls, null, TEST_TWO, null, stackTraceWriterOne, 5 ),
+            ReportEntryType.ERROR, 5, createStdOutput( firstRunOut ), createStdOutput( firstRunErr ) );
 
-        WrappedReportEntry testTwoSecondError =
-                new WrappedReportEntry( new SimpleReportEntry( getClass().getName(), null, TEST_TWO, null,
-                        stackTraceWriterTwo, 13 ), ReportEntryType.ERROR, 13, createStdOutput( secondRunOut ),
-                        createStdOutput( secondRunErr ) );
+        WrappedReportEntry testTwoSecondError = new WrappedReportEntry( new SimpleReportEntry(
+            RERUN_TEST_AFTER_FAILURE, 1L, cls, null, TEST_TWO, null, stackTraceWriterTwo, 13 ),
+            ReportEntryType.ERROR, 13, createStdOutput( secondRunOut ), createStdOutput( secondRunErr ) );
 
-        WrappedReportEntry testThreeFirstRun =
-                new WrappedReportEntry( new SimpleReportEntry( getClass().getName(), null, TEST_THREE, null,
-                        stackTraceWriterOne, 13 ), ReportEntryType.FAILURE, 13, createStdOutput( firstRunOut ),
-                        createStdOutput( firstRunErr ) );
+        WrappedReportEntry testThreeFirstRun = new WrappedReportEntry( new SimpleReportEntry( NORMAL_RUN, 2L,
+            cls, null, TEST_THREE, null, stackTraceWriterOne, 13 ),
+            ReportEntryType.FAILURE, 13, createStdOutput( firstRunOut ), createStdOutput( firstRunErr ) );
 
-        WrappedReportEntry testThreeSecondRun =
-                new WrappedReportEntry( new SimpleReportEntry( getClass().getName(), null, TEST_THREE, null,
-                        stackTraceWriterTwo, 2 ), ReportEntryType.SUCCESS, 2, createStdOutput( secondRunOut ),
-                        createStdOutput( secondRunErr ) );
+        WrappedReportEntry testThreeSecondRun = new WrappedReportEntry( new SimpleReportEntry(
+            RERUN_TEST_AFTER_FAILURE, 3L, cls, null, TEST_THREE, null, stackTraceWriterTwo, 2 ),
+            ReportEntryType.SUCCESS, 2, createStdOutput( secondRunOut ), createStdOutput( secondRunErr ) );
 
         stats.testSucceeded( testTwoFirstError );
         stats.testSucceeded( testThreeFirstRun );
@@ -328,7 +330,7 @@ public class StatelessXmlReporterTest
         out.write( null, true );
 
         assertThat( out.getByteCount() )
-            .isEqualTo( 33_000 * ( 1 + 1 + NL.length() ) + 4 + 4 + NL.length() );
+            .isEqualTo( 33_000L * ( 1 + 1 + NL.length() ) + 4 + 4 + NL.length() );
 
         StringBuilder expectedContent = new StringBuilder( 150_000 );
         for ( int i = 0; i < 33_000; i++ )
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/WrappedReportEntryTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/WrappedReportEntryTest.java
index 208896e..7d40e88 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/WrappedReportEntryTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/report/WrappedReportEntryTest.java
@@ -28,6 +28,7 @@ import static org.apache.maven.plugin.surefire.report.ReportEntryType.ERROR;
 import static org.apache.maven.plugin.surefire.report.ReportEntryType.FAILURE;
 import static org.apache.maven.plugin.surefire.report.ReportEntryType.SKIPPED;
 import static org.apache.maven.plugin.surefire.report.ReportEntryType.SUCCESS;
+import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
 
 /**
  * @author Kristian Rosenvold
@@ -39,7 +40,8 @@ public class WrappedReportEntryTest
     {
         String className = "surefire.testcase.JunitParamsTest";
         WrappedReportEntry wr =
-            new WrappedReportEntry( new SimpleReportEntry( className, null, null, null ), SUCCESS, 12, null, null );
+            new WrappedReportEntry( new SimpleReportEntry( NORMAL_RUN, 1L, className, null, null, null ),
+                SUCCESS, 12, null, null );
         final String reportName = wr.getReportSourceName();
         assertEquals( "surefire.testcase.JunitParamsTest.null", wr.getClassMethodName() );
         assertEquals( "surefire.testcase.JunitParamsTest", reportName );
@@ -50,7 +52,8 @@ public class WrappedReportEntryTest
 
     public void testRegular()
     {
-        ReportEntry reportEntry = new SimpleReportEntry( "surefire.testcase.JunitParamsTest", null, "testSum", null );
+        ReportEntry reportEntry =
+            new SimpleReportEntry( NORMAL_RUN, 1L, "surefire.testcase.JunitParamsTest", null, "testSum", null );
         WrappedReportEntry wr = new WrappedReportEntry( reportEntry, null, 12, null, null );
         assertEquals( "surefire.testcase.JunitParamsTest.testSum", wr.getClassMethodName() );
         assertEquals( "surefire.testcase.JunitParamsTest", wr.getReportSourceName() );
@@ -69,8 +72,8 @@ public class WrappedReportEntryTest
 
     public void testDisplayNames()
     {
-        ReportEntry reportEntry =
-                new SimpleReportEntry( "surefire.testcase.JunitParamsTest", "dn1", "testSum", "dn2", "exception" );
+        ReportEntry reportEntry = new SimpleReportEntry( NORMAL_RUN, 0L,
+            "surefire.testcase.JunitParamsTest", "dn1", "testSum", "dn2", "exception" );
         WrappedReportEntry wr = new WrappedReportEntry( reportEntry, ERROR, 12, null, null );
         assertEquals( "surefire.testcase.JunitParamsTest.testSum", wr.getClassMethodName() );
         assertEquals( "dn1", wr.getReportSourceName() );
@@ -90,7 +93,7 @@ public class WrappedReportEntryTest
 
     public void testEqualDisplayNames()
     {
-        ReportEntry reportEntry = new SimpleReportEntry( "surefire.testcase.JunitParamsTest",
+        ReportEntry reportEntry = new SimpleReportEntry( NORMAL_RUN, 1L, "surefire.testcase.JunitParamsTest",
                 "surefire.testcase.JunitParamsTest", "testSum", "testSum" );
         WrappedReportEntry wr = new WrappedReportEntry( reportEntry, FAILURE, 12, null, null );
         assertEquals( "surefire.testcase.JunitParamsTest", wr.getReportSourceName() );
@@ -104,7 +107,7 @@ public class WrappedReportEntryTest
     public void testGetReportNameWithParams()
     {
         String className = "[0] 1\u002C 2\u002C 3 (testSum)";
-        ReportEntry reportEntry = new SimpleReportEntry( className, null, null, null );
+        ReportEntry reportEntry = new SimpleReportEntry( NORMAL_RUN, 1L, className, null, null, null );
         WrappedReportEntry wr = new WrappedReportEntry( reportEntry, SKIPPED, 12, null, null );
         final String reportName = wr.getReportSourceName();
         assertEquals( "[0] 1, 2, 3 (testSum)", reportName );
@@ -116,7 +119,7 @@ public class WrappedReportEntryTest
     public void testElapsed()
     {
         String className = "[0] 1\u002C 2\u002C 3 (testSum)";
-        ReportEntry reportEntry = new SimpleReportEntry( className, null, null, null );
+        ReportEntry reportEntry = new SimpleReportEntry( NORMAL_RUN, 1L, className, null, null, null );
         WrappedReportEntry wr = new WrappedReportEntry( reportEntry, null, 12, null, null );
         String elapsedTimeSummary = wr.getElapsedTimeSummary();
         assertEquals( "[0] 1, 2, 3 (testSum)  Time elapsed: 0.012 s",
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/runorder/RunEntryStatisticsMapTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/runorder/RunEntryStatisticsMapTest.java
index 5f6840a..5938912 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/runorder/RunEntryStatisticsMapTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/runorder/RunEntryStatisticsMapTest.java
@@ -38,6 +38,7 @@ import junit.framework.TestCase;
 import org.apache.maven.surefire.api.util.internal.ClassMethod;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
 import static org.apache.maven.surefire.shared.io.IOUtils.readLines;
 import static org.apache.maven.surefire.api.util.internal.StringUtils.NL;
 import static org.fest.assertions.Assertions.assertThat;
@@ -86,7 +87,8 @@ public class RunEntryStatisticsMapTest
     {
         File data = File.createTempFile( "surefire-unit", "test" );
         RunEntryStatisticsMap newResults = new RunEntryStatisticsMap();
-        ReportEntry reportEntry = new SimpleReportEntry( "abc", null, null, null, 42 );
+        ReportEntry reportEntry = new SimpleReportEntry( NORMAL_RUN, 0L,
+            "abc", null, null, null, 42 );
         newResults.add( newResults.createNextGeneration( reportEntry ) );
         newResults.serialize( data );
         try ( InputStream io = new FileInputStream( data ) )
@@ -131,9 +133,12 @@ public class RunEntryStatisticsMapTest
         RunEntryStatisticsMap existingEntries = RunEntryStatisticsMap.fromFile( data );
         RunEntryStatisticsMap newResults = new RunEntryStatisticsMap();
 
-        ReportEntry reportEntry1 = new SimpleReportEntry( "abc", null, "method1", null, 42 );
-        ReportEntry reportEntry2 = new SimpleReportEntry( "abc", null, "willFail", null, 17 );
-        ReportEntry reportEntry3 = new SimpleReportEntry( "abc", null, "method3", null, 100 );
+        ReportEntry reportEntry1 = new SimpleReportEntry( NORMAL_RUN, 0L,
+            "abc", null, "method1", null, 42 );
+        ReportEntry reportEntry2 = new SimpleReportEntry( NORMAL_RUN, 0L,
+            "abc", null, "willFail", null, 17 );
+        ReportEntry reportEntry3 = new SimpleReportEntry( NORMAL_RUN, 0L,
+            "abc", null, "method3", null, 100 );
 
         newResults.add( existingEntries.createNextGeneration( reportEntry1 ) );
         newResults.add( existingEntries.createNextGeneration( reportEntry2 ) );
@@ -154,9 +159,12 @@ public class RunEntryStatisticsMapTest
         RunEntryStatisticsMap nextRun = RunEntryStatisticsMap.fromFile( data );
         newResults = new RunEntryStatisticsMap();
 
-        ReportEntry newRunReportEntry1 = new SimpleReportEntry( "abc", null, "method1", null, 52 );
-        ReportEntry newRunReportEntry2 = new SimpleReportEntry( "abc", null, "willFail", null, 27 );
-        ReportEntry newRunReportEntry3 = new SimpleReportEntry( "abc", null, "method3", null, 110 );
+        ReportEntry newRunReportEntry1 = new SimpleReportEntry( NORMAL_RUN, 0L,
+            "abc", null, "method1", null, 52 );
+        ReportEntry newRunReportEntry2 = new SimpleReportEntry( NORMAL_RUN, 0L,
+            "abc", null, "willFail", null, 27 );
+        ReportEntry newRunReportEntry3 = new SimpleReportEntry( NORMAL_RUN, 0L,
+            "abc", null, "method3", null, 110 );
 
         newResults.add( nextRun.createNextGeneration( newRunReportEntry1 ) );
         newResults.add( nextRun.createNextGenerationFailure( newRunReportEntry2 ) );
@@ -180,7 +188,8 @@ public class RunEntryStatisticsMapTest
     {
         File data = File.createTempFile( "surefire-unit", "test" );
         RunEntryStatisticsMap reportEntries = RunEntryStatisticsMap.fromFile( data );
-        ReportEntry reportEntry = new SimpleReportEntry( "abc", null, "line1\nline2" + NL + " line3", null, 42 );
+        ReportEntry reportEntry = new SimpleReportEntry( NORMAL_RUN, 0L,
+            "abc", null, "line1\nline2" + NL + " line3", null, 42 );
         reportEntries.add( reportEntries.createNextGeneration( reportEntry ) );
 
         reportEntries.serialize( data );
@@ -215,10 +224,10 @@ public class RunEntryStatisticsMapTest
     {
         File data = File.createTempFile( "surefire-unit", "test" );
         RunEntryStatisticsMap reportEntries = RunEntryStatisticsMap.fromFile( data );
-        reportEntries.add(
-                reportEntries.createNextGeneration( new SimpleReportEntry( "abc", null, "line1\nline2", null, 42 ) ) );
-        reportEntries.add(
-                reportEntries.createNextGeneration( new SimpleReportEntry( "abc", null, "test", null, 10 ) ) );
+        reportEntries.add( reportEntries.createNextGeneration( new SimpleReportEntry( NORMAL_RUN, 0L,
+                    "abc", null, "line1\nline2", null, 42 ) ) );
+        reportEntries.add( reportEntries.createNextGeneration( new SimpleReportEntry( NORMAL_RUN, 0L,
+            "abc", null, "test", null, 10 ) ) );
 
         reportEntries.serialize( data );
         try ( InputStream io = new FileInputStream( data ) )
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/api/booter/BaseProviderFactory.java b/surefire-api/src/main/java/org/apache/maven/surefire/api/booter/BaseProviderFactory.java
index 9654b14..1436e98 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/api/booter/BaseProviderFactory.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/api/booter/BaseProviderFactory.java
@@ -22,8 +22,6 @@ package org.apache.maven.surefire.api.booter;
 import org.apache.maven.surefire.api.cli.CommandLineOption;
 import org.apache.maven.surefire.api.provider.CommandChainReader;
 import org.apache.maven.surefire.api.provider.ProviderParameters;
-import org.apache.maven.surefire.api.report.ConsoleStream;
-import org.apache.maven.surefire.api.report.DefaultDirectConsoleReporter;
 import org.apache.maven.surefire.api.report.ReporterConfiguration;
 import org.apache.maven.surefire.api.report.ReporterFactory;
 import org.apache.maven.surefire.api.testset.DirectoryScannerParameters;
@@ -53,8 +51,6 @@ public class BaseProviderFactory
 
     private ReporterFactory reporterFactory;
 
-    private MasterProcessChannelEncoder masterProcessChannelEncoder;
-
     private List<CommandLineOption> mainCliOptions = emptyList();
 
     private Map<String, String> providerProperties;
@@ -148,14 +144,6 @@ public class BaseProviderFactory
         this.testClassLoader = testClassLoader;
     }
 
-    @Override
-    public ConsoleStream getConsoleLogger()
-    {
-        return insideFork
-            ? new ForkingRunListener( masterProcessChannelEncoder, reporterConfiguration.isTrimStackTrace() )
-            : new DefaultDirectConsoleReporter( reporterConfiguration.getOriginalSystemOut() );
-    }
-
     public void setTestRequest( TestRequest testRequest )
     {
         this.testRequest = testRequest;
@@ -260,9 +248,4 @@ public class BaseProviderFactory
     {
         this.systemExitTimeout = systemExitTimeout;
     }
-
-    public void setForkedChannelEncoder( MasterProcessChannelEncoder masterProcessChannelEncoder )
-    {
-        this.masterProcessChannelEncoder = masterProcessChannelEncoder;
-    }
 }
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/api/booter/ForkingReporterFactory.java b/surefire-api/src/main/java/org/apache/maven/surefire/api/booter/ForkingReporterFactory.java
index 31bbfa5..e33abc5 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/api/booter/ForkingReporterFactory.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/api/booter/ForkingReporterFactory.java
@@ -19,8 +19,11 @@ package org.apache.maven.surefire.api.booter;
  * under the License.
  */
 
+import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
+import org.apache.maven.surefire.api.report.AbstractRunListener;
+import org.apache.maven.surefire.api.report.ConsoleStream;
 import org.apache.maven.surefire.api.report.ReporterFactory;
-import org.apache.maven.surefire.api.report.RunListener;
+import org.apache.maven.surefire.api.report.RunListenerContext;
 import org.apache.maven.surefire.api.suite.RunResult;
 
 /**
@@ -32,20 +35,30 @@ import org.apache.maven.surefire.api.suite.RunResult;
 public class ForkingReporterFactory
     implements ReporterFactory
 {
-    private final boolean trimstackTrace;
+    private final ForkingRunListener runListener;
 
-    private final MasterProcessChannelEncoder eventChannel;
+    public ForkingReporterFactory( RunListenerContext ctx, boolean trimStackTrace,
+                                   MasterProcessChannelEncoder eventChannel )
+    {
+        runListener = new ForkingRunListener( ctx, eventChannel, trimStackTrace );
+    }
 
-    public ForkingReporterFactory( boolean trimstackTrace, MasterProcessChannelEncoder eventChannel )
+    @Override
+    public AbstractRunListener getRunListener()
+    {
+        return runListener;
+    }
+
+    @Override
+    public ConsoleLogger getConsoleLogger()
     {
-        this.trimstackTrace = trimstackTrace;
-        this.eventChannel = eventChannel;
+        return runListener;
     }
 
     @Override
-    public RunListener createReporter()
+    public ConsoleStream getConsoleStream()
     {
-        return new ForkingRunListener( eventChannel, trimstackTrace );
+        return runListener;
     }
 
     @Override
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/api/booter/ForkingRunListener.java b/surefire-api/src/main/java/org/apache/maven/surefire/api/booter/ForkingRunListener.java
index 169f358..daaa4a0 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/api/booter/ForkingRunListener.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/api/booter/ForkingRunListener.java
@@ -20,15 +20,16 @@ package org.apache.maven.surefire.api.booter;
  */
 
 import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
+import org.apache.maven.surefire.api.report.AbstractRunListener;
 import org.apache.maven.surefire.api.report.ConsoleOutputReceiver;
 import org.apache.maven.surefire.api.report.ConsoleStream;
 import org.apache.maven.surefire.api.report.ReportEntry;
-import org.apache.maven.surefire.api.report.RunListener;
+import org.apache.maven.surefire.api.report.RunListenerContext;
 import org.apache.maven.surefire.api.report.RunMode;
 import org.apache.maven.surefire.api.report.TestSetReportEntry;
 
-import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
 import static java.util.Objects.requireNonNull;
+import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
 
 /**
  * Encodes the full output of the test run to the stdout stream.
@@ -47,8 +48,9 @@ import static java.util.Objects.requireNonNull;
  *
  * @author Kristian Rosenvold
  */
-public class ForkingRunListener
-    implements RunListener, ConsoleLogger, ConsoleOutputReceiver, ConsoleStream
+public final class ForkingRunListener
+    extends AbstractRunListener
+    implements ConsoleLogger, ConsoleOutputReceiver, ConsoleStream
 {
     private final MasterProcessChannelEncoder target;
 
@@ -56,8 +58,9 @@ public class ForkingRunListener
 
     private volatile RunMode runMode = NORMAL_RUN;
 
-    public ForkingRunListener( MasterProcessChannelEncoder target, boolean trim )
+    public ForkingRunListener( RunListenerContext ctx, MasterProcessChannelEncoder target, boolean trim )
     {
+        super( ctx );
         this.target = target;
         this.trim = trim;
     }
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/api/provider/ProviderParameters.java b/surefire-api/src/main/java/org/apache/maven/surefire/api/provider/ProviderParameters.java
index 048622f..34a2ffa 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/api/provider/ProviderParameters.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/api/provider/ProviderParameters.java
@@ -20,7 +20,6 @@ package org.apache.maven.surefire.api.provider;
  */
 
 import org.apache.maven.surefire.api.cli.CommandLineOption;
-import org.apache.maven.surefire.api.report.ConsoleStream;
 import org.apache.maven.surefire.api.report.ReporterConfiguration;
 import org.apache.maven.surefire.api.report.ReporterFactory;
 import org.apache.maven.surefire.api.testset.DirectoryScannerParameters;
@@ -78,16 +77,6 @@ public interface ProviderParameters
     ReporterFactory getReporterFactory();
 
     /**
-     * Gets a logger intended for console output.
-     * <br>
-     * This output is intended for provider-oriented messages that are not attached to a single test-set
-     * and will normally be written to something console-like immediately.
-     *
-     * @return A console stream logger
-     */
-    ConsoleStream getConsoleLogger();
-
-    /**
      * The raw parameters used in creating the directory scanner
      *
      * @return The parameters
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/api/report/DefaultDirectConsoleReporter.java b/surefire-api/src/main/java/org/apache/maven/surefire/api/report/AbstractRunListener.java
similarity index 68%
copy from surefire-api/src/main/java/org/apache/maven/surefire/api/report/DefaultDirectConsoleReporter.java
copy to surefire-api/src/main/java/org/apache/maven/surefire/api/report/AbstractRunListener.java
index b3a4c1c..c8c7ba7 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/api/report/DefaultDirectConsoleReporter.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/api/report/AbstractRunListener.java
@@ -19,24 +19,22 @@ package org.apache.maven.surefire.api.report;
  * under the License.
  */
 
-import java.io.PrintStream;
+import javax.annotation.Nonnull;
 
 /**
- * @author <a href="mailto:kristian@zenior.no">Kristian Rosenvold</a>
+ * Base class for run-listeners used in providers and ForkingRunListener.
  */
-public final class DefaultDirectConsoleReporter
-    implements ConsoleStream
+public abstract class AbstractRunListener implements RunListener
 {
-    private final PrintStream systemOut;
+    private final RunListenerContext ctx;
 
-    public DefaultDirectConsoleReporter( PrintStream systemOut )
+    protected AbstractRunListener( @Nonnull RunListenerContext ctx )
     {
-        this.systemOut = systemOut;
+        this.ctx = ctx;
     }
 
-    @Override
-    public void println( String message )
+    public final RunListenerContext getContext()
     {
-        systemOut.println( message );
+        return ctx;
     }
 }
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/api/report/CategorizedReportEntry.java b/surefire-api/src/main/java/org/apache/maven/surefire/api/report/CategorizedReportEntry.java
index 34be63c..ead2302 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/api/report/CategorizedReportEntry.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/api/report/CategorizedReportEntry.java
@@ -19,6 +19,8 @@ package org.apache.maven.surefire.api.report;
  * under the License.
  */
 
+import javax.annotation.Nonnegative;
+import javax.annotation.Nonnull;
 import java.util.Collections;
 import java.util.Map;
 import java.util.Objects;
@@ -35,42 +37,48 @@ public class CategorizedReportEntry
 
     private final String group;
 
-    public CategorizedReportEntry( String source, String name, String group )
+    public CategorizedReportEntry( @Nonnull RunMode runMode, @Nonnegative long testRunId,
+                                   String source, String name, String group )
     {
-        this( source, name, group, null, null );
+        this( runMode, testRunId, source, name, group, null, null );
     }
 
-    public CategorizedReportEntry( String source, String name, String group, StackTraceWriter stackTraceWriter,
+    public CategorizedReportEntry( @Nonnull RunMode runMode, @Nonnegative long testRunId,
+                                   String source, String name, String group, StackTraceWriter stackTraceWriter,
                                    Integer elapsed )
     {
-        super( source, null, name, null, stackTraceWriter, elapsed );
+        super( runMode, testRunId, source, null, name, null, stackTraceWriter, elapsed );
         this.group = group;
     }
 
-    public CategorizedReportEntry( String source, String name, String group, StackTraceWriter stackTraceWriter,
+    public CategorizedReportEntry( @Nonnull RunMode runMode, @Nonnegative long testRunId,
+                                   String source, String name, String group, StackTraceWriter stackTraceWriter,
                                    Integer elapsed, String message )
     {
-        this( source, null, name, null,
-                group, stackTraceWriter, elapsed, message, Collections.<String, String>emptyMap() );
+        this( runMode, testRunId, source, null, name, null,
+            group, stackTraceWriter, elapsed, message, Collections.<String, String>emptyMap() );
     }
 
-    public CategorizedReportEntry( String source, String sourceText, String name, String nameText,
+    public CategorizedReportEntry( @Nonnull RunMode runMode, @Nonnegative long testRunId,
+                                   String source, String sourceText, String name, String nameText,
                                    String group, StackTraceWriter stackTraceWriter,
                                    Integer elapsed, String message, Map<String, String> systemProperties )
     {
-        super( source, sourceText, name, nameText, stackTraceWriter, elapsed, message, systemProperties );
+        super( runMode, testRunId, source, sourceText, name, nameText, stackTraceWriter, elapsed, message,
+            systemProperties );
         this.group = group;
     }
 
-    public static TestSetReportEntry reportEntry( String source, String sourceText, String name, String nameText,
-                                                  String group,
+    public static TestSetReportEntry reportEntry( @Nonnull RunMode runMode, @Nonnegative Long testRunId,
+                                                  String source, String sourceText,
+                                                  String name, String nameText, String group,
                                                   StackTraceWriter stackTraceWriter, Integer elapsed, String message,
                                                   Map<String, String> systemProperties )
     {
         return group != null
-            ? new CategorizedReportEntry( source, sourceText, name, nameText,
+            ? new CategorizedReportEntry( runMode, testRunId, source, sourceText, name, nameText,
                 group, stackTraceWriter, elapsed, message, systemProperties )
-            : new SimpleReportEntry( source, sourceText, name, nameText,
+            : new SimpleReportEntry( runMode, testRunId, source, sourceText, name, nameText,
                 stackTraceWriter, elapsed, message, systemProperties );
     }
 
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/api/report/ReportEntry.java b/surefire-api/src/main/java/org/apache/maven/surefire/api/report/ReportEntry.java
index 65fb723..a3ab5d1 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/api/report/ReportEntry.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/api/report/ReportEntry.java
@@ -19,6 +19,10 @@ package org.apache.maven.surefire.api.report;
  * under the License.
  */
 
+import javax.annotation.Nonnegative;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
 /**
  * Describes a single entry for a test report
  *
@@ -105,4 +109,21 @@ public interface ReportEntry
      * @return A string with the test case text and group/category, or just the source text.
      */
     String getReportNameWithGroup();
+
+    /**
+     * Run mode.
+     *
+     * @return a normal run, or re-run.
+     */
+    @Nonnull
+    RunMode getRunMode();
+
+    /**
+     * This represents a reference pointing to a literal representation of test description or literal unique id.
+     *
+     * @return id
+     */
+    @Nonnegative
+    @Nullable
+    Long getTestRunId();
 }
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/api/report/ReporterFactory.java b/surefire-api/src/main/java/org/apache/maven/surefire/api/report/ReporterFactory.java
index af9057e..b55b6cc 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/api/report/ReporterFactory.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/api/report/ReporterFactory.java
@@ -19,6 +19,7 @@ package org.apache.maven.surefire.api.report;
  * under the License.
  */
 
+import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
 import org.apache.maven.surefire.api.suite.RunResult;
 
 /**
@@ -29,11 +30,28 @@ import org.apache.maven.surefire.api.suite.RunResult;
 public interface ReporterFactory
 {
     /**
-     * Creates a reporter.
+     * Get a reporter.
      *
      * @return A reporter instance
      */
-    RunListener createReporter();
+    AbstractRunListener getRunListener();
+
+    /**
+     * Gets a logger intended for console output.
+     * <br>
+     * This output is intended for provider-oriented messages that are not attached to a single test-set
+     * and will normally be written to something console-like immediately.
+     *
+     * @return A console logger
+     */
+    ConsoleLogger getConsoleLogger();
+
+    /**
+     * Get a console stream (System.out) used by (forked) provider.
+     *
+     * @return A console stream
+     */
+    ConsoleStream getConsoleStream();
 
     /**
      * Closes the factory, freeing resources allocated in the factory.
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/api/report/RunListenerContext.java b/surefire-api/src/main/java/org/apache/maven/surefire/api/report/RunListenerContext.java
new file mode 100644
index 0000000..6369b58
--- /dev/null
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/api/report/RunListenerContext.java
@@ -0,0 +1,67 @@
+package org.apache.maven.surefire.api.report;
+
+/*
+ * 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 javax.annotation.Nonnull;
+
+/**
+ * Memento object handled by {@link RunListener} (and Providers) which carries a runtime status related
+ * to the listener important for the concrete implementations in the context of Provider where the listener is utilized.
+ */
+public final class RunListenerContext
+{
+    private final ThreadLocal<Long> currentTestIds = new ThreadLocal<>();
+    private volatile RunMode runMode;
+
+    public RunListenerContext( @Nonnull RunMode runMode )
+    {
+        this.runMode = runMode;
+    }
+
+    public void setRunMode( @Nonnull RunMode runMode )
+    {
+        this.runMode = runMode;
+    }
+
+    public RunMode getRunMode()
+    {
+        return runMode;
+    }
+
+    public void removeCurrentTestId()
+    {
+        currentTestIds.remove();
+    }
+
+    public void setCurrentTestId( long testId )
+    {
+        currentTestIds.set( testId );
+    }
+
+    public Long getCurrentTestId()
+    {
+        return currentTestIds.get();
+    }
+
+    public boolean hasCurrentTestId()
+    {
+        return currentTestIds.get() != null;
+    }
+}
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/api/report/SimpleReportEntry.java b/surefire-api/src/main/java/org/apache/maven/surefire/api/report/SimpleReportEntry.java
index 5e324ad..64ff8d8 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/api/report/SimpleReportEntry.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/api/report/SimpleReportEntry.java
@@ -21,6 +21,9 @@ package org.apache.maven.surefire.api.report;
 
 import org.apache.maven.surefire.api.util.internal.ImmutableMap;
 
+import javax.annotation.Nonnegative;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import java.util.Collections;
 import java.util.Map;
 import java.util.Objects;
@@ -33,6 +36,10 @@ import java.util.Objects;
 public class SimpleReportEntry
     implements TestSetReportEntry
 {
+    private final RunMode runMode;
+
+    private final Long testRunId;
+
     private final Map<String, String> systemProperties;
 
     private final String source;
@@ -49,37 +56,46 @@ public class SimpleReportEntry
 
     private final String message;
 
-    public SimpleReportEntry( String source, String sourceText, String name, String nameText )
+    public SimpleReportEntry( @Nonnull RunMode runMode, @Nonnegative Long testRunId,
+                              String source, String sourceText, String name, String nameText )
     {
-        this( source, sourceText, name, nameText, null, null );
+        this( runMode, testRunId, source, sourceText, name, nameText, null, null );
     }
 
-    public SimpleReportEntry( String source, String sourceText, String name, String nameText,
+    public SimpleReportEntry( @Nonnull RunMode runMode, @Nonnegative Long testRunId,
+                              String source, String sourceText, String name, String nameText,
                               Map<String, String> systemProperties )
     {
-        this( source, sourceText, name, nameText, null, null, systemProperties );
+        this( runMode, testRunId, source, sourceText, name, nameText, null, null, systemProperties );
     }
 
-    private SimpleReportEntry( String source, String sourceText, String name, String nameText,
+    private SimpleReportEntry( @Nonnull RunMode runMode, @Nonnegative Long testRunId,
+                               String source, String sourceText, String name, String nameText,
                                StackTraceWriter stackTraceWriter )
     {
-        this( source, sourceText, name, nameText, stackTraceWriter, null );
+        this( runMode, testRunId, source, sourceText, name, nameText, stackTraceWriter, null );
     }
 
-    public SimpleReportEntry( String source, String sourceText, String name, String nameText, Integer elapsed )
+    public SimpleReportEntry( @Nonnull RunMode runMode, @Nonnegative Long testRunId,
+                              String source, String sourceText, String name, String nameText, Integer elapsed )
     {
-        this( source, sourceText, name, nameText, null, elapsed );
+        this( runMode, testRunId, source, sourceText, name, nameText, null, elapsed );
     }
 
-    public SimpleReportEntry( String source, String sourceText, String name, String nameText, String message )
+    public SimpleReportEntry( @Nonnull RunMode runMode, @Nonnegative Long testRunId,
+                              String source, String sourceText, String name, String nameText, String message )
     {
-        this( source, sourceText, name, nameText, null, null, message, Collections.<String, String>emptyMap() );
+        this( runMode, testRunId,
+            source, sourceText, name, nameText, null, null, message, Collections.<String, String>emptyMap() );
     }
 
-    public SimpleReportEntry( String source, String sourceText, String name, String nameText,
-                                 StackTraceWriter stackTraceWriter, Integer elapsed, String message,
-                                 Map<String, String> systemProperties )
+    public SimpleReportEntry( @Nonnull RunMode runMode, @Nonnegative Long testRunId,
+                              String source, String sourceText, String name, String nameText,
+                              StackTraceWriter stackTraceWriter, Integer elapsed, String message,
+                              Map<String, String> systemProperties )
     {
+        this.runMode = runMode;
+        this.testRunId = testRunId;
         this.source = source;
         this.sourceText = sourceText;
         this.name = name;
@@ -90,35 +106,39 @@ public class SimpleReportEntry
         this.systemProperties = new ImmutableMap<>( systemProperties );
     }
 
-    public SimpleReportEntry( String source, String sourceText, String name, String nameText,
-                              StackTraceWriter stackTraceWriter, Integer elapsed )
+    public SimpleReportEntry( @Nonnull RunMode runMode, @Nonnegative Long testRunId,
+                               String source, String sourceText, String name, String nameText,
+                               StackTraceWriter stackTraceWriter, Integer elapsed )
     {
-        this( source, sourceText, name, nameText, stackTraceWriter, elapsed, Collections.<String, String>emptyMap() );
+        this( runMode, testRunId,
+            source, sourceText, name, nameText, stackTraceWriter, elapsed, Collections.<String, String>emptyMap() );
     }
 
-    public SimpleReportEntry( String source, String sourceText, String name, String nameText,
+    public SimpleReportEntry( @Nonnull RunMode runMode, @Nonnegative Long testRunId,
+                              String source, String sourceText, String name, String nameText,
                               StackTraceWriter stackTraceWriter, Integer elapsed, Map<String, String> systemProperties )
     {
-        this( source, sourceText, name, nameText,
-                stackTraceWriter, elapsed, safeGetMessage( stackTraceWriter ), systemProperties );
+        this( runMode, testRunId, source, sourceText, name, nameText,
+            stackTraceWriter, elapsed, safeGetMessage( stackTraceWriter ), systemProperties );
     }
 
-    public static SimpleReportEntry assumption( String source, String sourceText, String name, String nameText,
-                                                String message )
+    public static SimpleReportEntry assumption( RunMode runMode, Long testRunId, String source,
+                                                String sourceText, String name, String nameText, String message )
     {
-        return new SimpleReportEntry( source, sourceText, name, nameText, message );
+        return new SimpleReportEntry( runMode, testRunId, source, sourceText, name, nameText, message );
     }
 
-    public static SimpleReportEntry ignored( String source, String sourceText, String name, String nameText,
-                                             String message )
+    public static SimpleReportEntry ignored( RunMode runMode, Long testRunId, String source,
+                                             String sourceText, String name, String nameText, String message )
     {
-        return new SimpleReportEntry( source, sourceText, name, nameText, message );
+        return new SimpleReportEntry( runMode, testRunId, source, sourceText, name, nameText, message );
     }
 
-    public static SimpleReportEntry withException( String source, String sourceText, String name, String nameText,
+    public static SimpleReportEntry withException( RunMode runMode, Long testRunId, String source,
+                                                   String sourceText, String name, String nameText,
                                                    StackTraceWriter stackTraceWriter )
     {
-        return new SimpleReportEntry( source, sourceText, name, nameText, stackTraceWriter );
+        return new SimpleReportEntry( runMode, testRunId, source, sourceText, name, nameText, stackTraceWriter );
     }
 
     private static String safeGetMessage( StackTraceWriter stackTraceWriter )
@@ -185,9 +205,10 @@ public class SimpleReportEntry
     @Override
     public String toString()
     {
-        return "ReportEntry{" + "source='" + source + "', sourceText='" + sourceText
-                + "', name='" + name + "', nameText='" + nameText + "', stackTraceWriter='"
-                + stackTraceWriter + "', elapsed='" + elapsed + "', message='" + message + "'}";
+        return "ReportEntry{" + "runMode='" + runMode + "', testRunId='" + testRunId
+            + "', source='" + source + "', sourceText='" + sourceText
+            + "', name='" + name + "', nameText='" + nameText + "', stackTraceWriter='" + stackTraceWriter
+            + "', elapsed='" + elapsed + "', message='" + message + "'}";
     }
 
     @Override
@@ -209,7 +230,8 @@ public class SimpleReportEntry
         }
 
         SimpleReportEntry that = (SimpleReportEntry) o;
-        return isSourceEqual( that ) && isSourceTextEqual( that )
+        return isRunModeEqual( that ) && isTestRunIdEqual( that )
+                && isSourceEqual( that ) && isSourceTextEqual( that )
                 && isNameEqual( that ) && isNameTextEqual( that )
                 && isStackEqual( that )
                 && isElapsedTimeEqual( that )
@@ -220,7 +242,9 @@ public class SimpleReportEntry
     @Override
     public int hashCode()
     {
-        int result = Objects.hashCode( getSourceName() );
+        int result = Objects.hashCode( getRunMode() );
+        result = 31 * result + Objects.hashCode( getTestRunId() );
+        result = 31 * result + Objects.hashCode( getSourceName() );
         result = 31 * result + Objects.hashCode( getSourceText() );
         result = 31 * result + Objects.hashCode( getName() );
         result = 31 * result + Objects.hashCode( getNameText() );
@@ -244,11 +268,36 @@ public class SimpleReportEntry
     }
 
     @Override
+    @Nonnull
+    public final RunMode getRunMode()
+    {
+        return runMode;
+    }
+
+    @Override
+    @Nonnegative
+    @Nullable
+    public final Long getTestRunId()
+    {
+        return testRunId;
+    }
+
+    @Override
     public Map<String, String> getSystemProperties()
     {
         return systemProperties;
     }
 
+    private boolean isRunModeEqual( SimpleReportEntry en )
+    {
+        return Objects.equals( getRunMode(), en.getRunMode() );
+    }
+
+    private boolean isTestRunIdEqual( SimpleReportEntry en )
+    {
+        return Objects.equals( getTestRunId(), en.getTestRunId() );
+    }
+
     private boolean isElapsedTimeEqual( SimpleReportEntry en )
     {
         return Objects.equals( getElapsed(), en.getElapsed() );
diff --git a/surefire-api/src/test/java/org/apache/maven/surefire/api/booter/ForkingRunListenerTest.java b/surefire-api/src/test/java/org/apache/maven/surefire/api/booter/ForkingRunListenerTest.java
index 25c479b..ef36fe9 100644
--- a/surefire-api/src/test/java/org/apache/maven/surefire/api/booter/ForkingRunListenerTest.java
+++ b/surefire-api/src/test/java/org/apache/maven/surefire/api/booter/ForkingRunListenerTest.java
@@ -20,8 +20,10 @@ package org.apache.maven.surefire.api.booter;
  */
 
 import junit.framework.TestCase;
+import org.apache.maven.surefire.api.report.RunListenerContext;
 import org.mockito.ArgumentCaptor;
 
+import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
 import static org.fest.assertions.Assertions.assertThat;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doNothing;
@@ -41,7 +43,8 @@ public class ForkingRunListenerTest
         MasterProcessChannelEncoder encoder = mock( MasterProcessChannelEncoder.class );
         ArgumentCaptor<String> argument1 = ArgumentCaptor.forClass( String.class );
         doNothing().when( encoder ).consoleInfoLog( anyString() );
-        ForkingRunListener forkingRunListener = new ForkingRunListener( encoder, true );
+        RunListenerContext ctx = new RunListenerContext( NORMAL_RUN );
+        ForkingRunListener forkingRunListener = new ForkingRunListener( ctx, encoder, true );
         forkingRunListener.info( new String( new byte[]{ (byte) 'A' } ) );
         forkingRunListener.info( new String( new byte[]{ } ) );
         verify( encoder, times( 2 ) ).consoleInfoLog( argument1.capture() );
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java
index d170237..bfa0a06 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java
@@ -32,6 +32,7 @@ import org.apache.maven.surefire.api.provider.CommandListener;
 import org.apache.maven.surefire.api.provider.ProviderParameters;
 import org.apache.maven.surefire.api.provider.SurefireProvider;
 import org.apache.maven.surefire.api.report.LegacyPojoStackTraceWriter;
+import org.apache.maven.surefire.api.report.RunListenerContext;
 import org.apache.maven.surefire.api.report.StackTraceWriter;
 import org.apache.maven.surefire.api.testset.TestSetFailedException;
 import org.apache.maven.surefire.booter.spi.LegacyMasterProcessChannelProcessorFactory;
@@ -63,6 +64,7 @@ import static java.util.ServiceLoader.load;
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.concurrent.TimeUnit.SECONDS;
 import static org.apache.maven.surefire.api.cli.CommandLineOption.LOGGING_LEVEL_DEBUG;
+import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
 import static org.apache.maven.surefire.api.util.ReflectionUtils.instantiateOneArg;
 import static org.apache.maven.surefire.api.util.internal.DaemonThreadFactory.newDaemonThreadFactory;
 import static org.apache.maven.surefire.api.util.internal.StringUtils.NL;
@@ -138,7 +140,7 @@ public final class ForkedBooter
         flushEventChannelOnExit();
 
         forkingReporterFactory = createForkingReporterFactory();
-        ConsoleLogger logger = (ConsoleLogger) forkingReporterFactory.createReporter();
+        ConsoleLogger logger = forkingReporterFactory.getConsoleLogger();
         commandReader = new CommandReader( decoder, providerConfiguration.getShutdown(), logger );
 
         pingScheduler = isDebugging ? null : listenToShutdownCommands( booterDeserializer.getPluginPid(), logger );
@@ -438,8 +440,9 @@ public final class ForkedBooter
 
     private ForkingReporterFactory createForkingReporterFactory()
     {
-        final boolean trimStackTrace = providerConfiguration.getReporterConfiguration().isTrimStackTrace();
-        return new ForkingReporterFactory( trimStackTrace, eventChannel );
+        RunListenerContext ctx = new RunListenerContext( NORMAL_RUN );
+        boolean trimStackTrace = providerConfiguration.getReporterConfiguration().isTrimStackTrace();
+        return new ForkingReporterFactory( ctx, trimStackTrace, eventChannel );
     }
 
     private synchronized ScheduledThreadPoolExecutor getJvmTerminator()
@@ -485,7 +488,6 @@ public final class ForkedBooter
         bpf.setCommandReader( commandReader );
         bpf.setTestRequest( providerConfiguration.getTestSuiteDefinition() );
         bpf.setReporterConfiguration( providerConfiguration.getReporterConfiguration() );
-        bpf.setForkedChannelEncoder( eventChannel );
         ClassLoader classLoader = currentThread().getContextClassLoader();
         bpf.setClassLoaders( classLoader );
         bpf.setTestArtifactInfo( providerConfiguration.getTestArtifact() );
diff --git a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SurefireReflectorTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SurefireReflectorTest.java
index 88fd583..5e5ec00 100644
--- a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SurefireReflectorTest.java
+++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SurefireReflectorTest.java
@@ -20,12 +20,14 @@ package org.apache.maven.surefire.booter;
  */
 
 import junit.framework.TestCase;
+import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
 import org.apache.maven.surefire.api.booter.BaseProviderFactory;
 import org.apache.maven.surefire.api.provider.ProviderParameters;
 import org.apache.maven.surefire.api.provider.SurefireProvider;
+import org.apache.maven.surefire.api.report.AbstractRunListener;
+import org.apache.maven.surefire.api.report.ConsoleStream;
 import org.apache.maven.surefire.api.report.ReporterConfiguration;
 import org.apache.maven.surefire.api.report.ReporterFactory;
-import org.apache.maven.surefire.api.report.RunListener;
 import org.apache.maven.surefire.api.suite.RunResult;
 import org.apache.maven.surefire.api.testset.DirectoryScannerParameters;
 import org.apache.maven.surefire.api.testset.RunOrderParameters;
@@ -55,7 +57,19 @@ public class SurefireReflectorTest
         ReporterFactory factory = new ReporterFactory()
         {
             @Override
-            public RunListener createReporter()
+            public AbstractRunListener getRunListener()
+            {
+                return null;
+            }
+
+            @Override
+            public ConsoleLogger getConsoleLogger()
+            {
+                return null;
+            }
+
+            @Override
+            public ConsoleStream getConsoleStream()
             {
                 return null;
             }
@@ -255,7 +269,19 @@ public class SurefireReflectorTest
         ReporterFactory reporterFactory = new ReporterFactory()
         {
             @Override
-            public RunListener createReporter()
+            public AbstractRunListener getRunListener()
+            {
+                return null;
+            }
+
+            @Override
+            public ConsoleLogger getConsoleLogger()
+            {
+                return null;
+            }
+
+            @Override
+            public ConsoleStream getConsoleStream()
             {
                 return null;
             }
@@ -279,7 +305,19 @@ public class SurefireReflectorTest
         ReporterFactory reporterFactory = new ReporterFactory()
         {
             @Override
-            public RunListener createReporter()
+            public AbstractRunListener getRunListener()
+            {
+                return null;
+            }
+
+            @Override
+            public ConsoleLogger getConsoleLogger()
+            {
+                return null;
+            }
+
+            @Override
+            public ConsoleStream getConsoleStream()
             {
                 return null;
             }
diff --git a/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4RunListener.java b/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4RunListener.java
index 7f4e97e..34e15ab 100644
--- a/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4RunListener.java
+++ b/surefire-providers/common-junit4/src/main/java/org/apache/maven/surefire/common/junit4/JUnit4RunListener.java
@@ -19,8 +19,11 @@ package org.apache.maven.surefire.common.junit4;
  * under the License.
  */
 
+import org.apache.maven.surefire.api.report.AbstractRunListener;
 import org.apache.maven.surefire.api.report.ReportEntry;
 import org.apache.maven.surefire.api.report.RunListener;
+import org.apache.maven.surefire.api.report.RunListenerContext;
+import org.apache.maven.surefire.api.report.RunMode;
 import org.apache.maven.surefire.api.report.SimpleReportEntry;
 import org.apache.maven.surefire.api.report.StackTraceWriter;
 import org.apache.maven.surefire.api.testset.TestSetFailedException;
@@ -29,12 +32,14 @@ import org.junit.runner.Description;
 import org.junit.runner.Result;
 import org.junit.runner.notification.Failure;
 
-import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.isFailureInsideJUnitItself;
-import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.toClassMethod;
-import static org.apache.maven.surefire.common.junit4.JUnit4Reflector.getAnnotatedIgnoreValue;
+import java.util.concurrent.atomic.AtomicLong;
+
 import static org.apache.maven.surefire.api.report.SimpleReportEntry.assumption;
 import static org.apache.maven.surefire.api.report.SimpleReportEntry.ignored;
 import static org.apache.maven.surefire.api.report.SimpleReportEntry.withException;
+import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.isFailureInsideJUnitItself;
+import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.toClassMethod;
+import static org.apache.maven.surefire.common.junit4.JUnit4Reflector.getAnnotatedIgnoreValue;
 
 /**
  * RunListener for JUnit4, delegates to our own RunListener
@@ -43,7 +48,7 @@ import static org.apache.maven.surefire.api.report.SimpleReportEntry.withExcepti
 public class JUnit4RunListener
     extends org.junit.runner.notification.RunListener
 {
-    protected final RunListener reporter;
+    protected final AbstractRunListener reporter;
 
     /**
      * This flag is set after a failure has occurred so that a {@link RunListener#testSucceeded} event is not fired.
@@ -52,13 +57,14 @@ public class JUnit4RunListener
      * event-- even if there was a failure.
      */
     private final ThreadLocal<Boolean> failureFlag = new InheritableThreadLocal<>();
+    private final AtomicLong testIdCounter = new AtomicLong();
 
     /**
      * Constructor.
      *
      * @param reporter the reporter to log testing events to
      */
-    public JUnit4RunListener( RunListener reporter )
+    public JUnit4RunListener( AbstractRunListener reporter )
     {
         this.reporter = reporter;
     }
@@ -76,7 +82,10 @@ public class JUnit4RunListener
     {
         String reason = getAnnotatedIgnoreValue( description );
         ClassMethod classMethod = toClassMethod( description );
-        reporter.testSkipped( ignored( classMethod.getClazz(), null, classMethod.getMethod(), null, reason ) );
+        RunMode runMode = reporter.getContext().getRunMode();
+        long testId = reporter.getContext().getCurrentTestId();
+        reporter.testSkipped( ignored( runMode, testId, classMethod.getClazz(), null,
+            classMethod.getMethod(), null, reason ) );
     }
 
     /**
@@ -112,8 +121,10 @@ public class JUnit4RunListener
         {
             StackTraceWriter stackTrace = createStackTraceWriter( failure );
             ClassMethod classMethod = toClassMethod( failure.getDescription() );
-            ReportEntry report =
-                    withException( classMethod.getClazz(), null, classMethod.getMethod(), null, stackTrace );
+            RunMode runMode = reporter.getContext().getRunMode();
+            long testId = reporter.getContext().getCurrentTestId();
+            ReportEntry report = withException( runMode, testId, classMethod.getClazz(), null,
+                classMethod.getMethod(), null, stackTrace );
 
             if ( failure.getException() instanceof AssertionError )
             {
@@ -136,8 +147,10 @@ public class JUnit4RunListener
         {
             Description desc = failure.getDescription();
             ClassMethod classMethod = toClassMethod( desc );
-            ReportEntry report = assumption( classMethod.getClazz(), null, classMethod.getMethod(), null,
-                    failure.getMessage() );
+            RunMode runMode = reporter.getContext().getRunMode();
+            long testId = reporter.getContext().getCurrentTestId();
+            ReportEntry report = assumption( runMode, testId, classMethod.getClazz(), null,
+                classMethod.getMethod(), null, failure.getMessage() );
             reporter.testAssumptionFailure( report );
         }
         finally
@@ -178,7 +191,22 @@ public class JUnit4RunListener
     protected SimpleReportEntry createReportEntry( Description description )
     {
         ClassMethod classMethod = toClassMethod( description );
-        return new SimpleReportEntry( classMethod.getClazz(), null, classMethod.getMethod(), null );
+        RunMode runMode = reporter.getContext().getRunMode();
+        Long testId = currentTestId();
+        return new SimpleReportEntry( runMode, testId, classMethod.getClazz(), null,
+            classMethod.getMethod(), null );
+    }
+
+    protected final Long currentTestId()
+    {
+        RunListenerContext ctx = reporter.getContext();
+        Long testId = ctx.getCurrentTestId();
+        if ( testId == null )
+        {
+            testId = testIdCounter.incrementAndGet();
+            ctx.setCurrentTestId( testId );
+        }
+        return testId;
     }
 
     public static void rethrowAnyTestMechanismFailures( Result run )
diff --git a/surefire-providers/common-junit4/src/test/java/org/apache/maven/surefire/common/junit4/MockReporter.java b/surefire-providers/common-junit4/src/test/java/org/apache/maven/surefire/common/junit4/MockReporter.java
index 39947fc..1d7162b 100644
--- a/surefire-providers/common-junit4/src/test/java/org/apache/maven/surefire/common/junit4/MockReporter.java
+++ b/surefire-providers/common-junit4/src/test/java/org/apache/maven/surefire/common/junit4/MockReporter.java
@@ -19,8 +19,9 @@ package org.apache.maven.surefire.common.junit4;
  * under the License.
  */
 
+import org.apache.maven.surefire.api.report.AbstractRunListener;
 import org.apache.maven.surefire.api.report.ReportEntry;
-import org.apache.maven.surefire.api.report.RunListener;
+import org.apache.maven.surefire.api.report.RunListenerContext;
 import org.apache.maven.surefire.api.report.RunMode;
 import org.apache.maven.surefire.api.report.TestSetReportEntry;
 
@@ -32,7 +33,7 @@ import java.util.concurrent.atomic.AtomicInteger;
  * Internal tests use only.
  */
 final class MockReporter
-    implements RunListener
+    extends AbstractRunListener
 {
     private final List<String> events = new ArrayList<>();
 
@@ -56,6 +57,7 @@ final class MockReporter
 
     MockReporter()
     {
+        super( new RunListenerContext( RunMode.NORMAL_RUN ) );
     }
 
     @Override
diff --git a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java
index 5bd3ee4..2abad7f 100644
--- a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java
+++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProvider.java
@@ -113,7 +113,7 @@ public class JUnitPlatformProvider
         final RunResult runResult;
         try
         {
-            RunListener runListener = reporterFactory.createReporter();
+            RunListener runListener = reporterFactory.getRunListener();
             startCapture( ( ConsoleOutputReceiver ) runListener );
             if ( forkTestSet instanceof TestsToRun )
             {
diff --git a/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTest.java b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTest.java
index 5064285..041996a 100644
--- a/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTest.java
+++ b/surefire-providers/surefire-junit-platform/src/test/java/org/apache/maven/surefire/junitplatform/JUnitPlatformProviderTest.java
@@ -929,7 +929,7 @@ public class JUnitPlatformProviderTest
         when( runOrderCalculator.orderTestClasses( any() ) ).thenReturn( testsToRun );
 
         ReporterFactory reporterFactory = mock( ReporterFactory.class );
-        when( reporterFactory.createReporter() ).thenReturn( runListener );
+        when( reporterFactory.getRunListener() ).thenReturn( runListener );
 
         TestRequest testRequest = mock( TestRequest.class );
         when( testRequest.getTestListResolver() ).thenReturn( testListResolver );
@@ -1111,7 +1111,7 @@ public class JUnitPlatformProviderTest
         TestsToRun testsToRun = newTestsToRun( Sub1Tests.class, Sub2Tests.class );
 
         invokeProvider( jUnitPlatformProvider, testsToRun );
-        RunListener reporter = providerParameters.getReporterFactory().createReporter();
+        RunListener reporter = providerParameters.getReporterFactory().getRunListener();
 
         ArgumentCaptor<ReportEntry> reportEntryArgumentCaptor =
                         ArgumentCaptor.forClass( ReportEntry.class );
diff --git a/surefire-providers/surefire-junit3/src/main/java/org/apache/maven/surefire/junit/JUnit3Provider.java b/surefire-providers/surefire-junit3/src/main/java/org/apache/maven/surefire/junit/JUnit3Provider.java
index f7c2c0c..bf30eec 100644
--- a/surefire-providers/surefire-junit3/src/main/java/org/apache/maven/surefire/junit/JUnit3Provider.java
+++ b/surefire-providers/surefire-junit3/src/main/java/org/apache/maven/surefire/junit/JUnit3Provider.java
@@ -97,7 +97,7 @@ public class JUnit3Provider
         RunResult runResult;
         try
         {
-            final RunListener reporter = reporterFactory.createReporter();
+            final RunListener reporter = reporterFactory.getRunListener();
             ConsoleOutputCapture.startCapture( (ConsoleOutputReceiver) reporter );
             Map<String, String> systemProperties = systemProps();
             String smClassName = System.getProperty( "surefire.security.manager" );
diff --git a/surefire-providers/surefire-junit3/src/main/java/org/apache/maven/surefire/junit/TestListenerInvocationHandler.java b/surefire-providers/surefire-junit3/src/main/java/org/apache/maven/surefire/junit/TestListenerInvocationHandler.java
index 219e064..12a7e3f 100644
--- a/surefire-providers/surefire-junit3/src/main/java/org/apache/maven/surefire/junit/TestListenerInvocationHandler.java
+++ b/surefire-providers/surefire-junit3/src/main/java/org/apache/maven/surefire/junit/TestListenerInvocationHandler.java
@@ -52,17 +52,17 @@ public class TestListenerInvocationHandler
 
     private final Set<FailedTest> failedTestsSet = new HashSet<>();
 
-    private RunListener reporter;
+    private final RunListener reporter;
 
-    private static final Class[] EMPTY_CLASS_ARRAY = { };
+    private static final Class<?>[] EMPTY_CLASS_ARRAY = { };
 
     private static final Object[] EMPTY_STRING_ARRAY = { };
 
     private static class FailedTest
     {
-        private Object testThatFailed;
+        private final Object testThatFailed;
 
-        private Thread threadOnWhichTestFailed;
+        private final Thread threadOnWhichTestFailed;
 
         FailedTest( Object testThatFailed, Thread threadOnWhichTestFailed )
         {
diff --git a/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4Provider.java b/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4Provider.java
index 3f4b095..458d85a 100644
--- a/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4Provider.java
+++ b/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4Provider.java
@@ -22,6 +22,7 @@ package org.apache.maven.surefire.junit4;
 import org.apache.maven.surefire.api.booter.Command;
 import org.apache.maven.surefire.api.provider.CommandChainReader;
 import org.apache.maven.surefire.api.provider.CommandListener;
+import org.apache.maven.surefire.api.report.AbstractRunListener;
 import org.apache.maven.surefire.common.junit4.JUnit4RunListener;
 import org.apache.maven.surefire.common.junit4.JUnit4TestChecker;
 import org.apache.maven.surefire.common.junit4.JUnitTestFailureListener;
@@ -121,7 +122,7 @@ public class JUnit4Provider
         RunResult runResult;
         try
         {
-            RunListener reporter = reporterFactory.createReporter();
+            AbstractRunListener reporter = reporterFactory.getRunListener();
 
             startCapture( (ConsoleOutputReceiver) reporter );
             // startCapture() called in prior to setTestsToRun()
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ClassesParallelRunListener.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ClassesParallelRunListener.java
index 73a8682..00012e2 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ClassesParallelRunListener.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ClassesParallelRunListener.java
@@ -23,6 +23,7 @@ import java.util.Map;
 
 import org.apache.maven.surefire.api.report.ConsoleStream;
 import org.apache.maven.surefire.api.report.ReporterFactory;
+import org.apache.maven.surefire.api.report.RunListenerContext;
 import org.apache.maven.surefire.api.testset.TestSetFailedException;
 import org.junit.runner.notification.RunListener.ThreadSafe;
 
@@ -33,11 +34,13 @@ import org.junit.runner.notification.RunListener.ThreadSafe;
 public class ClassesParallelRunListener
     extends ConcurrentRunListener
 {
-    public ClassesParallelRunListener( Map<String, TestSet> classMethodCounts, ReporterFactory reporterFactory,
+    public ClassesParallelRunListener( RunListenerContext ctx,
+                                       Map<String, TestSet> classMethodCounts,
+                                       ReporterFactory reporterFactory,
                                        ConsoleStream consoleStream )
         throws TestSetFailedException
     {
-        super( reporterFactory, consoleStream, false, classMethodCounts );
+        super( ctx, reporterFactory, consoleStream, false, classMethodCounts );
     }
 
     @Override
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ConcurrentRunListener.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ConcurrentRunListener.java
index ce8ad88..1397ed0 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ConcurrentRunListener.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ConcurrentRunListener.java
@@ -20,11 +20,14 @@ package org.apache.maven.surefire.junitcore;
  */
 
 import java.util.Map;
+
+import org.apache.maven.surefire.api.report.AbstractRunListener;
 import org.apache.maven.surefire.api.report.ConsoleOutputReceiver;
 import org.apache.maven.surefire.api.report.ConsoleStream;
 import org.apache.maven.surefire.api.report.ReportEntry;
 import org.apache.maven.surefire.api.report.ReporterFactory;
 import org.apache.maven.surefire.api.report.RunListener;
+import org.apache.maven.surefire.api.report.RunListenerContext;
 import org.apache.maven.surefire.api.report.RunMode;
 import org.apache.maven.surefire.api.report.StackTraceWriter;
 import org.apache.maven.surefire.api.report.TestSetReportEntry;
@@ -43,8 +46,9 @@ import static org.apache.maven.surefire.junitcore.TestMethod.getThreadTestMethod
  * @see org.apache.maven.surefire.junitcore.JUnitCoreRunListener for details about regular junit run listening
  * @author Kristian Rosenvold
  */
-public abstract class ConcurrentRunListener
-    implements RunListener, ConsoleOutputReceiver
+abstract class ConcurrentRunListener
+    extends AbstractRunListener
+    implements ConsoleOutputReceiver
 {
     private final Map<String, TestSet> classMethodCounts;
 
@@ -54,10 +58,13 @@ public abstract class ConcurrentRunListener
 
     private final ConsoleStream consoleStream;
 
-    ConcurrentRunListener( final ReporterFactory reporterFactory, ConsoleStream consoleStream,
+    ConcurrentRunListener( RunListenerContext ctx,
+                           final ReporterFactory reporterFactory,
+                           ConsoleStream consoleStream,
                            boolean reportImmediately, Map<String, TestSet> classMethodCounts )
         throws TestSetFailedException
     {
+        super( ctx );
         this.reportImmediately = reportImmediately;
         this.classMethodCounts = classMethodCounts;
         this.consoleStream = consoleStream;
@@ -66,7 +73,7 @@ public abstract class ConcurrentRunListener
             @Override
             protected RunListener initialValue()
             {
-                return reporterFactory.createReporter();
+                return reporterFactory.getRunListener();
             }
         };
     }
@@ -206,15 +213,17 @@ public abstract class ConcurrentRunListener
         return reporterManagerThreadLocal.get();
     }
 
-    public static ConcurrentRunListener createInstance( Map<String, TestSet> classMethodCounts,
-                                                            ReporterFactory reporterFactory,
-                                                            boolean parallelClasses, boolean parallelBoth,
-                                                            ConsoleStream consoleStream )
+    public static ConcurrentRunListener createInstance( RunListenerContext ctx,
+                                                        Map<String, TestSet> classMethodCounts,
+                                                        ReporterFactory reporterFactory,
+                                                        boolean parallelClasses,
+                                                        boolean parallelBoth,
+                                                        ConsoleStream consoleStream )
         throws TestSetFailedException
     {
         return parallelClasses
-            ? new ClassesParallelRunListener( classMethodCounts, reporterFactory, consoleStream )
-            : new MethodsParallelRunListener( classMethodCounts, reporterFactory, !parallelBoth, consoleStream );
+            ? new ClassesParallelRunListener( ctx, classMethodCounts, reporterFactory, consoleStream )
+            : new MethodsParallelRunListener( ctx, classMethodCounts, reporterFactory, !parallelBoth, consoleStream );
     }
 
 
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java
index 6877b00..7902603 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java
@@ -20,18 +20,13 @@ package org.apache.maven.surefire.junitcore;
  */
 
 import org.apache.maven.surefire.api.booter.Command;
+import org.apache.maven.surefire.api.provider.AbstractProvider;
 import org.apache.maven.surefire.api.provider.CommandChainReader;
 import org.apache.maven.surefire.api.provider.CommandListener;
-import org.apache.maven.surefire.common.junit4.JUnit4RunListener;
-import org.apache.maven.surefire.common.junit4.JUnitTestFailureListener;
-import org.apache.maven.surefire.common.junit4.Notifier;
-import org.apache.maven.surefire.common.junit48.FilterFactory;
-import org.apache.maven.surefire.common.junit48.JUnit48Reflector;
-import org.apache.maven.surefire.common.junit48.JUnit48TestChecker;
-import org.apache.maven.surefire.api.provider.AbstractProvider;
 import org.apache.maven.surefire.api.provider.ProviderParameters;
 import org.apache.maven.surefire.api.report.ConsoleStream;
 import org.apache.maven.surefire.api.report.ReporterFactory;
+import org.apache.maven.surefire.api.report.RunListenerContext;
 import org.apache.maven.surefire.api.suite.RunResult;
 import org.apache.maven.surefire.api.testset.TestListResolver;
 import org.apache.maven.surefire.api.testset.TestSetFailedException;
@@ -39,6 +34,12 @@ import org.apache.maven.surefire.api.util.RunOrderCalculator;
 import org.apache.maven.surefire.api.util.ScanResult;
 import org.apache.maven.surefire.api.util.ScannerFilter;
 import org.apache.maven.surefire.api.util.TestsToRun;
+import org.apache.maven.surefire.common.junit4.JUnit4RunListener;
+import org.apache.maven.surefire.common.junit4.JUnitTestFailureListener;
+import org.apache.maven.surefire.common.junit4.Notifier;
+import org.apache.maven.surefire.common.junit48.FilterFactory;
+import org.apache.maven.surefire.common.junit48.JUnit48Reflector;
+import org.apache.maven.surefire.common.junit48.JUnit48TestChecker;
 import org.junit.runner.Description;
 import org.junit.runner.manipulation.Filter;
 
@@ -46,13 +47,15 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
+import static org.apache.maven.surefire.api.report.ConsoleOutputCapture.startCapture;
+import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
+import static org.apache.maven.surefire.api.report.RunMode.RERUN_TEST_AFTER_FAILURE;
+import static org.apache.maven.surefire.api.testset.TestListResolver.optionallyWildcardFilter;
+import static org.apache.maven.surefire.api.util.TestsToRun.fromClass;
 import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.generateFailingTestDescriptions;
 import static org.apache.maven.surefire.common.junit4.JUnit4RunListenerFactory.createCustomListeners;
 import static org.apache.maven.surefire.common.junit4.Notifier.pureNotifier;
 import static org.apache.maven.surefire.junitcore.ConcurrentRunListener.createInstance;
-import static org.apache.maven.surefire.api.report.ConsoleOutputCapture.startCapture;
-import static org.apache.maven.surefire.api.testset.TestListResolver.optionallyWildcardFilter;
-import static org.apache.maven.surefire.api.util.TestsToRun.fromClass;
 
 /**
  * @author Kristian Rosenvold
@@ -119,10 +122,12 @@ public class JUnitCoreProvider
     {
         final ReporterFactory reporterFactory = providerParameters.getReporterFactory();
 
-        final ConsoleStream consoleStream = providerParameters.getConsoleLogger();
+        final ConsoleStream consoleStream = reporterFactory.getConsoleStream();
+
+        RunListenerContext ctx = new RunListenerContext( NORMAL_RUN );
 
         Notifier notifier =
-            new Notifier( createRunListener( reporterFactory, consoleStream ), getSkipAfterFailureCount() );
+            new Notifier( createRunListener( ctx, reporterFactory, consoleStream ), getSkipAfterFailureCount() );
         // startCapture() called in createRunListener() in prior to setTestsToRun()
 
         Filter filter = jUnit48Reflector.isJUnit48Available() ? createJUnit48Filter() : null;
@@ -160,6 +165,7 @@ public class JUnitCoreProvider
             // Rerun failing tests if rerunFailingTestsCount is larger than 0
             if ( isRerunFailingTests() )
             {
+                ctx.setRunMode( RERUN_TEST_AFTER_FAILURE );
                 Notifier rerunNotifier = pureNotifier();
                 notifier.copyListenersTo( rerunNotifier );
                 JUnitCoreWrapper rerunCore = new JUnitCoreWrapper( rerunNotifier, jUnitCoreParameters, consoleStream );
@@ -238,12 +244,13 @@ public class JUnitCoreProvider
         } );
     }
 
-    private JUnit4RunListener createRunListener( ReporterFactory reporterFactory, ConsoleStream consoleStream )
+    private JUnit4RunListener createRunListener( RunListenerContext ctx, ReporterFactory reporterFactory,
+                                                 ConsoleStream consoleStream )
         throws TestSetFailedException
     {
         if ( isSingleThreaded() )
         {
-            NonConcurrentRunListener rm = new NonConcurrentRunListener( reporterFactory.createReporter() );
+            NonConcurrentRunListener rm = new NonConcurrentRunListener( reporterFactory.getRunListener() );
             startCapture( rm );
             return rm;
         }
@@ -251,7 +258,7 @@ public class JUnitCoreProvider
         {
             final Map<String, TestSet> testSetMap = new ConcurrentHashMap<>();
 
-            ConcurrentRunListener listener = createInstance( testSetMap, reporterFactory, isParallelTypes(),
+            ConcurrentRunListener listener = createInstance( ctx, testSetMap, reporterFactory, isParallelTypes(),
                                                              isParallelMethodsAndTypes(), consoleStream );
             startCapture( listener );
 
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreRunListener.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreRunListener.java
index 37f3759..687cde5 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreRunListener.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreRunListener.java
@@ -19,9 +19,9 @@ package org.apache.maven.surefire.junitcore;
  * under the License.
  */
 
+import org.apache.maven.surefire.api.report.AbstractRunListener;
 import org.apache.maven.surefire.common.junit4.JUnit4RunListener;
 import org.apache.maven.surefire.common.junit4.JUnit4StackTraceWriter;
-import org.apache.maven.surefire.api.report.RunListener;
 import org.apache.maven.surefire.api.report.StackTraceWriter;
 import org.junit.runner.Description;
 import org.junit.runner.Result;
@@ -49,7 +49,7 @@ public class JUnitCoreRunListener
      * @param reporter          the report manager to log testing events to
      * @param classMethodCounts A map of methods
      */
-    public JUnitCoreRunListener( RunListener reporter, Map<String, TestSet> classMethodCounts )
+    public JUnitCoreRunListener( AbstractRunListener reporter, Map<String, TestSet> classMethodCounts )
     {
         super( reporter );
         this.classMethodCounts = classMethodCounts;
@@ -62,7 +62,6 @@ public class JUnitCoreRunListener
      */
     @Override
     public void testRunStarted( Description description )
-        throws Exception
     {
         fillTestCountMap( description );
         reporter.testSetStarting( null ); // Not entirely meaningful as we can see
@@ -70,7 +69,6 @@ public class JUnitCoreRunListener
 
     @Override
     public void testRunFinished( Result result )
-        throws Exception
     {
         try
         {
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/MethodsParallelRunListener.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/MethodsParallelRunListener.java
index 4ca3603..a52feb1 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/MethodsParallelRunListener.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/MethodsParallelRunListener.java
@@ -23,6 +23,7 @@ import java.util.Map;
 
 import org.apache.maven.surefire.api.report.ConsoleStream;
 import org.apache.maven.surefire.api.report.ReporterFactory;
+import org.apache.maven.surefire.api.report.RunListenerContext;
 import org.apache.maven.surefire.api.testset.TestSetFailedException;
 import org.junit.runner.notification.RunListener.ThreadSafe;
 
@@ -37,11 +38,13 @@ public class MethodsParallelRunListener
 
     private final Object lock = new Object();
 
-    public MethodsParallelRunListener( Map<String, TestSet> classMethodCounts, ReporterFactory reporterFactory,
+    public MethodsParallelRunListener( RunListenerContext ctx,
+                                       Map<String, TestSet> classMethodCounts,
+                                       ReporterFactory reporterFactory,
                                        boolean reportImmediately, ConsoleStream consoleStream )
         throws TestSetFailedException
     {
-        super( reporterFactory, consoleStream, reportImmediately, classMethodCounts );
+        super( ctx, reporterFactory, consoleStream, reportImmediately, classMethodCounts );
     }
 
     @Override
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/NonConcurrentRunListener.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/NonConcurrentRunListener.java
index 262a4ee..fa5682c 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/NonConcurrentRunListener.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/NonConcurrentRunListener.java
@@ -19,13 +19,13 @@ package org.apache.maven.surefire.junitcore;
  * under the License.
  */
 
+import org.apache.maven.surefire.api.report.AbstractRunListener;
+import org.apache.maven.surefire.api.report.RunMode;
 import org.apache.maven.surefire.api.util.internal.ClassMethod;
 import org.apache.maven.surefire.common.junit4.JUnit4RunListener;
 import org.apache.maven.surefire.api.report.ConsoleOutputReceiver;
-import org.apache.maven.surefire.api.report.RunListener;
 import org.apache.maven.surefire.api.report.SimpleReportEntry;
 import org.apache.maven.surefire.api.report.TestSetReportEntry;
-import org.apache.maven.surefire.api.testset.TestSetFailedException;
 import org.junit.runner.Description;
 import org.junit.runner.Result;
 import org.junit.runner.notification.Failure;
@@ -49,8 +49,7 @@ public class NonConcurrentRunListener
 
     private Description lastFinishedDescription;
 
-    public NonConcurrentRunListener( RunListener reporter )
-        throws TestSetFailedException
+    public NonConcurrentRunListener( AbstractRunListener reporter )
     {
         super( reporter );
     }
@@ -65,13 +64,17 @@ public class NonConcurrentRunListener
     protected SimpleReportEntry createReportEntry( Description description )
     {
         ClassMethod classMethod = toClassMethod( description );
-        return new SimpleReportEntry( classMethod.getClazz(), null, classMethod.getMethod(), null );
+        RunMode runMode = reporter.getContext().getRunMode();
+        long testId = currentTestId();
+        return new SimpleReportEntry( runMode, testId, classMethod.getClazz(), null, classMethod.getMethod(), null );
     }
 
     private TestSetReportEntry createReportEntryForTestSet( Description description, Map<String, String> systemProps )
     {
         ClassMethod classMethod = toClassMethod( description );
-        return new SimpleReportEntry( classMethod.getClazz(), null, null, null, systemProps );
+        RunMode runMode = reporter.getContext().getRunMode();
+        long testId = currentTestId();
+        return new SimpleReportEntry( runMode, testId, classMethod.getClazz(), null, null, null, systemProps );
     }
 
     private TestSetReportEntry createTestSetReportEntryStarted( Description description )
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/ConcurrentRunListenerTest.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/ConcurrentRunListenerTest.java
index 8940b51..326e682 100644
--- a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/ConcurrentRunListenerTest.java
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/ConcurrentRunListenerTest.java
@@ -24,10 +24,11 @@ import java.io.PrintStream;
 import java.util.HashMap;
 import java.util.Map;
 import org.apache.maven.plugin.surefire.report.DefaultReporterFactory;
+import org.apache.maven.surefire.api.report.AbstractRunListener;
 import org.apache.maven.surefire.api.report.ConsoleStream;
-import org.apache.maven.surefire.api.report.DefaultDirectConsoleReporter;
 import org.apache.maven.surefire.api.report.ReporterFactory;
-import org.apache.maven.surefire.api.report.RunListener;
+import org.apache.maven.surefire.api.report.RunListenerContext;
+import org.apache.maven.surefire.api.report.RunMode;
 import org.apache.maven.surefire.report.RunStatistics;
 import org.apache.maven.surefire.api.testset.TestSetFailedException;
 
@@ -149,15 +150,17 @@ public class ConcurrentRunListenerTest
         DefaultReporterFactory reporterFactory = createReporterFactory();
         HashMap<String, TestSet> classMethodCounts = new HashMap<>();
         final ConsoleStream defaultConsoleReporter = new DefaultDirectConsoleReporter( System.out );
-        RunListener reporter =
-            new ClassesParallelRunListener( classMethodCounts, reporterFactory, defaultConsoleReporter );
+        RunListenerContext ctx = new RunListenerContext( RunMode.NORMAL_RUN );
+        AbstractRunListener reporter =
+            new ClassesParallelRunListener( ctx, classMethodCounts, reporterFactory, defaultConsoleReporter );
         JUnitCoreRunListener runListener = new JUnitCoreRunListener( reporter, classMethodCounts );
         RunStatistics result = runClasses( reporterFactory, runListener, classes );
         assertReporter( result, success, ignored, failure, "classes" );
         classMethodCounts.clear();
 
         reporterFactory = createReporterFactory();
-        reporter = new MethodsParallelRunListener( classMethodCounts, reporterFactory, true, defaultConsoleReporter );
+        reporter =
+            new MethodsParallelRunListener( ctx, classMethodCounts, reporterFactory, true, defaultConsoleReporter );
         runListener = new JUnitCoreRunListener( reporter, classMethodCounts );
         result = runClasses( reporterFactory, runListener, classes );
         assertReporter( result, success, ignored, failure, "methods" );
@@ -200,8 +203,9 @@ public class ConcurrentRunListenerTest
                                                                          Map<String, TestSet> testSetMap )
         throws TestSetFailedException
     {
+        RunListenerContext ctx = new RunListenerContext( RunMode.NORMAL_RUN );
         return new JUnitCoreRunListener(
-            new ClassesParallelRunListener( testSetMap, reporterFactory,
+            new ClassesParallelRunListener( ctx, testSetMap, reporterFactory,
                                                   new DefaultDirectConsoleReporter( System.out ) ), testSetMap );
     }
 
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/api/report/DefaultDirectConsoleReporter.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/DefaultDirectConsoleReporter.java
similarity index 92%
rename from surefire-api/src/main/java/org/apache/maven/surefire/api/report/DefaultDirectConsoleReporter.java
rename to surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/DefaultDirectConsoleReporter.java
index b3a4c1c..20292a2 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/api/report/DefaultDirectConsoleReporter.java
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/DefaultDirectConsoleReporter.java
@@ -1,4 +1,4 @@
-package org.apache.maven.surefire.api.report;
+package org.apache.maven.surefire.junitcore;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -19,6 +19,8 @@ package org.apache.maven.surefire.api.report;
  * under the License.
  */
 
+import org.apache.maven.surefire.api.report.ConsoleStream;
+
 import java.io.PrintStream;
 
 /**
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnitCoreTester.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnitCoreTester.java
index defc3a9..5c55591 100644
--- a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnitCoreTester.java
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnitCoreTester.java
@@ -26,9 +26,9 @@ import org.apache.maven.plugin.surefire.extensions.SurefireStatelessTestsetInfoR
 import org.apache.maven.plugin.surefire.log.api.NullConsoleLogger;
 import org.apache.maven.plugin.surefire.report.DefaultReporterFactory;
 import org.apache.maven.surefire.api.report.ConsoleOutputReceiver;
-import org.apache.maven.surefire.api.report.DefaultDirectConsoleReporter;
 import org.apache.maven.surefire.api.report.ReporterFactory;
 import org.apache.maven.surefire.api.report.RunListener;
+import org.apache.maven.surefire.api.report.RunListenerContext;
 import org.apache.maven.surefire.api.testset.TestSetFailedException;
 import org.junit.runner.Computer;
 import org.junit.runner.JUnitCore;
@@ -38,8 +38,9 @@ import java.io.File;
 import java.util.HashMap;
 import java.util.concurrent.ExecutionException;
 
-import static org.apache.maven.surefire.junitcore.ConcurrentRunListener.createInstance;
 import static org.apache.maven.surefire.api.report.ConsoleOutputCapture.startCapture;
+import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
+import static org.apache.maven.surefire.junitcore.ConcurrentRunListener.createInstance;
 
 /**
  * @author Kristian Rosenvold
@@ -66,8 +67,8 @@ public class JUnitCoreTester
         try
         {
             final HashMap<String, TestSet> classMethodCounts = new HashMap<>();
-            RunListener reporter = createInstance( classMethodCounts, reporterManagerFactory, parallelClasses, false,
-                                                         new DefaultDirectConsoleReporter( System.out ) );
+            RunListener reporter = createInstance( new RunListenerContext( NORMAL_RUN ), classMethodCounts,
+                reporterManagerFactory, parallelClasses, false, new DefaultDirectConsoleReporter( System.out ) );
             startCapture( (ConsoleOutputReceiver) reporter );
 
             JUnitCoreRunListener runListener = new JUnitCoreRunListener( reporter, classMethodCounts );
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/MockReporter.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/MockReporter.java
index 3694f92..78aed02 100644
--- a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/MockReporter.java
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/MockReporter.java
@@ -22,8 +22,10 @@ package org.apache.maven.surefire.junitcore;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.maven.surefire.api.report.AbstractRunListener;
 import org.apache.maven.surefire.api.report.ReportEntry;
-import org.apache.maven.surefire.api.report.RunListener;
+import org.apache.maven.surefire.api.report.RunListenerContext;
 import org.apache.maven.surefire.api.report.TestSetReportEntry;
 import org.apache.maven.surefire.api.report.RunMode;
 
@@ -31,7 +33,7 @@ import org.apache.maven.surefire.api.report.RunMode;
  * Internal tests use only.
  */
 final class MockReporter
-    implements RunListener
+    extends AbstractRunListener
 {
     private final List<String> events = new ArrayList<>();
 
@@ -55,6 +57,7 @@ final class MockReporter
 
     MockReporter()
     {
+        super( new RunListenerContext( RunMode.NORMAL_RUN ) );
     }
 
     @Override
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/Surefire746Test.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/Surefire746Test.java
index 38690ae..6989042 100644
--- a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/Surefire746Test.java
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/Surefire746Test.java
@@ -46,9 +46,9 @@ import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.maven.surefire.api.booter.BaseProviderFactory;
 import org.apache.maven.surefire.api.booter.ProviderParameterNames;
+import org.apache.maven.surefire.api.report.RunListenerContext;
 import org.apache.maven.surefire.common.junit4.JUnit4RunListener;
 import org.apache.maven.surefire.common.junit4.Notifier;
-import org.apache.maven.surefire.api.report.DefaultDirectConsoleReporter;
 import org.apache.maven.surefire.api.report.ReporterConfiguration;
 import org.apache.maven.surefire.api.report.ReporterFactory;
 import org.apache.maven.surefire.api.report.RunListener;
@@ -66,6 +66,7 @@ import org.junit.runners.BlockJUnit4ClassRunner;
 import org.junit.runners.model.InitializationError;
 
 import static junit.framework.Assert.assertEquals;
+import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
 
 /**
  * {@code
@@ -120,8 +121,8 @@ public class Surefire746Test
 
         final Map<String, TestSet> testSetMap = new ConcurrentHashMap<>();
 
-        RunListener listener = ConcurrentRunListener.createInstance( testSetMap, reporterFactory, false, false,
-                new DefaultDirectConsoleReporter( System.out ) );
+        RunListener listener = ConcurrentRunListener.createInstance( new RunListenerContext( NORMAL_RUN ),
+            testSetMap, reporterFactory, false, false, new DefaultDirectConsoleReporter( System.out ) );
 
         TestsToRun testsToRun = new TestsToRun( Collections.<Class<?>>singleton( TestClassTest.class ) );
 
@@ -137,7 +138,8 @@ public class Surefire746Test
             exception.expect( TestSetFailedException.class );
             JUnit4RunListener dummy = new JUnit4RunListener( new MockReporter() );
             new JUnitCoreWrapper( new Notifier( dummy, 0 ), jUnitCoreParameters,
-                    new DefaultDirectConsoleReporter( System.out ) ).execute( testsToRun, customRunListeners, null );
+                    new DefaultDirectConsoleReporter( System.out ) )
+                .execute( testsToRun, customRunListeners, null );
         }
         finally
         {
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilderTest.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilderTest.java
index 0855aa7..2592aff 100755
--- a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilderTest.java
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilderTest.java
@@ -21,7 +21,7 @@ package org.apache.maven.surefire.junitcore.pc;
 
 import net.jcip.annotations.NotThreadSafe;
 import org.apache.maven.surefire.api.report.ConsoleStream;
-import org.apache.maven.surefire.api.report.DefaultDirectConsoleReporter;
+import org.apache.maven.surefire.junitcore.DefaultDirectConsoleReporter;
 import org.junit.After;
 import org.junit.AfterClass;
 import org.junit.Before;
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerUtilTest.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerUtilTest.java
index 6f7e02b..1833b3c 100644
--- a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerUtilTest.java
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerUtilTest.java
@@ -21,7 +21,7 @@ package org.apache.maven.surefire.junitcore.pc;
 
 import org.apache.maven.surefire.junitcore.JUnitCoreParameters;
 import org.apache.maven.surefire.api.report.ConsoleStream;
-import org.apache.maven.surefire.api.report.DefaultDirectConsoleReporter;
+import org.apache.maven.surefire.junitcore.DefaultDirectConsoleReporter;
 import org.apache.maven.surefire.api.testset.TestSetFailedException;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/SchedulingStrategiesTest.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/SchedulingStrategiesTest.java
index 03a5d8e..5c8abcb 100644
--- a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/SchedulingStrategiesTest.java
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/SchedulingStrategiesTest.java
@@ -20,7 +20,7 @@ package org.apache.maven.surefire.junitcore.pc;
  */
 
 import org.apache.maven.surefire.api.report.ConsoleStream;
-import org.apache.maven.surefire.api.report.DefaultDirectConsoleReporter;
+import org.apache.maven.surefire.junitcore.DefaultDirectConsoleReporter;
 import org.junit.Test;
 
 import java.util.concurrent.ExecutorService;
diff --git a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java
index 5878248..5ccd050 100644
--- a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java
+++ b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java
@@ -98,7 +98,7 @@ public class TestNGProvider
         }
 
         final ReporterFactory reporterFactory = providerParameters.getReporterFactory();
-        final RunListener reporter = reporterFactory.createReporter();
+        final RunListener reporter = reporterFactory.getRunListener();
         /*
          * {@link org.apache.maven.surefire.api.report.ConsoleOutputCapture#startCapture(ConsoleOutputReceiver)}
          * called in prior to initializing variable {@link #testsToRun}