diff --git a/src/edu/nps/moves/dis7/utilities/DisChannel.java b/src/edu/nps/moves/dis7/utilities/DisChannel.java
index 758df84bb906ce8a5f6c047546945f913b3ff3d1..16a366781b10475310a8d42fc9f24a7c45ce5866 100644
--- a/src/edu/nps/moves/dis7/utilities/DisChannel.java
+++ b/src/edu/nps/moves/dis7/utilities/DisChannel.java
@@ -13,6 +13,8 @@ import edu.nps.moves.dis7.utilities.stream.PduRecorder;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
+import java.util.Timer;
+import java.util.TimerTask;
 
 /**
  * DisChannel integrates multiple utility capabilities to handle most  networking and entity-management tasks.
@@ -50,6 +52,8 @@ public class DisChannel
             DisThreadedNetworkInterface.PduListener pduListener;
             Pdu                                     receivedPdu;
     private PduRecorder                             pduRecorder;
+    private boolean                                 verboseDisNetworkInterface = true;
+    private boolean                                 verbosePduRecorder         = true;
           
     /** CommentPdu type providing a description, used for consistent reporting and logging. */
     public final VariableRecordType COMMENTPDU_DESCRIPTION            = VariableRecordType.DESCRIPTION;
@@ -87,10 +91,30 @@ public class DisChannel
         initialize();
     }
     /** Constructor with new descriptor
-     * @param newDescriptor descriptor for this instance */
-    public DisChannel(String newDescriptor)
+     * @param initialDescriptor descriptor for this instance */
+    public DisChannel(String initialDescriptor)
     {
-        descriptor = newDescriptor;
+        descriptor = initialDescriptor;
+        initialize();
+    }
+    /** Constructor with new verboseness
+     * @param verbosenessDisNetworkInterface  whether channel is initially verbose
+     * @param verbosenessPduRecorder      whether PduRecorder is initially verbose */
+    public DisChannel(boolean verbosenessDisNetworkInterface, boolean verbosenessPduRecorder)
+    {
+        verboseDisNetworkInterface = verbosenessDisNetworkInterface;
+        verbosePduRecorder         = verbosenessPduRecorder;
+        initialize();
+    }
+    /** Constructor with new descriptor, verboseness
+     * @param initialDescriptor descriptor for this instance
+     * @param verbosenessDisNetworkInterface  whether channel is initially verbose
+     * @param verbosenessPduRecorder whether PduRecorder is initially verbose  */
+    public DisChannel(String initialDescriptor, boolean verbosenessDisNetworkInterface, boolean verbosenessPduRecorder)
+    {
+        descriptor = initialDescriptor;
+        verboseDisNetworkInterface = verbosenessDisNetworkInterface;
+        verbosePduRecorder         = verbosenessPduRecorder;
         initialize();
     }
     /** Initialize this class */
@@ -200,8 +224,10 @@ public class DisChannel
         }            
         disNetworkInterface = new DisThreadedNetworkInterface(getNetworkAddress(), getNetworkPort());
         getDisNetworkInterface().setDescriptor(descriptor);
-        printlnTRACE("Network confirmation:" + " address=" + getDisNetworkInterface().getAddress() + //  disNetworkInterface.getMulticastGroup() +
-                                                  " port=" + getDisNetworkInterface().getPort()); // + disNetworkInterface.getDisPort());
+        getDisNetworkInterface().setVerbose(isVerboseDisNetworkInterface());
+        if (isVerbosePduRecorder())
+            printlnTRACE("Network confirmation:" + " address=" + getDisNetworkInterface().getAddress() + //  disNetworkInterface.getMulticastGroup() +
+                                                      " port=" + getDisNetworkInterface().getPort());    // + disNetworkInterface.getDisPort());
         pduListener = new DisThreadedNetworkInterface.PduListener() {
             /** Callback handler for listener */
             @Override
@@ -214,13 +240,15 @@ public class DisChannel
         printlnTRACE("Beginning pdu save to directory " + pduLogOutputDirectory);
         pduRecorder = new PduRecorder(pduLogOutputDirectory, getNetworkAddress(), getNetworkPort()); // assumes save
         pduRecorder.setEncodingPduLog(PduRecorder.ENCODING_PLAINTEXT);
-        pduRecorder.setVerbose(true); // either sending, receiving or both
+        pduRecorder.setVerbose(isVerboseDisNetworkInterface()); // either sending, receiving or both
         pduRecorder.start(); // begin running
     }
 
     /** All done, release network resources */
