// Connects to the AicServer and listens for messages
        private void Listener_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = (BackgroundWorker)sender;

            while (!worker.CancellationPending)
            {
                #region Connect to server
                while (!worker.CancellationPending && mTcpClient == null)
                {
                    Connect();
                    var connectionStatusChangedEventArgs = new ConnectionStatusChangedEventArgs();
                    connectionStatusChangedEventArgs.ConnectedToServer     = mTcpClient != null;
                    connectionStatusChangedEventArgs.CurrentReconnectCount = mCurrentReconnectCount;
                    worker.ReportProgress(0, connectionStatusChangedEventArgs);
                    if (mTcpClient == null)
                    {
                        Thread.Sleep(5000);
                    }
                }
                #endregion

                #region Listen to server
                while (!worker.CancellationPending && mTcpClient != null)
                {
                    Thread.Sleep(200);                                  // Prevent high cpu usage

                    // Check last connection and send a keepalive message if necessary
                    if (ConnectivityTimeoutExceeded)
                    {
                        var aicMessage = new AicMessage();
                        aicMessage.MessageType = MessageType.KeepAlive;
                        try
                        {
                            Send(aicMessage);
                        }
                        catch (Exception ex)
                        {
                            Log.GetInstance().LogError("Error in sending keepalive.", ex);
                            Disconnect();
                            break;
                        }
                        LastConnectivity = DateTime.Now;
                    }

                    // Get stream and check if it contains data
                    bool dataAvailable;
                    try
                    {
                        if (mTcpClient == null)
                        {
                            throw new Exception("mTcpClient is null.");
                        }
                        dataAvailable = mTcpClient.GetStream().DataAvailable;
                    }
                    catch (Exception ex)
                    {
                        Disconnect();
                        Log.GetInstance().LogError("Error in getting stream and checking if data is available.", ex);
                        break;
                    }

                    // Read stream data
                    if (dataAvailable)
                    {
                        Log.GetInstance().LogInformation("Received a message from AIC server.");
                        LastConnectivity = DateTime.Now;
                        AicMessage aicMessage = null;
                        try
                        {
                            // Deserialize stream
                            using (var ms = mTcpClient.ReadNetworkStream(AicMessage.XmlEndTagRegex))
                            {
                                ms.Position = 0;
                                aicMessage  = AicMessage.Deserialize(ms);
                            }
                        }
                        catch (Exception ex)
                        {
                            bool connectionOk = CheckConnection();
                            if (!connectionOk)
                            {
                                Disconnect();
                                break;
                            }
                            Log.GetInstance().LogError("Error in deserializing network stream.", ex);
                        }

                        if (aicMessage != null)
                        {
                            // Only report AicMessage if it is a request or a response
                            if (aicMessage.MessageType == MessageType.Request || aicMessage.MessageType == MessageType.Response)
                            {
                                worker.ReportProgress(0, new MessageReceivedEventArgs(aicMessage));
                            }

                            #region Send response

                            if (aicMessage.MessageType == MessageType.Request || aicMessage.MessageType == MessageType.KeepAlive)
                            {
                                try
                                {
                                    string msg      = string.Empty;
                                    var    response = new AicMessage();
                                    if (aicMessage.MessageType == MessageType.Request)
                                    {
                                        msg             = "response";
                                        response.Alarms = aicMessage.Alarms;
                                        response.ConnectionWasToServerOk = aicMessage.ConnectionWasToServerOk;
                                        response.MessageType             = MessageType.Response;
                                    }
                                    else if (aicMessage.MessageType == MessageType.KeepAlive)
                                    {
                                        msg = "keepalive";
                                        response.MessageType = MessageType.KeepAlive;
                                    }

                                    Send(response);
                                    Log.GetInstance().LogInformation("Sent " + msg + " to AIC server.");
                                }
                                catch (Exception ex)
                                {
                                    Log.GetInstance().LogError("Error in sending response/keepalive.", ex);
                                }
                            }

                            #endregion
                        }
                    }
                }
                #endregion
            }
            e.Cancel = worker.CancellationPending;
        }