public static DialerMessage FromRaw(String data)
 {
     MessageHeader header = MessageHeader.FromString(data.Substring(0, 55));
     DialerMessage result = null;
     String[] segments = data.Substring(56).Split((char)MessageSeperator.Delimiter);
     Array.ForEach(segments, a => a = a.Replace(((char)MessageSeperator.Delimiter).ToString(), ""));
     string typeName = "Dialer.Communication.Messages." + header.Name.Replace("AGT", "");
     if (Type.GetType(typeName) != null && header.Type == MessageType.Data)
     {
         ConstructorInfo ci = Type.GetType(typeName).GetConstructor(Type.EmptyTypes);
         result = ci.Invoke(null) as DialerMessage;
     }
     else
         result = new DialerMessage();
     result.Header = header;
     result.Message = data;
     result.Segments = segments.ToList();
     result.Parse(segments.Skip(2).ToList());
     return result;
 }
        /// <summary>
        /// A notification was received from the dialer so handle which kind.
        /// </summary>
        /// <param name="response">The structured data received from the dialer</param>
        /// <returns>Whether the notification was handled or not</returns>
        private bool HandleNotification(DialerMessage response)
        {
            bool handled = true;

            //The agent hung up the headset without logging off
            if (response.Header.Name == "AGTHeadsetConnBroken")
            {
                //Bubble the message to the presentation layer
                OnNewMessage("NOTICE: Headset connection broke.  Logoff process beginning.", false);
                //Start the logoff process
                Agent.MoveToState(AgentState.LoggedOff, true);
            }
            //An information message was received from the supervisor.  This is not a system message delivery mechanism
            else if (response.Header.Name == "AGTReceiveMessage")
            {
                //Bubble the message to the presentation layer
                OnNewMessage("NOTICE: New message from supervisor to follow.", false);
                //Pull out the actual message received
                OnNewMessage(response.Segments.ToList()[1], false);
            }
            //The job we are currently attached to is ending.  Begin detach process
            else if (response.Header.Name == "AGTJobEnd")
            {
                //Bubble the message to the presentation layer
                OnNewMessage("NOTICE: The current job has ended.", false);
                //Start the detach process
                Agent.MoveToState(AgentState.LoggedOn, true);
            }
            //System error received.  This is usually detramental
            else if (response.Header.Name == "AGTSystemError")
            {
                //Pull out the message the dialer is sending
                string message = response.Segments.ToList()[1];

                //Bubble the message to the user
                OnNewMessage("NOTICE: System error reported. Message to follow.", false);
                OnNewMessage(message, true);

                //Check to see if it was a command that failed.
                Command pendingCommand = null;
                lock (((ICollection)_waitingCommands).SyncRoot)
                    pendingCommand = _waitingCommands.FirstOrDefault(c => message.Contains(c.Header.Name));
                //If so, end the command
                if (pendingCommand != null)
                    pendingCommand.Finished.Set();
            }
            else if (response.Header.Name == "AGTAutoReleaseLine")
            {
                OnNewMessage("The line has been disconnected.", false);
                Agent.MoveToState(AgentState.Disconnected);
            }
            //A new call was received in the format expected
            else if (response.Header.Name == "AGTCallNotify")
            {
                OnNewMessage(response);
                if (response.Segments[1] == "M00000")
                    OnNewMessage("NOTICE: Call received", false);
            }
            //We dont have a method for handling the notification so indicate that
            else
                handled = false;

            //Return if we handled the notification or not
            return handled;
        }
        private bool HandleError(DialerMessage response)
        {
            List<string> segments = new List<string>(response.Segments);
            string[] details = segments[1].Split(',');
            string[] data = new string[details.Length - 1];
            Array.Copy(details, 1, data, 0, data.Length);

            XElement message =
                (from m in _messagesDocument.Descendants("message")
                 where (string)m.Attribute("code") == details[0]
                 select m).FirstOrDefault();

            if (message != null)
            {
                response.Message = message.Descendants("source").Where(d => (string)d.Attribute("name") == response.Header.Name).Select(v => v.Value).FirstOrDefault();
                if (string.IsNullOrEmpty(response.Message))
                    response.Message = message.Descendants("source").Where(d => (string)d.Attribute("name") == "default").Select(v => v.Value).FirstOrDefault();
            }

            return message != null;
        }