-    public void tearDownNetworkInterface() {
-        getPduRecorder().stop(); // handles disNetworkInterface.close(), tears down threads and sockets
+    public void tearDownNetworkInterface() 
+    {
+        getPduRecorder().stop();     // handles disNetworkInterface.close(), tears down threads and sockets
+        disNetworkInterface.close(); // make sure
     }
 
     /** 
@@ -242,42 +270,68 @@ public class DisChannel
             System.exit(1);
         }
     }
+
     /** 
-     * Send a single Protocol Data Unit (PDU) of any type following time delay
-     * @param delayTimeMilliseconds delay before sending
+     * Send a single Protocol Data Unit (PDU) of any type after setting given timestamp
+     * @param disTimeStamp timestamp for this PDU
      * @param pdu the pdu to send
      */
-    public void sendSinglePduDelayed(long delayTimeMilliseconds, Pdu pdu)
+    public void sendSinglePdu(int disTimeStamp, Pdu pdu)
     {
+        if (getDisNetworkInterface() == null)
+            setUpNetworkInterface(); // ensure connected
         try
         {
-            Thread.sleep(delayTimeMilliseconds);
-        }
-        catch (InterruptedException ie)
+            pdu.setTimestamp(disTimeStamp);
+            getDisNetworkInterface().send(pdu);
+            Thread.sleep(100); // TODO consider refactoring the wait logic and moving externally
+        } 
+        catch (InterruptedException ex)
         {
-            System.err.println(ie);
+            System.err.println(this.getClass().getSimpleName() + " Error sending PDU: " + ex.getLocalizedMessage());
+            System.exit(1);
         }
-        sendSinglePdu(pdu);
+    }
+    /** 
+     * Send a single Protocol Data Unit (PDU) of any type following a real-time delay
+     * @param pdu the pdu to send
+     * @param delayTimeMilliseconds delay before sending
+     */
+    public void sendSinglePduDelayed(Pdu pdu, long delayTimeMilliseconds)
+    {
+        // https://stackoverflow.com/questions/4044726/how-to-set-a-timer-in-java
+        Timer timer = new Timer();
+        
+        timer.schedule(new TimerTask() 
+        {
+            @Override
+            public void run()
+            {
+                sendSinglePdu(pdu);
+            }
+        }, delayTimeMilliseconds);
     }
 
     /** 
-     * Send a single Protocol Data Unit (PDU) of any type following time delay
-     * @param delayTimeSeconds delay before sending
+     * Send a single Protocol Data Unit (PDU) of any type following a real-time delay
      * @param pdu the pdu to send
+     * @param delayTimeSeconds delay before sending
      */
-    public void sendSinglePduDelayed(double delayTimeSeconds, Pdu pdu)
+    public void sendSinglePduDelayed(Pdu pdu, double delayTimeSeconds)
     {
         long delayTimemilliseconds = (long)(delayTimeSeconds * 1000);
-        sendSinglePduDelayed(delayTimemilliseconds, pdu);
+        sendSinglePduDelayed(pdu, delayTimemilliseconds);
     }
     /**
-     * Send Comment PDU
+     * Send Comment PDU using given DIS timestamp
+     * @param disTimeStamp     timestamp for this PDU
      * @param commentType    enumeration value describing purpose of the narrative comment
      * @param comments       String array of narrative comments
      * @see VariableRecordType for other potential CommentPdu type enumerations.
      * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments
      */
-    public void sendCommentPdu(VariableRecordType commentType,
+    public void sendCommentPdu(int disTimeStamp,
+                               VariableRecordType commentType,
                                      // vararg... variable-length set of String comments can optionally follow
                                         String... comments)
     {
@@ -301,53 +355,70 @@ public class DisChannel
                 // now build the commentPdu from these string inputs, thus constructing a narrative entry
                 @SuppressWarnings("CollectionsToArray")
                 CommentPdu commentPdu = getPduFactory().makeCommentPdu(commentType, newCommentsList.toArray(new String[0])); // comments);
+                commentPdu.setTimestamp(disTimeStamp);
                 sendSinglePdu(commentPdu);
-                if (isVerboseComments())
+                if (isVerboseComments()) // narrative report
                 {
-                    printlnTRACE("*** [CommentPdu narrative sent: " + commentType.name() + "] " + newCommentsList.toString());
+                    printlnTRACE("*** [CommentPdu " + commentType.name() + "] " + newCommentsList.toString());
                     System.out.flush();
                 }
             }
         }
     }
