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 2015/11/28 08:43:21 UTC

[1/3] maven-surefire git commit: surefire-1193

Repository: maven-surefire
Updated Branches:
  refs/heads/master 021b263ab -> 0693bd900


surefire-1193


Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/c643b32d
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/c643b32d
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/c643b32d

Branch: refs/heads/master
Commit: c643b32d6c0ee6b963dc063b11dfd91de31875aa
Parents: 021b263
Author: Tibor17 <ti...@lycos.com>
Authored: Sun Nov 22 22:48:30 2015 +0100
Committer: Tibor17 <ti...@lycos.com>
Committed: Sun Nov 22 22:48:30 2015 +0100

----------------------------------------------------------------------
 .../surefire/booter/MasterProcessReader.java    | 44 ++++++--------------
 .../booter/MasterProcessReaderTest.java         |  2 +-
 2 files changed, 14 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/c643b32d/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessReader.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessReader.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessReader.java
index a63bf9e..a114154 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessReader.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessReader.java
@@ -30,13 +30,12 @@ import java.util.NoSuchElementException;
 import java.util.Queue;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Semaphore;
 import java.util.concurrent.atomic.AtomicReference;
 
 import static java.lang.Thread.State.NEW;
 import static java.lang.Thread.State.RUNNABLE;
 import static java.lang.Thread.State.TERMINATED;
-import static java.util.concurrent.locks.LockSupport.park;
-import static java.util.concurrent.locks.LockSupport.unpark;
 import static org.apache.maven.surefire.booter.Command.toShutdown;
 import static org.apache.maven.surefire.booter.ForkingRunListener.BOOTERCODE_NEXT_TEST;
 import static org.apache.maven.surefire.booter.MasterProcessCommand.NOOP;
@@ -67,12 +66,12 @@ public final class MasterProcessReader
 
     private final AtomicReference<Thread.State> state = new AtomicReference<Thread.State>( NEW );
 
-    private final Queue<Thread> waiters = new ConcurrentLinkedQueue<Thread>();
-
     private final CountDownLatch startMonitor = new CountDownLatch( 1 );
 
     private final Node headTestClassQueue = new Node();
 
+    private final Semaphore newCommandNotifier = new Semaphore( 0 );
+
     private volatile Node tailTestClassQueue = headTestClassQueue;
 
     private volatile Shutdown shutdown;
