diff --git a/test/edu/nps/moves/dis7/AllPduRoundTripTest.java b/test/edu/nps/moves/dis7/AllPduRoundTripTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d668947460c90731f8a282a78fed0aa41a284a1
--- /dev/null
+++ b/test/edu/nps/moves/dis7/AllPduRoundTripTest.java
@@ -0,0 +1,249 @@
+/**
+ * Copyright (c) 2008-2019, MOVES Institute, Naval Postgraduate School. All rights reserved.
+ * This work is licensed under the BSD open source license, available at https://www.movesinstitute.org/licenses/bsd.html
+ */
+package edu.nps.moves.dis7;
+
+/**
+ * This is a test class (which can also be run through its main() method) which tests round-tripping of pdus, i.e.,
+ * creating a pdu instance in java, serializing it and sending over the network as a stream of bytes, at the same time
+ * reading them back from the net.  It also uses the pdu logger in the Player class to  save the received pdus to disk.
+ * 
+ * Two tests for pdu equivalency are performed:
+ * 1.  Sent vs. received
+ * 2.  Sent vs. persisted
+ * 
+ * @author Mike Bailey, jmbailey@edu.nps.edu
+ * @version $Id$
+ */
+import com.google.common.io.Files;
+import edu.nps.moves.dis7.enumerations.Country;
+import edu.nps.moves.dis7.enumerations.DISPDUType;
+import edu.nps.moves.dis7.util.DisThreadedNetIF;
+import edu.nps.moves.dis7.util.PduFactory;
+import edu.nps.moves.dis7.util.playerrecorder.Player;
+import edu.nps.moves.dis7.util.playerrecorder.Recorder;
+import java.io.File;
+import java.util.HashMap;
+import java.util.concurrent.Semaphore;
+import org.junit.jupiter.api.*;
+import static org.junit.jupiter.api.Assertions.*;
+
+@DisplayName("All Pdu Round Trip Test")
+
+public class AllPduRoundTripTest
+{
+  private PduFactory fact;
+
+  @BeforeAll
+  public static void beforeAllTests()
+  {
+    System.out.println("AllPduRoundTripTest");
+  }
+
+  @AfterAll
+  public static void afterAllTests()
+  {
+  }
+
+  @BeforeEach
+  public void setUp()
+  {
+  }
+
+  @AfterEach
+  public void tearDown()
+  {
+  }
+
+  @Test
+  public void testRoundTripAllPdus()
+  {
+    Throwable ex = null;
+    try {
+      setupReceiver();
+      setupRecorder();
+      
+      fact = new PduFactory(Country.PHILIPPINES_PHL, (byte) 11, (byte) 22, (short) 33, true);
+
+      sendOne(fact.makeAcknowledgePdu());
+      sendOne(fact.makeAcknowledgeReliablePdu());
+      sendOne(fact.makeActionRequestPdu());
+      sendOne(fact.makeActionRequestReliablePdu());
+      sendOne(fact.makeActionResponsePdu());
+      sendOne(fact.makeActionResponseReliablePdu());
+      sendOne(fact.makeAggregateStatePdu());
+      sendOne(fact.makeAppearancePdu());
+      sendOne(fact.makeArealObjectStatePdu());
+      sendOne(fact.makeArticulatedPartsPdu());
+      sendOne(fact.makeAttributePdu());
+      sendOne(fact.makeCollisionElasticPdu());
+      sendOne(fact.makeCollisionPdu());
+      sendOne(fact.makeCommentPdu());
+      sendOne(fact.makeCommentReliablePdu());
+      sendOne(fact.makeCreateEntityPdu());
+      sendOne(fact.makeCreateEntityReliablePdu());
+      sendOne(fact.makeDataPdu());
+      sendOne(fact.makeDataQueryPdu());
+      sendOne(fact.makeDataQueryReliablePdu());
+      sendOne(fact.makeDataReliablePdu());
+      sendOne(fact.makeDesignatorPdu());
+      sendOne(fact.makeDetonationPdu());
+      sendOne(fact.makeDirectedEnergyFirePdu());
+      sendOne(fact.makeElectronicEmissionsPdu());
+      sendOne(fact.makeEntityDamageStatusPdu());
+      sendOne(fact.makeEntityStatePdu());
+      sendOne(fact.makeEntityStateUpdatePdu());
+      sendOne(fact.makeEnvironmentalProcessPdu());
+      sendOne(fact.makeEventReportPdu());
+      sendOne(fact.makeEventReportReliablePdu());
+      sendOne(fact.makeFirePdu());
+      sendOne(fact.makeGriddedDataPdu());
+      sendOne(fact.makeIffPdu());
+      sendOne(fact.makeInformationOperationsReportPdu());
+      sendOne(fact.makeInformationOperationsActionPdu());
+      sendOne(fact.makeIntercomControlPdu());
+      sendOne(fact.makeIntercomSignalPdu());
+      sendOne(fact.makeIsGroupOfPdu());
+      sendOne(fact.makeIsPartOfPdu());
+      sendOne(fact.makeLEDetonationPdu());
+      sendOne(fact.makeLEFirePdu());
+      sendOne(fact.makeLinearObjectStatePdu());
+      sendOne(fact.makeMinefieldDataPdu());
+      sendOne(fact.makeMinefieldQueryPdu());
+      sendOne(fact.makeMinefieldResponseNackPdu());
+      sendOne(fact.makeMinefieldStatePdu());
+      sendOne(fact.makePointObjectStatePdu());
+      sendOne(fact.makeReceiverPdu());
+      sendOne(fact.makeRecordQueryReliablePdu());
+      sendOne(fact.makeRecordReliablePdu());
+      sendOne(fact.makeRemoveEntityPdu());
+      sendOne(fact.makeRemoveEntityReliablePdu());
+      sendOne(fact.makeRepairCompletePdu());
+      sendOne(fact.makeRepairResponsePdu());
+      sendOne(fact.makeResupplyCancelPdu());
+      sendOne(fact.makeResupplyOfferPdu());
+      sendOne(fact.makeResupplyReceivedPdu());
+      sendOne(fact.makeSeesPdu());
+      sendOne(fact.makeServiceRequestPdu());
+      sendOne(fact.makeSetDataPdu());
+      sendOne(fact.makeSetDataReliablePdu());
+      sendOne(fact.makeSetRecordReliablePdu());
+      sendOne(fact.makeSignalPdu());
+      sendOne(fact.makeStartResumePdu());
+      sendOne(fact.makeStartResumeReliablePdu());
+      sendOne(fact.makeStopFreezePdu());
+      sendOne(fact.makeStopFreezeReliablePdu());
+      sendOne(fact.makeTransferOwnershipPdu());
+      sendOne(fact.makeTransmitterPdu());
+      sendOne(fact.makeTspiPdu());
+      sendOne(fact.makeUnderwaterAcousticPdu());
+
+      sleep(1000L);
+
+      assertTrue(pduReceivedMap.size() == pduSentMap.size(),"No pdus, or not all sent pdus, received");
+
+      shutDownReceiver();
+      shutDownRecorder();
+
+      testForEquals();
+      
+      Semaphore mutex = new Semaphore(1);
+      getAllFromRecorder(mutex);
+      mutex.acquire(); // wait until above method is done
+      
+      testRecorderForEquals();
+    }
+    catch (Throwable t) {
+      ex = t;
+      System.out.println(t.getLocalizedMessage());
+      t.printStackTrace();
+    }
+
+    assertNull(ex, "Exception should be null if successful creation of all objects");
+  }
+
+  private File recorderDirectory;
+  private HashMap<DISPDUType, Pdu> pduSentMap = new HashMap<>();
+  private HashMap<DISPDUType, Pdu> pduReceivedMap = new HashMap<>();
+  private HashMap<DISPDUType, Pdu> pduReadMap = new HashMap<>();
+
+  DisThreadedNetIF disnetworking;
+  Recorder recorder;
+
+  private void setupReceiver()
+  {
+    disnetworking = new DisThreadedNetIF();
+    disnetworking.addListener(pdu -> {
+      pduReceivedMap.put(pdu.getPduType(), pdu);
+    });
+  }
+
+  private void shutDownReceiver()
+  {
+    disnetworking.kill();
+  }
+
+  private void sendOne(Pdu pdu)
+  {
+    pduSentMap.put(pdu.getPduType(), pdu);
+    disnetworking.send(pdu);
+  }
+
+  private void setupRecorder() throws Exception
+  {
+    recorderDirectory = Files.createTempDir();
+    recorder = new Recorder(recorderDirectory.getAbsolutePath(), disnetworking.getMcastGroup(), disnetworking.getDisPort());
+    System.out.println("Recorder log at " + recorderDirectory.getAbsolutePath());
+  }
+
+  private void shutDownRecorder() throws Exception
+  {
+    recorder.end();
+  }
+
+  private void testForEquals() throws Exception
+  {
+    assertEquals(pduSentMap.size(), pduReceivedMap.size(), "Different number of pdus received than sent");
+
+    pduSentMap.keySet().forEach(typ -> assertTrue(pduSentMap.get(typ).equals(pduReceivedMap.get(typ)), "Sent and received pdus not identical"));
+  }
+
+  private void getAllFromRecorder(Semaphore sem) throws Exception
+  {
+    sem.acquire();
+    Player player = new Player(disnetworking.getMcastGroup(), disnetworking.getDisPort(), recorderDirectory.toPath());
+    player.sendToNet(false);
+    player.addRawListener(ba -> {
+      if (ba != null) {
+        Pdu pdu = fact.createPdu(ba);
+        pduReadMap.put(pdu.getPduType(), pdu);
+      }
+      else {
+        player.end();
+        sem.release();
+      }
+    });
+
+    player.startResume();
+  }
+
+  private void testRecorderForEquals() throws Exception
+  {
+    assertEquals(pduSentMap.size(), pduReadMap.size(), "Different number of pdus sent than read");
+
+    pduSentMap.keySet().forEach(typ -> assertTrue(pduSentMap.get(typ).equals(pduReadMap.get(typ)), "Sent and read pdus not identical"));
+  }
+  
+//@formatter:off
+  private void sleep(long ms)
+  {
+    try {Thread.sleep(ms);}catch (InterruptedException ex) {}
+  }
+//@formatter:on
+  
+  public static void main(String[] args)
+  {
+    new AllPduRoundTripTest().testRoundTripAllPdus();
+  }
+}