/// <summary>
        /// Creates a deep copy, replacing the specified parameters.
        /// </summary>
        /// <param name="name">The new name for the copy.</param>
        /// <param name="data">The new data for the copy.</param>
        /// <returns>A copy of the event.</returns>
        /// <remarks>
        /// A common design pattern is to queue data event copies, each with its own unique data payload, to state machines for handling.
        /// </remarks>
        public NSFDataEvent <DataType> copy(NSFString name, DataType data)
        {
            NSFDataEvent <DataType> eventCopy = copy(data);

            eventCopy.Name = name;
            return(eventCopy);
        }
        /// <summary>
        /// Creates a deep copy, replacing the specified parameters.
        /// </summary>
        /// <param name="source">The new source for the copy.</param>
        /// <param name="destination">The new destination for the copy.</param>
        /// <param name="data">The new data for the copy.</param>
        /// <returns>A copy of the event.</returns>
        /// <remarks>
        /// A common design pattern is to queue data event copies, each with its own unique data payload, to state machines for handling.
        /// </remarks>
        public NSFDataEvent <DataType> copy(INSFNamedObject source, INSFEventHandler destination, DataType data)
        {
            NSFDataEvent <DataType> eventCopy = copy(data);

            eventCopy.Source      = source;
            eventCopy.Destination = destination;
            return(eventCopy);
        }
        /// <summary>
        /// Creates a debug utility.
        /// </summary>
        public NSFDebugUtility()
            : base("DebugUtility")
        {
            eventHandler            = new NSFEventHandler(Name, new NSFEventThread(Name, NSFOSThread.LowestPriority));
            writeToConsoleEvent     = new NSFDataEvent <NSFString>("WriteToConsole", eventHandler);
            writeLineToConsoleEvent = new NSFDataEvent <NSFString>("WriteLineToConsole", eventHandler);

            eventHandler.LoggingEnabled = false;
            eventHandler.addEventReaction(writeToConsoleEvent, performWriteToConsole);
            eventHandler.addEventReaction(writeLineToConsoleEvent, performWriteLineToConsole);
            eventHandler.startEventHandler();
        }
        /// <summary>
        /// Creates a trace log
        /// </summary>
        /// <param name="name">The name of the log.</param>
        /// <remarks>
        /// By default, thread priority is set to lowest.
        /// </remarks>
        public NSFTraceLog(NSFString name)
            : base(name)
        {
            eventHandler = new NSFEventHandler(Name, new NSFEventThread(Name, NSFOSThread.LowestPriority));
            eventHandler.LoggingEnabled = false;

            traceAddEvent  = new NSFDataEvent <NSFXMLElement>(TraceAddString, eventHandler);
            traceSaveEvent = new NSFDataEvent <NSFString>(TraceSaveString, eventHandler);

            eventHandler.addEventReaction(traceAddEvent, addTraceToLog);
            eventHandler.addEventReaction(traceSaveEvent, saveTrace);

            eventHandler.startEventHandler();

            addTrace(NSFTraceTags.InformationalTag, NSFTraceTags.NameTag, "TraceStart");
        }
 /// <summary>
 /// Creates event that can have a data payload.
 /// </summary>
 /// <param name="nsfEvent">The event to copy.</param>
 public NSFDataEvent(NSFDataEvent <DataType> nsfEvent)
     : base(nsfEvent)
 {
     Data = nsfEvent.Data;
 }
 /// <summary>
 /// Creates event that can have a data payload.
 /// </summary>
 /// <param name="nsfEvent">The event to copy.</param>
 /// <param name="data">The data of the event.</param>
 public NSFDataEvent(NSFDataEvent <DataType> nsfEvent, DataType data)
     : base(nsfEvent)
 {
     Data = data;
 }