Refactored decode(Memento) and embedded Memento in the decoder instance
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/EventConsumerThread.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/EventConsumerThread.java
index 79d5c85..2e5b5d3 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/EventConsumerThread.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/extensions/EventConsumerThread.java
@@ -21,7 +21,6 @@
 
 import org.apache.maven.surefire.api.event.Event;
 import org.apache.maven.surefire.api.fork.ForkNodeArguments;
-import org.apache.maven.surefire.api.stream.AbstractStreamDecoder.Memento;
 import org.apache.maven.surefire.extensions.CloseableDaemonThread;
 import org.apache.maven.surefire.extensions.EventHandler;
 import org.apache.maven.surefire.extensions.util.CountdownCloseable;
@@ -67,10 +66,9 @@
               CountdownCloseable c = countdownCloseable;
               EventDecoder eventDecoder = decoder )
         {
-            Memento memento = eventDecoder.new Memento();
             do
             {
-                Event event = eventDecoder.decode( memento );
+                Event event = eventDecoder.decode();
                 if ( event != null && !disabled )
                 {
                     eventHandler.handleEvent( event );
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 ea11889..fa61d49 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
@@ -140,6 +140,8 @@
 
     private final OutputStream debugSink;
 
+    private Memento memento;
+
     public EventDecoder( @Nonnull ReadableByteChannel channel,
                          @Nonnull ForkNodeArguments arguments )
     {
@@ -148,8 +150,15 @@
     }
 
     @Override
-    public Event decode( @Nonnull Memento memento ) throws IOException
+    public Event decode() throws IOException
     {
+        if ( memento == null )
+        {
+            // do not create memento in constructor because the constructor is called in another thread
+            // memento is the thread confinement object
+            memento = new Memento();
+        }
+
         try
         {
             ForkedProcessEventType eventType = readMessageType( memento );
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/api/stream/AbstractStreamDecoder.java b/surefire-api/src/main/java/org/apache/maven/surefire/api/stream/AbstractStreamDecoder.java
index 6ddbb45..02b3d3a 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/api/stream/AbstractStreamDecoder.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/api/stream/AbstractStreamDecoder.java
@@ -89,7 +89,15 @@
         logger = arguments.getConsoleLogger();
     }
 
-    public abstract M decode( @Nonnull Memento memento ) throws MalformedChannelException, IOException;
+    /**
+     * Decoding and returns a message {@code M} and waiting, if necessary, for the next
+     * message received from the channel.
+     *
+     * @return message {@code M}, or null if could not decode a message due to a frame error
+     * @throws MalformedChannelException the channel error
+     * @throws IOException stream I/O exception
+     */
+    public abstract M decode() throws MalformedChannelException, IOException;
 
     @Nonnull
     protected abstract byte[] getEncodedMagicNumber();
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/api/stream/MalformedChannelException.java b/surefire-api/src/main/java/org/apache/maven/surefire/api/stream/MalformedChannelException.java
index cf4468f..8944735 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/api/stream/MalformedChannelException.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/api/stream/MalformedChannelException.java
@@ -20,7 +20,7 @@
  */
 
 /**
- *
+ * No supported message type.
  */
 public class MalformedChannelException extends Exception
 {
diff --git a/surefire-api/src/test/java/org/apache/maven/surefire/api/stream/AbstractStreamDecoderTest.java b/surefire-api/src/test/java/org/apache/maven/surefire/api/stream/AbstractStreamDecoderTest.java
index 2ff06ea..2cec298 100644
--- a/surefire-api/src/test/java/org/apache/maven/surefire/api/stream/AbstractStreamDecoderTest.java
+++ b/surefire-api/src/test/java/org/apache/maven/surefire/api/stream/AbstractStreamDecoderTest.java
@@ -664,7 +664,7 @@
         }
 
         @Override
-        public Event decode( @Nonnull Memento memento ) throws MalformedChannelException
+        public Event decode() throws MalformedChannelException
         {
             throw new MalformedChannelException();
         }
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/CommandChannelDecoder.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/CommandChannelDecoder.java
index 85bda73..8b7a5d7 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/CommandChannelDecoder.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/spi/CommandChannelDecoder.java
@@ -22,7 +22,6 @@
 import org.apache.maven.surefire.api.booter.Command;
 import org.apache.maven.surefire.api.booter.MasterProcessChannelDecoder;
 import org.apache.maven.surefire.api.fork.ForkNodeArguments;
-import org.apache.maven.surefire.api.stream.AbstractStreamDecoder.Memento;
 import org.apache.maven.surefire.api.stream.MalformedChannelException;
 import org.apache.maven.surefire.booter.stream.CommandDecoder;
 
@@ -40,7 +39,6 @@
 public class CommandChannelDecoder implements MasterProcessChannelDecoder
 {
     private final CommandDecoder decoder;
-    private Memento memento;
 
     public CommandChannelDecoder( @Nonnull ReadableByteChannel channel,
                                   @Nonnull ForkNodeArguments arguments )
@@ -53,18 +51,11 @@
     @SuppressWarnings( "checkstyle:innerassignment" )
     public Command decode() throws IOException
     {
-        if ( memento == null )
-        {
-            // do not create memento in constructor because the constructor is called in another thread
-            // memento is the thread confinement object
-            memento = decoder.new Memento();
-        }
-
         do
         {
             try
             {
-                Command command = decoder.decode( memento );
+                Command command = decoder.decode();
                 if ( command != null )
                 {
                     return command;
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/stream/CommandDecoder.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/stream/CommandDecoder.java
index 4a7e257..9387f85 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/stream/CommandDecoder.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/stream/CommandDecoder.java
@@ -70,6 +70,7 @@
 
     private final ForkNodeArguments arguments;
     private final OutputStream debugSink;
+    private Memento memento;
 
     public CommandDecoder( @Nonnull ReadableByteChannel channel,
                            @Nonnull ForkNodeArguments arguments )
@@ -80,8 +81,15 @@
     }
 
     @Override
-    public Command decode( @Nonnull Memento memento ) throws IOException, MalformedChannelException
+    public Command decode() throws IOException, MalformedChannelException
     {
+        if ( memento == null )
+        {
+            // do not create memento in constructor because the constructor is called in another thread
+            // memento is the thread confinement object
+            memento = new Memento();
+        }
+
         try
         {
             MasterProcessCommand commandType = readMessageType( memento );