@@ -362,12 +361,7 @@ public final class MasterProcessReader
                     {
                         do
                         {
-                            await();
-                            /**
-                             * {@link java.util.concurrent.locks.LockSupport#park()}
-                             * may spuriously (that is, for no reason) return, therefore the loop here.
-                             * Could be waken up by System.exit or closing the stream.
-                             */
+                            awaitNextTest();
                             if ( isStopped() )
                             {
                                 clazz = null;
@@ -426,26 +420,14 @@ public final class MasterProcessReader
         return command;
     }
 
-    private void await()
+    private void awaitNextTest()
     {
-        final Thread currentThread = Thread.currentThread();
-        try
-        {
-            waiters.add( currentThread );
-            park();
-        }
-        finally
-        {
-            waiters.remove( currentThread );
-        }
+        newCommandNotifier.acquireUninterruptibly();
     }
 
-    private void wakeupWaiters()
+    private void wakeupIterator()
     {
-        for ( Thread waiter : waiters )
-        {
-            unpark( waiter );
-        }
+        newCommandNotifier.release();
     }
 
     private final class CommandRunnable
@@ -472,14 +454,14 @@ public final class MasterProcessReader
                         {
                             case TEST_SET_FINISHED:
                                 isTestSetFinished = true;
-                                wakeupWaiters();
+                                wakeupIterator();
                                 break;
                             case RUN_CLASS:
-                                wakeupWaiters();
+                                wakeupIterator();
                                 break;
                             case SHUTDOWN:
                                 insertToQueue( Command.TEST_SET_FINISHED );
-                                wakeupWaiters();
+                                wakeupIterator();
                                 break;
                             default:
                                 // checkstyle do nothing
@@ -516,7 +498,7 @@ public final class MasterProcessReader
                 {
                     insert( Command.TEST_SET_FINISHED );
                 }
-                wakeupWaiters();
+                wakeupIterator();
             }
         }
 
@@ -529,7 +511,7 @@ public final class MasterProcessReader
             if ( shutdown != null )
             {
                 insert( Command.TEST_SET_FINISHED ); // lazily
-                wakeupWaiters();
+                wakeupIterator();
                 insertToListeners( toShutdown( shutdown ) );
                 switch ( shutdown )
                 {

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/c643b32d/surefire-booter/src/test/java/org/apache/maven/surefire/booter/MasterProcessReaderTest.java
----------------------------------------------------------------------
diff --git a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/MasterProcessReaderTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/MasterProcessReaderTest.java
index 4e1f0d0..fc56421 100644
--- a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/MasterProcessReaderTest.java
+++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/MasterProcessReaderTest.java
@@ -161,7 +161,7 @@ public class MasterProcessReaderTest
         }
     }
 
-    @Test
+    // @Test
     public void readTwoClassesInTwoThreads()
         throws Throwable
     {


[3/3] maven-surefire git commit: [SUREFIRE-1193] reworked MasterProcessReader

Posted by ti...@apache.org.
[SUREFIRE-1193] reworked MasterProcessReader


Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/0693bd90
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/0693bd90
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/0693bd90

Branch: refs/heads/master
Commit: 0693bd900cdb38d3aa0bd2d79cbf0c2f786783c5
Parents: 47bf4b8
Author: Tibor17 <ti...@lycos.com>
Authored: Sat Nov 28 08:01:28 2015 +0100
Committer: Tibor17 <ti...@lycos.com>
Committed: Sat Nov 28 08:01:28 2015 +0100

----------------------------------------------------------------------
 .../maven/surefire/booter/BiProperty.java       |  50 ++
 .../maven/surefire/booter/CommandListener.java  |  28 +
 .../maven/surefire/booter/CommandReader.java    | 433 +++++++++++++++
 .../surefire/booter/MasterProcessListener.java  |  28 -
 .../surefire/booter/MasterProcessReader.java    | 544 -------------------
 .../surefire/booter/TwoPropertiesWrapper.java   |  50 --
 .../maven/surefire/booter/ForkedBooter.java     |  20 +-
 .../maven/surefire/booter/LazyTestsToRun.java   |  14 +-
 .../surefire/booter/CommandReaderTest.java      | 199 +++++++
 .../maven/surefire/booter/JUnit4SuiteTest.java  |   2 +-
 .../booter/MasterProcessReaderTest.java         | 254 ---------
 .../maven/surefire/junit4/JUnit4Provider.java   |  14 +-
 .../surefire/junitcore/JUnitCoreProvider.java   |  14 +-
 .../maven/surefire/testng/TestNGProvider.java   |  14 +-
 14 files changed, 752 insertions(+), 912 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/0693bd90/surefire-api/src/main/java/org/apache/maven/surefire/booter/BiProperty.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/BiProperty.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/BiProperty.java
new file mode 100644
index 0000000..b49e12b
--- /dev/null
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/BiProperty.java
@@ -0,0 +1,50 @@
+package org.apache.maven.surefire.booter;
+
+/*
+ * 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.
+ */
+
+/**
+ * Internal generic wrapper.
+ *
+ * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
+ * @since 2.19
+ * @param <P1> first property
+ * @param <P2> second property
+ */
+final class BiProperty<P1, P2>
+{
+    private final P1 p1;
+    private final P2 p2;
+
+    BiProperty( P1 p1, P2 p2 )
+    {
+        this.p1 = p1;
+        this.p2 = p2;
+    }
+
+    P1 getP1()
+    {
+        return p1;
+    }
+
+    P2 getP2()
+    {
+        return p2;
+    }
+}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/0693bd90/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandListener.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandListener.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandListener.java
new file mode 100644
index 0000000..523ca76
--- /dev/null
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandListener.java
@@ -0,0 +1,28 @@
+package org.apache.maven.surefire.booter;
+
+/*
+ * 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.
+ */
+
+/**
+ * Command listener interface.
+ */
+public interface CommandListener
+{
+    void update( Command command );
+}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/0693bd90/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandReader.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandReader.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandReader.java
new file mode 100644
index 0000000..45e8a24
--- /dev/null
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/CommandReader.java
@@ -0,0 +1,433 @@
+package org.apache.maven.surefire.booter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.surefire.testset.TestSetFailedException;
+
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static java.lang.Thread.State.NEW;
+import static java.lang.Thread.State.RUNNABLE;
+import static java.lang.Thread.State.TERMINATED;
+import static org.apache.maven.surefire.booter.Command.toShutdown;
+import static org.apache.maven.surefire.booter.ForkingRunListener.BOOTERCODE_NEXT_TEST;
+import static org.apache.maven.surefire.booter.MasterProcessCommand.NOOP;
+import static org.apache.maven.surefire.booter.MasterProcessCommand.RUN_CLASS;
+import static org.apache.maven.surefire.booter.MasterProcessCommand.SHUTDOWN;
+import static org.apache.maven.surefire.booter.MasterProcessCommand.SKIP_SINCE_NEXT_TEST;
+import static org.apache.maven.surefire.booter.MasterProcessCommand.TEST_SET_FINISHED;
+import static org.apache.maven.surefire.booter.MasterProcessCommand.decode;
+import static org.apache.maven.surefire.util.internal.StringUtils.encodeStringForForkCommunication;
+import static org.apache.maven.surefire.util.internal.StringUtils.isNotBlank;
+import static org.apache.maven.surefire.util.internal.StringUtils.isBlank;
+import static org.apache.maven.surefire.util.internal.DaemonThreadFactory.newDaemonThread;
+
+/**
+ * Reader of commands coming from plugin(master) process.
+ *
+ * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
+ * @since 2.19
+ */
+public final class CommandReader
+{
+    private static final String LAST_TEST_SYMBOL = "";
+
+    private static final CommandReader READER = new CommandReader();
+
+    private final Queue<BiProperty<MasterProcessCommand, CommandListener>> listeners
+        = new ConcurrentLinkedQueue<BiProperty<MasterProcessCommand, CommandListener>>();
+
+    private final Thread commandThread = newDaemonThread( new CommandRunnable(), "surefire-forkedjvm-command-thread" );
+
+    private final AtomicReference<Thread.State> state = new AtomicReference<Thread.State>( NEW );
+
+    private final CountDownLatch startMonitor = new CountDownLatch( 1 );
+
+    private final Semaphore nextCommandNotifier = new Semaphore( 0 );
+
+    private final CopyOnWriteArrayList<String> testClasses = new CopyOnWriteArrayList<String>();
+
+    private volatile Shutdown shutdown;
+
+    public static CommandReader getReader()
+    {
+        final CommandReader reader = READER;
+        if ( reader.state.compareAndSet( NEW, RUNNABLE ) )
+        {
+            reader.commandThread.start();
+        }
+        return reader;
+    }
+
+    public CommandReader setShutdown( Shutdown shutdown )
+    {
+        this.shutdown = shutdown;
+        return this;
+    }
+
+    public boolean awaitStarted()
+        throws TestSetFailedException
+    {
+        if ( state.get() == RUNNABLE )
+        {
+            try
+            {
+                startMonitor.await();
+                return true;
+            }
+            catch ( InterruptedException e )
+            {
+                throw new TestSetFailedException( e.getLocalizedMessage() );
+            }
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    /**
+     * @param listener listener called with <em>Any</em> {@link MasterProcessCommand command type}
+     */
+    public void addListener( CommandListener listener )
+    {
+        listeners.add( new BiProperty<MasterProcessCommand, CommandListener>( null, listener ) );
+    }
+
+    public void addTestListener( CommandListener listener )
+    {
+        addListener( RUN_CLASS, listener );
+    }
+
+    public void addTestsFinishedListener( CommandListener listener )
+    {
+        addListener( TEST_SET_FINISHED, listener );
+    }
+
+    public void addSkipNextListener( CommandListener listener )
+    {
+        addListener( SKIP_SINCE_NEXT_TEST, listener );
+    }
+
+    public void addShutdownListener( CommandListener listener )
+    {
+        addListener( SHUTDOWN, listener );
+    }
+
+    public void addNoopListener( CommandListener listener )
+    {
+        addListener( NOOP, listener );
+    }
+
+    private void addListener( MasterProcessCommand cmd, CommandListener listener )
+    {
+        listeners.add( new BiProperty<MasterProcessCommand, CommandListener>( cmd, listener ) );
+    }
+
+    public void removeListener( CommandListener listener )
+    {
+        for ( Iterator<BiProperty<MasterProcessCommand, CommandListener>> it = listeners.iterator(); it.hasNext(); )
+        {
+            BiProperty<MasterProcessCommand, CommandListener> listenerWrapper = it.next();
+            if ( listener == listenerWrapper.getP2() )
+            {
+                it.remove();
+            }
+        }
+    }
+
+    /**
+     * The iterator can be used only in one Thread.
+     *
+     * @param originalOutStream original stream in current JVM process
+     * @return Iterator with test classes lazily loaded as commands from the main process
+     */
+    Iterable<String> getIterableClasses( PrintStream originalOutStream )
+    {
+        return new ClassesIterable( originalOutStream );
+    }
+
+    public void stop()
+    {
+        if ( state.compareAndSet( NEW, TERMINATED ) || state.compareAndSet( RUNNABLE, TERMINATED ) )
+        {
+            makeQueueFull();
+            listeners.clear();
+            commandThread.interrupt();
+        }
+    }
+
+    private boolean isStopped()
+    {
+        return state.get() == TERMINATED;
+    }
+
+    private boolean isQueueFull()
+    {
+        return testClasses.contains( LAST_TEST_SYMBOL );
+    }
+
+    public void makeQueueFull()
+    {
+        testClasses.addIfAbsent( LAST_TEST_SYMBOL );
+    }
+
+    public boolean insertToQueue( String test )
+    {
+        if ( isNotBlank( test ) && !isQueueFull() )
+        {
+            testClasses.add( test );
+            return true;
+        }
+        return false;
+    }
+
+    private final class ClassesIterable
+        implements Iterable<String>
+    {
+        private final PrintStream originalOutStream;
+
+        ClassesIterable( PrintStream originalOutStream )
+        {
+            this.originalOutStream = originalOutStream;
+        }
+
+        public Iterator<String> iterator()
+        {
+            return new ClassesIterator( originalOutStream );
+        }
+    }
+
+    private final class ClassesIterator
+        implements Iterator<String>
+    {
+        private final PrintStream originalOutStream;
+
+        private String clazz;
+
+        private int nextQueueIndex = 0;
+
+        private ClassesIterator( PrintStream originalOutStream )
+        {
+            this.originalOutStream = originalOutStream;
+        }
+
+        public boolean hasNext()
+        {
+            popUnread();
+            return isNotBlank( clazz );
+        }
+
+        public String next()
+        {
+            popUnread();
+            try
+            {
+                if ( isBlank( clazz ) )
+                {
+                    throw new NoSuchElementException( CommandReader.this.isStopped() ? "stream was stopped" : "" );
+                }
+                else
+                {
+                    return clazz;
+                }
+            }
+            finally
+            {
+                clazz = null;
+            }
+        }
+
+        public void remove()
+        {
+            throw new UnsupportedOperationException();
+        }
+
+        private void popUnread()
+        {
+            if ( CommandReader.this.isStopped() || CommandReader.this.isQueueFull() )
+            {
+                clazz = null;
+                return;
+            }
+
+            if ( isBlank( clazz ) )
+            {
+                requestNextTest();
+                CommandReader.this.awaitNextTest();
+                if ( CommandReader.this.isStopped() || CommandReader.this.isQueueFull() )
+                {
+                    clazz = null;
+                    return;
+                }
+                clazz = CommandReader.this.testClasses.get( nextQueueIndex++ );
+            }
+
+            if ( CommandReader.this.isStopped() )
+            {
+                clazz = null;
+            }
+        }
+
+        private void requestNextTest()
+        {
+            byte[] encoded = encodeStringForForkCommunication( ( (char) BOOTERCODE_NEXT_TEST ) + ",0,want more!\n" );
+            originalOutStream.write( encoded, 0, encoded.length );
+        }
+    }
+
+    private void awaitNextTest()
+    {
+        nextCommandNotifier.acquireUninterruptibly();
+    }
+
+    private void wakeupIterator()
+    {
+        nextCommandNotifier.release();
+    }
+
+    private final class CommandRunnable
+        implements Runnable
+    {
+        public void run()
+        {
+            CommandReader.this.startMonitor.countDown();
+            DataInputStream stdIn = new DataInputStream( System.in );
+            boolean isTestSetFinished = false;
+            try
+            {
+                while ( CommandReader.this.state.get() == RUNNABLE )
+                {
+                    Command command = decode( stdIn );
+                    if ( command == null )
+                    {
+                        System.err.println( "[SUREFIRE] std/in stream corrupted: first sequence not recognized" );
+                        break;
+                    }
+                    else
+                    {
+                        switch ( command.getCommandType() )
+                        {
+                            case RUN_CLASS:
+                                String test = command.getData();
+                                boolean inserted = CommandReader.this.insertToQueue( test );
+                                CommandReader.this.wakeupIterator();
+                                if ( inserted )
+                                {
+                                    insertToListeners( command );
+                                }
+                                break;
+                            case TEST_SET_FINISHED:
+                                CommandReader.this.makeQueueFull();
+                                isTestSetFinished = true;
+                                CommandReader.this.wakeupIterator();
+                                insertToListeners( command );
+                                break;
+                            case SHUTDOWN:
+                                CommandReader.this.makeQueueFull();
+                                CommandReader.this.wakeupIterator();
+                                insertToListeners( command );
+                                break;
+                            default:
+                                insertToListeners( command );
+                                break;
+                        }
+                    }
+                }
+            }
+            catch ( EOFException e )
+            {
+                CommandReader.this.state.set( TERMINATED );
+                if ( !isTestSetFinished )
+                {
+                    exitByConfiguration();
+                    // does not go to finally
+                }
+            }
+            catch ( IOException e )
+            {
+                CommandReader.this.state.set( TERMINATED );
+                // If #stop() method is called, reader thread is interrupted and cause is InterruptedException.
+                if ( !( e.getCause() instanceof InterruptedException ) )
+                {
+                    System.err.println( "[SUREFIRE] std/in stream corrupted" );
+                    e.printStackTrace();
+                }
+            }
+            finally
+            {
+                // ensure fail-safe iterator as well as safe to finish in for-each loop using ClassesIterator
+                if ( !isTestSetFinished )
+                {
+                    CommandReader.this.makeQueueFull();
+                }
+                CommandReader.this.wakeupIterator();
+            }
+        }
+
+        private void insertToListeners( Command cmd )
+        {
+            MasterProcessCommand expectedCommandType = cmd.getCommandType();
+            for ( BiProperty<MasterProcessCommand, CommandListener> listenerWrapper : CommandReader.this.listeners )
+            {
+                MasterProcessCommand commandType = listenerWrapper.getP1();
+                CommandListener listener = listenerWrapper.getP2();
+                if ( commandType == null || commandType == expectedCommandType )
+                {
+                    listener.update( cmd );
+                }
+            }
+        }
+
+        private void exitByConfiguration()
+        {
+            Shutdown shutdown = CommandReader.this.shutdown; // won't read inconsistent changes through the stack
+            if ( shutdown != null )
+            {
+                CommandReader.this.makeQueueFull();
+                CommandReader.this.wakeupIterator();
+                insertToListeners( toShutdown( shutdown ) );
+                switch ( shutdown )
+                {
+                    case EXIT:
+                        System.exit( 1 );
+                    case KILL:
+                        Runtime.getRuntime().halt( 1 );
+                    case DEFAULT:
+                    default:
+                        // should not happen; otherwise you missed enum case
+                        break;
+                }
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/0693bd90/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessListener.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessListener.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessListener.java
deleted file mode 100644
index 89a4f89..0000000
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessListener.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.apache.maven.surefire.booter;
-
-/*
- * 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.
- */
-
-/**
- * listener interface
- */
-public interface MasterProcessListener
-{
-    void update( Command command );
-}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/0693bd90/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessReader.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessReader.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessReader.java
deleted file mode 100644
index dabe80a..0000000
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessReader.java
+++ /dev/null
@@ -1,544 +0,0 @@
-package org.apache.maven.surefire.booter;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import org.apache.maven.surefire.testset.TestSetFailedException;
-
-import java.io.DataInputStream;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.atomic.AtomicReference;
-
-import static java.lang.Thread.State.NEW;
-import static java.lang.Thread.State.RUNNABLE;
-import static java.lang.Thread.State.TERMINATED;
-import static org.apache.maven.surefire.booter.Command.toShutdown;
-import static org.apache.maven.surefire.booter.ForkingRunListener.BOOTERCODE_NEXT_TEST;
-import static org.apache.maven.surefire.booter.MasterProcessCommand.NOOP;
-import static org.apache.maven.surefire.booter.MasterProcessCommand.RUN_CLASS;
-import static org.apache.maven.surefire.booter.MasterProcessCommand.SHUTDOWN;
-import static org.apache.maven.surefire.booter.MasterProcessCommand.SKIP_SINCE_NEXT_TEST;
-import static org.apache.maven.surefire.booter.MasterProcessCommand.TEST_SET_FINISHED;
-import static org.apache.maven.surefire.booter.MasterProcessCommand.decode;
-import static org.apache.maven.surefire.util.internal.StringUtils.encodeStringForForkCommunication;
-import static org.apache.maven.surefire.util.internal.StringUtils.isNotBlank;
-import static org.apache.maven.surefire.util.internal.StringUtils.isBlank;
-import static org.apache.maven.surefire.util.internal.DaemonThreadFactory.newDaemonThread;
-
-/**
- * Reader of commands coming from plugin(master) process.
- *
- * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
- * @since 2.19
- */
-public final class MasterProcessReader
-{
-    private static final MasterProcessReader READER = new MasterProcessReader();
-
-    private final Queue<TwoPropertiesWrapper<MasterProcessCommand, MasterProcessListener>> listeners
-        = new ConcurrentLinkedQueue<TwoPropertiesWrapper<MasterProcessCommand, MasterProcessListener>>();
-
-    private final Thread commandThread = newDaemonThread( new CommandRunnable(), "surefire-forkedjvm-command-thread" );
-
-    private final AtomicReference<Thread.State> state = new AtomicReference<Thread.State>( NEW );
-
-    private final CountDownLatch startMonitor = new CountDownLatch( 1 );
-
-    private final Node headTestClassQueue = new Node();
-
-    private final Semaphore newCommandNotifier = new Semaphore( 0 );
-
-    private volatile Node tailTestClassQueue = headTestClassQueue;
-
-    private volatile Shutdown shutdown;
-
-    private static class Node
-    {
-        final AtomicReference<Node> successor = new AtomicReference<Node>();
-        volatile String item;
-    }
-
-    public static MasterProcessReader getReader()
-    {
-        final MasterProcessReader reader = READER;
-        if ( reader.state.compareAndSet( NEW, RUNNABLE ) )
-        {
-            reader.commandThread.start();
-        }
-        return reader;
-    }
-
-    public MasterProcessReader setShutdown( Shutdown shutdown )
-    {
-        this.shutdown = shutdown;
-        return this;
-    }
-
-    public boolean awaitStarted()
-        throws TestSetFailedException
-    {
-        if ( state.get() == RUNNABLE )
-        {
-            try
-            {
-                startMonitor.await();
-                return true;
-            }
-            catch ( InterruptedException e )
-            {
-                throw new TestSetFailedException( e.getLocalizedMessage() );
-            }
-        }
-        else
-        {
-            return false;
-        }
-    }
-
-    /**
-     * @param listener listener called with <em>Any</em> {@link MasterProcessCommand command type}
-     */
-    public void addListener( MasterProcessListener listener )
-    {
-        listeners.add( new TwoPropertiesWrapper<MasterProcessCommand, MasterProcessListener>( null, listener ) );
-    }
-
-    public void addTestListener( MasterProcessListener listener )
-    {
-        addListener( RUN_CLASS, listener );
-    }
-
-    public void addTestsFinishedListener( MasterProcessListener listener )
-    {
-        addListener( TEST_SET_FINISHED, listener );
-    }
-
-    public void addSkipNextListener( MasterProcessListener listener )
-    {
-        addListener( SKIP_SINCE_NEXT_TEST, listener );
-    }
-
-    public void addShutdownListener( MasterProcessListener listener )
-    {
-        addListener( SHUTDOWN, listener );
-    }
-
-    public void addNoopListener( MasterProcessListener listener )
-    {
-        addListener( NOOP, listener );
-    }
-
-    private void addListener( MasterProcessCommand cmd, MasterProcessListener listener )
-    {
-        listeners.add( new TwoPropertiesWrapper<MasterProcessCommand, MasterProcessListener>( cmd, listener ) );
-    }
-
-    public void removeListener( MasterProcessListener listener )
-    {
-        for ( Iterator<TwoPropertiesWrapper<MasterProcessCommand, MasterProcessListener>> it = listeners.iterator();
-            it.hasNext(); )
-        {
-            TwoPropertiesWrapper<MasterProcessCommand, MasterProcessListener> listenerWrapper = it.next();
-            if ( listener == listenerWrapper.getP2() )
-            {
-                it.remove();
-            }
-        }
-    }
-
-    Iterable<String> getIterableClasses( PrintStream originalOutStream )
-    {
-        return new ClassesIterable( headTestClassQueue, originalOutStream );
-    }
-
-    public void stop()
-    {
-        if ( state.compareAndSet( NEW, TERMINATED ) || state.compareAndSet( RUNNABLE, TERMINATED ) )
-        {
-            makeQueueFull();
-            listeners.clear();
-            commandThread.interrupt();
-        }
-    }
-
-    private boolean isStopped()
-    {
-        return state.get() == TERMINATED;
-    }
-
-    private static boolean isLastNode( Node current )
-    {
-        return current.successor.get() == current;
-    }
-
-    private boolean isQueueFull()
-    {
-        return isLastNode( tailTestClassQueue );
-    }
-
-    /**
-     * thread-safety: Must be called from single thread like here the reader thread only.
-     */
-    private boolean addTestClassToQueue( String item )
-    {
-        if ( tailTestClassQueue.item == null )
-        {
-            tailTestClassQueue.item = item;
-            Node newNode = new Node();
-            tailTestClassQueue.successor.set( newNode );
-            tailTestClassQueue = newNode;
-            return true;
-        }
-        else
-        {
-            return false;
-        }
-    }
-
-    /**
-     * After this method returns the queue is closed, new item cannot be added and method
-     * {@link #isQueueFull()} returns true.
-     */
-    @SuppressWarnings( { "all", "checkstyle:needbraces", "checkstyle:emptystatement" } )
-    public void makeQueueFull()
-    {
-        // order between (#compareAndSet, and #get) matters in multithreading
-        for ( Node tail = this.tailTestClassQueue;
-              !tail.successor.compareAndSet( null, tail ) && tail.successor.get() != tail;
-              tail = tail.successor.get() );
-    }
-
-    /**
-     * thread-safety: Must be called from single thread like here the reader thread only.
-     */
-    private void insertToQueue( Command cmd )
-    {
-        MasterProcessCommand expectedCommandType = cmd.getCommandType();
-        switch ( expectedCommandType )
-        {
-            case RUN_CLASS:
-                addTestClassToQueue( cmd.getData() );
-                break;
-            case TEST_SET_FINISHED:
-                makeQueueFull();
-                break;
-            default:
-                // checkstyle noop
-                break;
-        }
-    }
-
-    private void insertToListeners( Command cmd )
-    {
-        MasterProcessCommand expectedCommandType = cmd.getCommandType();
-        for ( TwoPropertiesWrapper<MasterProcessCommand, MasterProcessListener> listenerWrapper
-            : MasterProcessReader.this.listeners )
-        {
-            MasterProcessCommand commandType = listenerWrapper.getP1();
-            MasterProcessListener listener = listenerWrapper.getP2();
-            if ( commandType == null || commandType == expectedCommandType )
-            {
-                listener.update( cmd );
-            }
-        }
-    }
-
-    /**
-     * thread-safety: Must be called from single thread like here the reader thread only.
-     */
-    private void insert( Command cmd )
-    {
-        insertToQueue( cmd );
-        insertToListeners( cmd );
-    }
-
-    private final class ClassesIterable
-        implements Iterable<String>
-    {
-        private final Node head;
-        private final PrintStream originalOutStream;
-
-        ClassesIterable( Node head, PrintStream originalOutStream )
-        {
-            this.head = head;
-            this.originalOutStream = originalOutStream;
-        }
-
-        public Iterator<String> iterator()
-        {
-            return new ClassesIterator( head, originalOutStream );
-        }
-    }
-
-    private final class ClassesIterator
-        implements Iterator<String>
-    {
-        private final PrintStream originalOutStream;
-
-        private Node current;
-
-        private String clazz;
-
-        private ClassesIterator( Node current, PrintStream originalOutStream )
-        {
-            this.current = current;
-            this.originalOutStream = originalOutStream;
-        }
-
-        public boolean hasNext()
-        {
-            popUnread();
-            return isNotBlank( clazz );
-        }
-
-        public String next()
-        {
-            popUnread();
-            try
-            {
-                if ( isBlank( clazz ) )
-                {
-                    throw new NoSuchElementException();
-                }
-                else
-                {
-                    return clazz;
-                }
-            }
-            finally
-            {
-                clazz = null;
-            }
-        }
-
-        public void remove()
-        {
-            throw new UnsupportedOperationException();
-        }
-
-        private void popUnread()
-        {
-            if ( isStopped() )
-            {
-                clazz = null;
-                return;
-            }
-
-            if ( isBlank( clazz ) )
-            {
-                do
-                {
-                    requestNextTest();
-                    /**
-                     * this branching should be refactored to
-                     * waitNextTest();
-                     * if ( isStopped() )
-                     * {
-                     *      clazz = null;
-                     *      return;
-                     * }
-                     * clazz = current.item;
-                     * if ( !isLastNode( current ) )
-                     * {
-                     *      current = current.successor.get();
-                     * }
-                     */
-                    if ( isLastNode( current ) )
-                    {
-                        clazz = null;
-                    }
-                    else if ( current.item == null )
-                    {
-                        do
-                        {
-                            awaitNextTest();
-                            if ( isStopped() )
-                            {
-                                clazz = null;
-                                return;
-                            }
-                        } while ( current.item == null && !isLastNode( current ) );
-                        clazz = current.item;
-                        current = current.successor.get();
-                    }
-                    else
-                    {
-                        clazz = current.item;
-                        current = current.successor.get();
-                    }
-                }
-                while ( tryNullWhiteClass() );
-            }
-
-            if ( isStopped() )
-            {
-                clazz = null;
-            }
-        }
-
-        private boolean tryNullWhiteClass()
-        {
-            if ( clazz != null && isBlank( clazz ) )
-            {
-                clazz = null;
-                return true;
-            }
-            else
-            {
-                return false;
-            }
-        }
-
-        private void requestNextTest()
-        {
-            byte[] encoded = encodeStringForForkCommunication( ( (char) BOOTERCODE_NEXT_TEST ) + ",0,want more!\n" );
-            originalOutStream.write( encoded, 0, encoded.length );
-        }
-    }
-
-    /**
-     * thread-safety: Must be called from single thread like here the reader thread only.
-     */
-    private Command read( DataInputStream stdIn )
-        throws IOException
-    {
-        Command command = decode( stdIn );
-        if ( command != null )
-        {
-            insertToQueue( command );
-        }
-        return command;
-    }
-
-    private void awaitNextTest()
-    {
-        newCommandNotifier.acquireUninterruptibly();
-    }
-
-    private void wakeupIterator()
-    {
-        newCommandNotifier.release();
-    }
-
-    private final class CommandRunnable
-        implements Runnable
-    {
-        public void run()
-        {
-            MasterProcessReader.this.startMonitor.countDown();
-            DataInputStream stdIn = new DataInputStream( System.in );
-            boolean isTestSetFinished = false;
-            try
-            {
-                while ( MasterProcessReader.this.state.get() == RUNNABLE )
-                {
-                    Command command = read( stdIn );
-                    if ( command == null )
-                    {
-                        System.err.println( "[SUREFIRE] std/in stream corrupted: first sequence not recognized" );
-                        break;
-                    }
-                    else
-                    {
-                        switch ( command.getCommandType() )
-                        {
-                            case TEST_SET_FINISHED:
-                                isTestSetFinished = true;
-                                wakeupIterator();
-                                break;
-                            case RUN_CLASS:
-                                wakeupIterator();
-                                break;
-                            case SHUTDOWN:
-                                insertToQueue( Command.TEST_SET_FINISHED );
-                                wakeupIterator();
-                                break;
-                            default:
-                                // checkstyle do nothing
-                                break;
-                        }
-
-                        insertToListeners( command );
-                    }
-                }
-            }
-            catch ( EOFException e )
-            {
-                MasterProcessReader.this.state.set( TERMINATED );
-                if ( !isTestSetFinished )
-                {
-                    exitByConfiguration();
-                    // does not go to finally
-                }
-            }
-            catch ( IOException e )
-            {
-                MasterProcessReader.this.state.set( TERMINATED );
-                // If #stop() method is called, reader thread is interrupted and cause is InterruptedException.
-                if ( !( e.getCause() instanceof InterruptedException ) )
-                {
-                    System.err.println( "[SUREFIRE] std/in stream corrupted" );
-                    e.printStackTrace();
-                }
-            }
-            finally
-            {
-                // ensure fail-safe iterator as well as safe to finish in for-each loop using ClassesIterator
-                if ( !isTestSetFinished )
-                {
-                    insert( Command.TEST_SET_FINISHED );
-                }
-                wakeupIterator();
-            }
-        }
-
-        /**
-         * thread-safety: Must be called from single thread like here the reader thread only.
-         */
-        private void exitByConfiguration()
-        {
-            Shutdown shutdown = MasterProcessReader.this.shutdown; // won't read inconsistent changes through the stack
-            if ( shutdown != null )
-            {
-                insert( Command.TEST_SET_FINISHED ); // lazily
-                wakeupIterator();
-                insertToListeners( toShutdown( shutdown ) );
-                switch ( shutdown )
-                {
-                    case EXIT:
-                        System.exit( 1 );
-                    case KILL:
-                        Runtime.getRuntime().halt( 1 );
-                    case DEFAULT:
-                    default:
-                        // should not happen; otherwise you missed enum case
-                        break;
-                }
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/0693bd90/surefire-api/src/main/java/org/apache/maven/surefire/booter/TwoPropertiesWrapper.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/TwoPropertiesWrapper.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/TwoPropertiesWrapper.java
deleted file mode 100644
index 5c6e690..0000000
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/TwoPropertiesWrapper.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package org.apache.maven.surefire.booter;
-
-/*
- * 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.
- */
-
-/**
- * Internal generic wrapper.
- *
- * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
- * @since 2.19
- * @param <P1> first property
- * @param <P2> second property
- */
-final class TwoPropertiesWrapper<P1, P2>
-{
-    private final P1 p1;
-    private final P2 p2;
-
-    TwoPropertiesWrapper( P1 p1, P2 p2 )
-    {
-        this.p1 = p1;
-        this.p2 = p2;
-    }
-
-    P1 getP1()
-    {
-        return p1;
-    }
-
-    P2 getP2()
-    {
-        return p2;
-    }
-}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/0693bd90/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java
----------------------------------------------------------------------
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 a0421cc..ba1c9b7 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
@@ -73,7 +73,7 @@ public final class ForkedBooter
      */
     public static void main( String... args )
     {
-        final MasterProcessReader reader = startupMasterProcessReader();
+        final CommandReader reader = startupMasterProcessReader();
         final ScheduledFuture<?> pingScheduler = listenToShutdownCommands( reader );
         final PrintStream originalOut = System.out;
         try
@@ -155,12 +155,12 @@ public final class ForkedBooter
         }
     }
 
-    private static MasterProcessReader startupMasterProcessReader()
+    private static CommandReader startupMasterProcessReader()
     {
-        return MasterProcessReader.getReader();
+        return CommandReader.getReader();
     }
 
-    private static ScheduledFuture<?> listenToShutdownCommands( MasterProcessReader reader )
+    private static ScheduledFuture<?> listenToShutdownCommands( CommandReader reader )
     {
         reader.addShutdownListener( createExitHandler( reader ) );
         AtomicBoolean pingDone = new AtomicBoolean( true );
@@ -169,9 +169,9 @@ public final class ForkedBooter
                                                    0, PING_TIMEOUT_IN_SECONDS, SECONDS );
     }
 
-    private static MasterProcessListener createPingHandler( final AtomicBoolean pingDone )
+    private static CommandListener createPingHandler( final AtomicBoolean pingDone )
     {
-        return new MasterProcessListener()
+        return new CommandListener()
         {
             public void update( Command command )
             {
@@ -180,9 +180,9 @@ public final class ForkedBooter
         };
     }
 
-    private static MasterProcessListener createExitHandler( final MasterProcessReader reader )
+    private static CommandListener createExitHandler( final CommandReader reader )
     {
-        return new MasterProcessListener()
+        return new CommandListener()
         {
             public void update( Command command )
             {
@@ -191,7 +191,7 @@ public final class ForkedBooter
         };
     }
 
-    private static Runnable createPingJob( final AtomicBoolean pingDone, final MasterProcessReader reader  )
+    private static Runnable createPingJob( final AtomicBoolean pingDone, final CommandReader reader  )
     {
         return new Runnable()
         {
@@ -212,7 +212,7 @@ public final class ForkedBooter
         out.write( encodeBytes, 0, encodeBytes.length );
     }
 
-    private static void exit( int returnCode, Shutdown shutdownType, MasterProcessReader reader )
+    private static void exit( int returnCode, Shutdown shutdownType, CommandReader reader )
     {
         switch ( shutdownType )
         {

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/0693bd90/surefire-booter/src/main/java/org/apache/maven/surefire/booter/LazyTestsToRun.java
----------------------------------------------------------------------
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/LazyTestsToRun.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/LazyTestsToRun.java
index d3e770c..c94f032 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/LazyTestsToRun.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/LazyTestsToRun.java
@@ -32,6 +32,8 @@ import org.apache.maven.surefire.util.TestsToRun;
  * The method {@link #iterator()} returns an Iterator that blocks on calls to
  * {@link Iterator#hasNext()} or {@link Iterator#next()} until new classes are available, or no more
  * classes will be available or the internal stream is closed.
+ * The iterator can be used only in one Thread and it is the thread which executes
+ * {@link org.apache.maven.surefire.providerapi.SurefireProvider provider implementation}.
  *
  * @author Andreas Gudian
  * @author Tibor Digana
@@ -57,7 +59,7 @@ final class LazyTestsToRun
         implements Iterator<Class<?>>
     {
         private final Iterator<String> it =
-            MasterProcessReader.getReader().getIterableClasses( originalOutStream ).iterator();
+            CommandReader.getReader().getIterableClasses( originalOutStream ).iterator();
 
         public boolean hasNext()
         {
@@ -77,15 +79,18 @@ final class LazyTestsToRun
 
     }
 
-    /* (non-Javadoc)
-      * @see org.apache.maven.surefire.util.TestsToRun#iterator()
-      */
+    /**
+     * The iterator can be used only in one Thread.
+     * {@inheritDoc}
+     * @see org.apache.maven.surefire.util.TestsToRun#iterator()
+     * */
     public Iterator<Class<?>> iterator()
     {
         return new BlockingIterator();
     }
 
     /* (non-Javadoc)
+     * {@inheritDoc}
       * @see org.apache.maven.surefire.util.TestsToRun#toString()
       */
     public String toString()
@@ -94,6 +99,7 @@ final class LazyTestsToRun
     }
 
     /* (non-Javadoc)
+     * {@inheritDoc}
      * @see org.apache.maven.surefire.util.TestsToRun#allowEagerReading()
      */
     public boolean allowEagerReading()

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/0693bd90/surefire-booter/src/test/java/org/apache/maven/surefire/booter/CommandReaderTest.java
----------------------------------------------------------------------
diff --git a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/CommandReaderTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/CommandReaderTest.java
new file mode 100644
index 0000000..5284974
--- /dev/null
+++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/CommandReaderTest.java
@@ -0,0 +1,199 @@
+package org.apache.maven.surefire.booter;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.surefire.testset.TestSetFailedException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import static org.apache.maven.surefire.util.internal.StringUtils.FORK_STREAM_CHARSET_NAME;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+/**
+ * Testing singleton {@code MasterProcessReader} in multiple class loaders.
+ *
+ * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
+ * @since 2.19
+ */
+@RunWith( NewClassLoaderRunner.class )
+public class CommandReaderTest
+{
+    private final BlockingQueue<Byte> blockingStream = new LinkedBlockingQueue<Byte>();
+    private InputStream realInputStream;
+    private CommandReader reader;
+
+    @Before
+    public void init()
+        throws UnsupportedEncodingException
+    {
+        Thread.interrupted();
+        realInputStream = System.in;
+        addTestToPipeline( getClass().getName() );
+        System.setIn( new SystemInputStream() );
+        reader = CommandReader.getReader();
+    }
+
+    @After
+    public void deinit()
+    {
+        reader.stop();
+        System.setIn( realInputStream );
+    }
+
+    @Test
+    public void readJustOneClass() throws Exception
+    {
+        Iterator<String> it = reader.getIterableClasses( new PrintStream( new ByteArrayOutputStream() ) )
+            .iterator();
+        assertTrue( it.hasNext() );
+        assertThat( it.next(), is( getClass().getName() ) );
+        reader.stop();
+        assertFalse( it.hasNext() );
+        try
+        {
+            it.next();
+            fail();
+        }
+        catch ( NoSuchElementException e )
+        {
+            // expected
+        }
+    }
+
+    @Test( expected = NoSuchElementException.class )
+    public void stopBeforeReadInThread()
+        throws Throwable
+    {
+        Runnable runnable = new Runnable()
+        {
+            public void run()
+            {
+                Iterator<String> it = reader.getIterableClasses( new PrintStream( new ByteArrayOutputStream() ) )
+                    .iterator();
+                assertThat( it.next(), is( CommandReaderTest.class.getName() ) );
+            }
+        };
+        FutureTask<Object> futureTask = new FutureTask<Object>( runnable, null );
+        Thread t = new Thread( futureTask );
+        reader.stop();
+        t.start();
+        try
+        {
+            futureTask.get();
+        }
+        catch ( ExecutionException e )
+        {
+            throw e.getCause();
+        }
+    }
+
+    @Test
+    public void readTwoClassesInThread()
+        throws Throwable
+    {
+        final CountDownLatch counter = new CountDownLatch( 1 );
+        Runnable runnable = new Runnable()
+        {
+            public void run()
+            {
+                Iterator<String> it = reader.getIterableClasses( new PrintStream( new ByteArrayOutputStream() ) )
+                    .iterator();
+                assertThat( it.next(), is( CommandReaderTest.class.getName() ) );
+                counter.countDown();
+                assertThat( it.next(), is( PropertiesWrapperTest.class.getName() ) );
+            }
+        };
+        FutureTask<Object> futureTask = new FutureTask<Object>( runnable, null );
+        Thread t = new Thread( futureTask );
+        t.start();
+        counter.await();
+        addTestToPipeline( PropertiesWrapperTest.class.getName() );
+        try
+        {
+            futureTask.get();
+        }
+        catch ( ExecutionException e )
+        {
+            throw e.getCause();
+        }
+    }
+
+    @Test( timeout = 15000 )
+    public void shouldAwaitReaderUp()
+        throws TestSetFailedException
+    {
+        assertTrue( reader.awaitStarted() );
+        reader.stop();
+        assertFalse( reader.awaitStarted() );
+    }
+
+    private class SystemInputStream
+        extends InputStream
+    {
+        @Override
+        public int read()
+            throws IOException
+        {
+            try
+            {
+                return CommandReaderTest.this.blockingStream.take();
+            }
+            catch ( InterruptedException e )
+            {
+                throw new IOException( e );
+            }
+        }
+    }
+
+    private void addTestToPipeline( String cls )
+        throws UnsupportedEncodingException
+    {
+        byte[] clazz = cls.getBytes( FORK_STREAM_CHARSET_NAME );
+        ByteBuffer buffer = ByteBuffer.allocate( 8 + clazz.length )
+            .putInt( MasterProcessCommand.RUN_CLASS.getId() )
+            .putInt( clazz.length )
+            .put( clazz );
+        buffer.rewind();
+        for ( ; buffer.hasRemaining(); )
+        {
+            blockingStream.add( buffer.get() );
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/0693bd90/surefire-booter/src/test/java/org/apache/maven/surefire/booter/JUnit4SuiteTest.java
----------------------------------------------------------------------
diff --git a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/JUnit4SuiteTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/JUnit4SuiteTest.java
index 5e84775..2bdcf21 100644
--- a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/JUnit4SuiteTest.java
+++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/JUnit4SuiteTest.java
@@ -32,7 +32,7 @@ import org.junit.runners.Suite;
  */
 @Suite.SuiteClasses( {
     ClasspathTest.class,
-    MasterProcessReaderTest.class,
+    CommandReaderTest.class,
     PropertiesWrapperTest.class,
     SurefireReflectorTest.class
 } )

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/0693bd90/surefire-booter/src/test/java/org/apache/maven/surefire/booter/MasterProcessReaderTest.java
----------------------------------------------------------------------
diff --git a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/MasterProcessReaderTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/MasterProcessReaderTest.java
deleted file mode 100644
index fc56421..0000000
--- a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/MasterProcessReaderTest.java
+++ /dev/null
@@ -1,254 +0,0 @@
-package org.apache.maven.surefire.booter;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import org.apache.maven.surefire.testset.TestSetFailedException;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import java.util.Random;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-import static org.apache.maven.surefire.util.internal.StringUtils.FORK_STREAM_CHARSET_NAME;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.*;
-
-/**
- * Testing singleton {@code MasterProcessReader} in multiple class loaders.
- *
- * @author <a href="mailto:tibordigana@apache.org">Tibor Digana (tibor17)</a>
- * @since 2.19
- */
-@RunWith( NewClassLoaderRunner.class )
-public class MasterProcessReaderTest
-{
-    private final BlockingQueue<Byte> blockingStream = new LinkedBlockingQueue<Byte>();
-    private InputStream realInputStream;
-    private MasterProcessReader reader;
-
-    @Before
-    public void init()
-        throws UnsupportedEncodingException
-    {
-        Thread.interrupted();
-        realInputStream = System.in;
-        addThisTestToPipeline( getClass().getName() );
-        System.setIn( new SystemInputStream() );
-        reader = MasterProcessReader.getReader();
-    }
-
-    @After
-    public void deinit()
-    {
-        reader.stop();
-        System.setIn( realInputStream );
-    }
-
-    @Test
-    public void readJustOneClass() throws Exception
-    {
-        Iterator<String> it = reader.getIterableClasses( new PrintStream( new ByteArrayOutputStream() ) )
-            .iterator();
-        assertTrue( it.hasNext() );
-        assertThat( it.next(), is( getClass().getName() ) );
-        reader.stop();
-        assertFalse( it.hasNext() );
-        try
-        {
-            it.next();
-            fail();
-        }
-        catch ( NoSuchElementException e )
-        {
-            // expected
-        }
-    }
-
-    @Test( expected = NoSuchElementException.class )
-    public void stopBeforeReadInThread()
-        throws Throwable
-    {
-        Runnable runnable = new Runnable()
-        {
-            public void run()
-            {
-                Iterator<String> it = reader.getIterableClasses( new PrintStream( new ByteArrayOutputStream() ) )
-                    .iterator();
-                assertThat( it.next(), is( MasterProcessReaderTest.class.getName() ) );
-            }
-        };
-        FutureTask<Object> futureTask = new FutureTask<Object>( runnable, null );
-        Thread t = new Thread( futureTask );
-        reader.stop();
-        t.start();
-        try
-        {
-            futureTask.get();
-        }
-        catch ( ExecutionException e )
-        {
-            throw e.getCause();
-        }
-    }
-
-    @Test
-    public void readTwoClassesInThread()
-        throws Throwable
-    {
-        final CountDownLatch counter = new CountDownLatch( 1 );
-        Runnable runnable = new Runnable()
-        {
-            public void run()
-            {
-                Iterator<String> it = reader.getIterableClasses( new PrintStream( new ByteArrayOutputStream() ) )
-                    .iterator();
-                assertThat( it.next(), is( MasterProcessReaderTest.class.getName() ) );
-                counter.countDown();
-                assertThat( it.next(), is( PropertiesWrapperTest.class.getName() ) );
-            }
-        };
-        FutureTask<Object> futureTask = new FutureTask<Object>( runnable, null );
-        Thread t = new Thread( futureTask );
-        t.start();
-        counter.await();
-        addThisTestToPipeline( PropertiesWrapperTest.class.getName() );
-        try
-        {
-            futureTask.get();
-        }
-        catch ( ExecutionException e )
-        {
-            throw e.getCause();
-        }
-    }
-
-    // @Test
-    public void readTwoClassesInTwoThreads()
-        throws Throwable
-    {
-        final Iterable<String> lazyTestSet =
-            reader.getIterableClasses( new PrintStream( new ByteArrayOutputStream() ) );
-
-        class Provider implements Runnable
-        {
-            public void run()
-            {
-                Iterator<String> it = lazyTestSet.iterator();
-                assertThat( it.next(), is( MasterProcessReaderTest.class.getName() ) );
-                assertThat( it.next(), is( PropertiesWrapperTest.class.getName() ) );
-                assertFalse( it.hasNext() );
-            }
-        }
-
-        ExecutorService es = Executors.newFixedThreadPool( 2 );
-        Future<?> result1 = es.submit( new Provider() );
-        Random rnd = new Random();
-        TimeUnit.MILLISECONDS.sleep( rnd.nextInt( 50 ) );
-        Future<?> result2 = es.submit( new Provider() );
-        TimeUnit.MILLISECONDS.sleep( rnd.nextInt( 50 ) );
-        addThisTestToPipeline( PropertiesWrapperTest.class.getName() );
-        TimeUnit.MILLISECONDS.sleep( rnd.nextInt( 50 ) );
-        addTestSetFinishedToPipeline();
-        for ( Future<?> result : Arrays.asList( result1, result2 ) )
-        {
-            try
-            {
-                result.get();
-            }
-            catch ( ExecutionException e )
-            {
-                throw e.getCause();
-            }
-        }
-    }
-
-    @Test( timeout = 15000 )
-    public void shouldAwaitReaderUp()
-        throws TestSetFailedException
-    {
-        assertTrue( reader.awaitStarted() );
-        reader.stop();
-        assertFalse( reader.awaitStarted() );
-    }
-
-    private class SystemInputStream
-        extends InputStream
-    {
-        @Override
-        public int read()
-            throws IOException
-        {
-            try
-            {
-                return MasterProcessReaderTest.this.blockingStream.take();
-            }
-            catch ( InterruptedException e )
-            {
-                throw new IOException( e );
-            }
-        }
-    }
-
-    private void addThisTestToPipeline( String cls )
-        throws UnsupportedEncodingException
-    {
-        byte[] clazz = cls.getBytes( FORK_STREAM_CHARSET_NAME );
-        ByteBuffer buffer = ByteBuffer.allocate( 8 + clazz.length )
-            .putInt( MasterProcessCommand.RUN_CLASS.getId() )
-            .putInt( clazz.length )
-            .put( clazz );
-        buffer.rewind();
-        for ( ; buffer.hasRemaining(); )
-        {
-            blockingStream.add( buffer.get() );
-        }
-    }
-
-    private void addTestSetFinishedToPipeline()
-        throws UnsupportedEncodingException
-    {
-        for ( byte b : MasterProcessCommand.TEST_SET_FINISHED.encode() )
-        {
-            blockingStream.add( b );
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/0693bd90/surefire-providers/surefire-junit4/src/main/java/org/apache/maven/surefire/junit4/JUnit4Provider.java
----------------------------------------------------------------------
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 948d514..85b2a98 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
@@ -20,8 +20,8 @@ package org.apache.maven.surefire.junit4;
  */
 
 import org.apache.maven.surefire.booter.Command;
-import org.apache.maven.surefire.booter.MasterProcessListener;
-import org.apache.maven.surefire.booter.MasterProcessReader;
+import org.apache.maven.surefire.booter.CommandListener;
+import org.apache.maven.surefire.booter.CommandReader;
 import org.apache.maven.surefire.common.junit4.ClassMethod;
 import org.apache.maven.surefire.common.junit4.JUnit4RunListener;
 import org.apache.maven.surefire.common.junit4.JUnit4TestChecker;
@@ -92,14 +92,14 @@ public class JUnit4Provider
 
     private final int rerunFailingTestsCount;
 
-    private final MasterProcessReader commandsReader;
+    private final CommandReader commandsReader;
 
     private TestsToRun testsToRun;
 
     public JUnit4Provider( ProviderParameters booterParameters )
     {
         // don't start a thread in MasterProcessReader while we are in in-plugin process
-        commandsReader = booterParameters.isInsideFork() ? MasterProcessReader.getReader().setShutdown(
+        commandsReader = booterParameters.isInsideFork() ? CommandReader.getReader().setShutdown(
             booterParameters.getShutdown() ) : null;
         providerParameters = booterParameters;
         testClassLoader = booterParameters.getTestClassLoader();
@@ -170,7 +170,7 @@ public class JUnit4Provider
 
                 if ( commandsReader != null )
                 {
-                    commandsReader.addShutdownListener( new MasterProcessListener()
+                    commandsReader.addShutdownListener( new CommandListener()
                     {
                         public void update( Command command )
                         {
@@ -224,9 +224,9 @@ public class JUnit4Provider
         }
     }
 
-    private MasterProcessListener registerPleaseStopJunitListener( final Notifier notifier )
+    private CommandListener registerPleaseStopJunitListener( final Notifier notifier )
     {
-        MasterProcessListener listener = new MasterProcessListener()
+        CommandListener listener = new CommandListener()
         {
             public void update( Command command )
             {

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/0693bd90/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java
----------------------------------------------------------------------
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 f2fa49f..5e03bff 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,8 +20,8 @@ package org.apache.maven.surefire.junitcore;
  */
 
 import org.apache.maven.surefire.booter.Command;
-import org.apache.maven.surefire.booter.MasterProcessListener;
-import org.apache.maven.surefire.booter.MasterProcessReader;
+import org.apache.maven.surefire.booter.CommandListener;
+import org.apache.maven.surefire.booter.CommandReader;
 import org.apache.maven.surefire.common.junit4.JUnit4RunListener;
 import org.apache.maven.surefire.common.junit4.JUnitTestFailureListener;
 import org.apache.maven.surefire.common.junit4.Notifier;
@@ -83,14 +83,14 @@ public class JUnitCoreProvider
 
     private final TestListResolver testResolver;
 
-    private final MasterProcessReader commandsReader;
+    private final CommandReader commandsReader;
 
     private TestsToRun testsToRun;
 
     public JUnitCoreProvider( ProviderParameters providerParameters )
     {
         commandsReader = providerParameters.isInsideFork()
-            ? MasterProcessReader.getReader().setShutdown( providerParameters.getShutdown() )
+            ? CommandReader.getReader().setShutdown( providerParameters.getShutdown() )
             : null;
         this.providerParameters = providerParameters;
         testClassLoader = providerParameters.getTestClassLoader();
@@ -167,7 +167,7 @@ public class JUnitCoreProvider
 
             if ( commandsReader != null )
             {
-                commandsReader.addShutdownListener( new MasterProcessListener()
+                commandsReader.addShutdownListener( new CommandListener()
                 {
                     public void update( Command command )
                     {
@@ -225,9 +225,9 @@ public class JUnitCoreProvider
         }
     }
 
-    private MasterProcessListener registerPleaseStopJunitListener( final Notifier stoppable )
+    private CommandListener registerPleaseStopJunitListener( final Notifier stoppable )
     {
-        MasterProcessListener listener = new MasterProcessListener()
+        CommandListener listener = new CommandListener()
         {
             public void update( Command command )
             {

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/0693bd90/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/TestNGProvider.java
----------------------------------------------------------------------
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 75d8463..5444fde 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
@@ -20,8 +20,8 @@ package org.apache.maven.surefire.testng;
  */
 
 import org.apache.maven.surefire.booter.Command;
-import org.apache.maven.surefire.booter.MasterProcessListener;
-import org.apache.maven.surefire.booter.MasterProcessReader;
+import org.apache.maven.surefire.booter.CommandListener;
+import org.apache.maven.surefire.booter.CommandReader;
 import org.apache.maven.surefire.cli.CommandLineOption;
 import org.apache.maven.surefire.providerapi.AbstractProvider;
 import org.apache.maven.surefire.providerapi.ProviderParameters;
@@ -66,7 +66,7 @@ public class TestNGProvider
 
     private final List<CommandLineOption> mainCliOptions;
 
-    private final MasterProcessReader commandsReader;
+    private final CommandReader commandsReader;
 
     private TestsToRun testsToRun;
 
@@ -74,7 +74,7 @@ public class TestNGProvider
     {
         // don't start a thread in MasterProcessReader while we are in in-plugin process
         commandsReader = booterParameters.isInsideFork()
-            ? MasterProcessReader.getReader().setShutdown( booterParameters.getShutdown() )
+            ? CommandReader.getReader().setShutdown( booterParameters.getShutdown() )
             : null;
         providerParameters = booterParameters;
         testClassLoader = booterParameters.getTestClassLoader();
@@ -140,7 +140,7 @@ public class TestNGProvider
 
                     if ( commandsReader != null )
                     {
-                        commandsReader.addShutdownListener( new MasterProcessListener()
+                        commandsReader.addShutdownListener( new CommandListener()
                         {
                             public void update( Command command )
                             {
@@ -189,9 +189,9 @@ public class TestNGProvider
         }
     }
 
-    private MasterProcessListener registerPleaseStopListener()
+    private CommandListener registerPleaseStopListener()
     {
-        MasterProcessListener listener = new MasterProcessListener()
+        CommandListener listener = new CommandListener()
         {
             public void update( Command command )
             {


[2/3] maven-surefire git commit: refactoring

Posted by ti...@apache.org.
refactoring


Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/47bf4b85
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/47bf4b85
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/47bf4b85

Branch: refs/heads/master
Commit: 47bf4b851093c6c785c14f1e68e6c14decf60f62
Parents: c643b32
Author: Tibor17 <ti...@lycos.com>
Authored: Sun Nov 22 23:17:47 2015 +0100
Committer: Tibor17 <ti...@lycos.com>
Committed: Sun Nov 22 23:17:47 2015 +0100

----------------------------------------------------------------------
 .../maven/surefire/booter/MasterProcessReader.java    | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/47bf4b85/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessReader.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessReader.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessReader.java
index a114154..dabe80a 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessReader.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/MasterProcessReader.java
@@ -353,6 +353,20 @@ public final class MasterProcessReader
                 do
                 {
                     requestNextTest();
+                    /**
+                     * this branching should be refactored to
+                     * waitNextTest();
+                     * if ( isStopped() )
+                     * {
+                     *      clazz = null;
+                     *      return;
+                     * }
+                     * clazz = current.item;
+                     * if ( !isLastNode( current ) )
+                     * {
+                     *      current = current.successor.get();
+                     * }
+                     */
                     if ( isLastNode( current ) )
                     {
                         clazz = null;