+    /**
+     * Send Comment PDU using current DIS timestamp
+     * @param commentType      enumeration value describing purpose of the narrative comment
+     * @param comments         String array of narrative comments
+     * @see VariableRecordType for other potential CommentPdu type enumerations.
+     * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments
+     */
+    public void sendCommentPdu(VariableRecordType commentType,
+                                     // vararg... variable-length set of String comments can optionally follow
+                                        String... comments)
+    {
+        sendCommentPdu (DisTime.getCurrentDisTimestamp(), commentType, comments);
+    }
+
     /** 
      * Send Comment PDU following time delay
-     * @param delayTimeMilliseconds delay before sending
      * @param commentType    enumeration value describing purpose of the narrative comment
+     * @param delayTimeMilliseconds delay before sending
      * @param comments       String array of narrative comments
      * @see VariableRecordType for other potential CommentPdu type enumerations.
      * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments
      */
-    public void sendCommentPduDelayed(long delayTimeMilliseconds,
-                                      VariableRecordType commentType,
+    public void sendCommentPduDelayed(VariableRecordType commentType,
+                                      long delayTimeMilliseconds,
                                       // vararg... variable-length set of String comments can optionally follow
                                       String... comments)
     {
-        try
-        {
-            Thread.sleep(delayTimeMilliseconds);
-        }
-        catch (InterruptedException ie)
+        // https://stackoverflow.com/questions/4044726/how-to-set-a-timer-in-java
+        Timer timer = new Timer();
+        
+        timer.schedule(new TimerTask() 
         {
-            System.err.println(ie);
-        }
-        sendCommentPdu(commentType, comments);
+            @Override
+            public void run()
+            {
+                sendCommentPdu(commentType, comments);
+            }
+        }, delayTimeMilliseconds);
     }
     /** 
      * Send Comment PDU following time delay
-     * @param delayTimeSeconds delay before sending
      * @param commentType    enumeration value describing purpose of the narrative comment
+     * @param delayTimeSeconds delay before sending
      * @param comments       String array of narrative comments
      * @see VariableRecordType for other potential CommentPdu type enumerations.
      * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments
      */
-    public void sendCommentPduDelayed(double delayTimeSeconds,
-                                      VariableRecordType commentType,
+    public void sendCommentPduDelayed(VariableRecordType commentType,
+                                      double delayTimeSeconds,
                                       // vararg... variable-length set of String comments can optionally follow
                                       String... comments)
     {
         long delayTimemilliseconds = (long)(delayTimeSeconds * 1000);
-        sendCommentPduDelayed(delayTimemilliseconds, commentType, comments);
+        sendCommentPduDelayed(commentType, delayTimemilliseconds, comments);
     }
 
     /**
@@ -468,4 +539,36 @@ public class DisChannel
         if (simulationManager != null)
             simulationManager.setDescriptor(descriptor);
     }
+
+    /**
+     * @return the verboseDisNetworkInterface
+     */
+    public boolean isVerboseDisNetworkInterface() {
+        return verboseDisNetworkInterface;
+    }
+
+    /**
+     * @param verboseDisNetworkInterface the verboseDisNetworkInterface to set
+     */
+    public void setVerboseDisNetworkInterface(boolean verboseDisNetworkInterface) {
+        this.verboseDisNetworkInterface = verboseDisNetworkInterface;
+        if (disNetworkInterface != null)
+            disNetworkInterface.setVerbose(verboseDisNetworkInterface);
+    }
+
+    /**
+     * @return the verbosePduRecorder
+     */
+    public boolean isVerbosePduRecorder() {
+        return verbosePduRecorder;
+    }
+
+    /**
+     * @param verbosePduRecorder the verbosePduRecorder to set
+     */
+    public void setVerbosePduRecorder(boolean verbosePduRecorder) {
+        this.verbosePduRecorder = verbosePduRecorder;
+        if (pduRecorder != null)
+            pduRecorder.setVerbose(verbosePduRecorder);
+    }
 }