/// <summary>
        /// Process our data
        /// </summary>
        /// <param name="state"></param>
        private static void ProcessData(object state)
        {
            object[] InVals     = (object[])state;
            String[] InLines    = (string[])InVals[0];
            Type     TargetType = (Type)InVals[1];

            PropertyInfo[] HeaderInfo = (PropertyInfo[])InVals[2];
            try
            {
                if (TargetType != null)
                {
                    Array OutList = Array.CreateInstance(TargetType, InLines.Length);
                    for (int a = 0; a < InLines.Length; a++)
                    {
                        OutList.SetValue(MM_Serialization.Deserialize(HeaderInfo, InLines[a].Split(','), Activator.CreateInstance(TargetType)), a);
                    }
                    MM_EMS_Data_Updater.ProcessUpdate(TargetType, OutList);
                    OutList = null;
                }
            }
            catch (Exception ex)
            {
                MM_Notification.WriteLine(ConsoleColor.Red, "Error sending {0} data: {1}", (TargetType == null ? "UNKNOWN" : TargetType.Name), ex);
            }
        }
 /// <summary>
 /// Update our unit control status data
 /// </summary>
 /// <param name="Status"></param>
 /// <returns></returns>
 public bool UpdateUnitControlStatusInformation(MM_Unit_Control_Status Status)
 {
     //First, update our dictionary with our status information
     User.LastReceivedMessage = DateTime.Now;
     MM_EMS_Data_Updater.ProcessUpdate(typeof(MM_Unit_Control_Status), new MM_Unit_Control_Status[] { Status });
     return(true);
 }
        /// <summary>
        /// Process a stream, reading and parsing its content
        /// </summary>
        /// <param name="InLines"></param>
        /// <param name="FileName"></param>
        public static void ProcessStreamRead(StreamReader sRd, String FileName, Type TargetType, ref DateTime LatestBatchID)
        {
            //Now, parse our stream
            IList OutList = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(TargetType));

            //Read our header
            String FirstLine = sRd.ReadLine().TrimStart('#').TrimEnd(',');

            String[] HeaderLine;
            Double   ProperDate;
            DateTime BatchId = DateTime.Now;

            if (Double.TryParse(FirstLine, out ProperDate))
            {
                BatchId    = new DateTime(1970, 1, 1).AddSeconds(ProperDate);
                HeaderLine = sRd.ReadLine().TrimStart('#').Split(',');
            }
            else
            {
                HeaderLine = FirstLine.Split(',');
            }

            if (BatchId < LatestBatchID)
            {
                MM_Notification.WriteLine(ConsoleColor.Red, "Aborting {0} Batch {1} because it's older than {1}", FileName, BatchId, LatestBatchID);
                return;
            }
            else
            {
                LatestBatchID = BatchId;
            }

            PropertyInfo[] HeaderInfo = MM_Serialization.GetHeaderInfo(TargetType, HeaderLine);
            for (int a = 0; a < HeaderLine.Length; a++)
            {
                if (HeaderInfo[a] == null)
                {
                    MM_Notification.WriteLine(ConsoleColor.Yellow, "Unknown variable {0} in {1}", HeaderLine[a], FileName);
                }
            }

            //Confirm all of our headers are present
            foreach (PropertyInfo pI in TargetType.GetProperties())
            {
                if (Array.FindIndex <String>(HeaderLine, T => T.Equals(pI.Name, StringComparison.CurrentCultureIgnoreCase)) == -1)
                {
                    MM_Notification.WriteLine(ConsoleColor.Yellow, "Missing variable {0} ({1}) in {2} / {3}", pI.Name, pI.PropertyType.Name, TargetType.Name, FileName);
                }
            }

            //Now, read in all of our lines of data, using reflection to store our data
            String InLine;

            while ((InLine = sRd.ReadLine()) != null)
            {
                if (InLine.StartsWith("#"))
                {
                    DateTime EndTime = new DateTime(1970, 1, 1).AddSeconds(Convert.ToDouble(InLine.TrimStart('#').TrimEnd(',')));
                    if (EndTime != BatchId)
                    {
                        MM_Notification.WriteLine(ConsoleColor.Red, "Mismatch date on {0}: Start {1}, End {2}", FileName, BatchId, EndTime);
                    }
                }
                else
                {
                    Object OutObj = MM_Serialization.Deserialize(HeaderInfo, InLine.Split(','), Activator.CreateInstance(TargetType));
                    //if (OutObj is MacomberMapCommunications.Messages.EMS.MM_BreakerSwitch_Data)
                    //{
                    //    MacomberMapCommunications.Messages.EMS.MM_BreakerSwitch_Data bs = (MacomberMapCommunications.Messages.EMS.MM_BreakerSwitch_Data)OutObj;
                    //    if (bs.TEID_CB == 118964)
                    //        MM_Notification.WriteLine(ConsoleColor.Magenta, "   TEID=" + bs.TEID_CB.ToString() + "    status=" + (bs.Open_CB ? "Open" : "Closed"));
                    //}
                    OutList.Add(OutObj);
                }
            }

            //Once our data are done, use the interprocess communication to update our data
            if (TargetType == typeof(MM_EMS_Command))
            {
                MM_Server.EMSCommands.Clear();
                foreach (Object obj in OutList)
                {
                    MM_Server.EMSCommands.Add((MM_EMS_Command)obj);
                }
            }
            else
            {
                MM_EMS_Data_Updater.ProcessUpdate(TargetType, (Array)OutList.GetType().GetMethod("ToArray").Invoke(OutList, null));
            }
            OutList.Clear();
            OutList = null;
        }