/// <summary>
        /// Starts listening to the WAS.
        /// <exception cref="InvalidOperationException">Thrown when the WAS listener is running.</exception>
        /// <exception cref="InvalidOperationException">Thrown when the reconnect process is currently running.</exception>
        /// <exception cref="AicException">If the ping to the WAS failed.</exception>
        /// </summary>
        public void StartWasListening()
        {
            lock (this.mLockerObject)
            {
                if (this.IsWasListenerRunning)
                {
                    this.mLogger.LogError("WAS listener is already running", ErrorType.ListeningManager_WasListenerAlreadyRunning);
                    throw new InvalidOperationException("WAS listener is already running");
                }

                if (this.mIsWasReconnectRunning)
                {
                    this.mLogger.LogError("The WAS reconnect process is currently running", ErrorType.ListeningManager_WasReconnectCurrentlyRunning);
                    throw new InvalidOperationException("The WAS reconnect process is currently running");
                }

                // Check if the WAS can be pinged
                if (!Network.PingAddress(AicSettings.Global.WasIp))
                {
                    this.mLogger.LogWarning("WAS can't be pinged", WarningType.ListeningManager_CantPingWas);
                    throw new AicException("WAS can't be pinged", AicExceptionType.ListeningManager_CantPingWas);
                }

                try
                {
                    // isShutdown: True if the broken connection is forced (due to shutdown)
                    this.mWasListener.WasConnectionStateChanged += delegate(bool connected, bool isShutdown)
                    {
                        this.mLogger.LogInformation(string.Format("WAS connection-state changed (Connected: {0} - Shutdown: {1})", connected, isShutdown), InformationType.ListeningManager_WasConnectionStateChanged);

                        lock (this.mLockerObject)
                        {
                            this.mIsWasListenerRunning = connected;

                            if (this.WasConnectionStateChanged != null)
                            {
                                this.WasConnectionStateChanged(connected);
                            }

                            if (MessageReceived != null)
                            {
                                var aicMessage = new AicMessage {
                                    Alarms = mAlarmState.Alarms, ConnectionWasToServerOk = connected
                                };
                                var args = new MessageReceivedEventArgs(aicMessage);
                                MessageReceived(null, args);
                            }

                            if (!connected && !isShutdown)
                            {
                                // Broken connection (not forced)
                                this.mLogger.LogWarning("WAS connection got broken", WarningType.ListeningManager_BrokenWasConnection);
                                this.TryWASReconnect();
                            }
                        }

                        if (this.mClientListener != null)
                        {
                            // Push new state of the backend to the clients
                            this.mClientListener.PushNewState();
                        }
                    };

                    this.mWasListener.WasObjectChanged += delegate(WasObject obj)
                    {
                        this.mLogger.LogInformation("New WAS-Data available", InformationType.ListeningManager_NewWasDataAvailable);

                        this.mAlarmState.UpdateAlarmObject(obj);

                        if (this.AlarmsChanged != null)
                        {
                            this.AlarmsChanged(this.mAlarmState.Alarms);
                        }

                        if (MessageReceived != null)
                        {
                            var aicMessage = new AicMessage {
                                Alarms = mAlarmState.Alarms, ConnectionWasToServerOk = true
                            };
                            var args = new MessageReceivedEventArgs(aicMessage);
                            MessageReceived(null, args);
                        }

                        if (AicSettings.Global.UploadEnabled)
                        {
                            this.mAlarmState.Alarms.ForEach(alarm =>
                                                            AlarmSend.SendAsync(AicSettings.Global.UploadUrl, alarm, (id, ex) => { this.mLogger.LogError("Error while uploading alarm (ID:" + id + ")!", ex); }));
                        }

                        if (this.mClientListener != null)
                        {
                            this.mClientListener.PushNewState();
                        }
                    };

                    this.mWasListener.StartListening();

                    this.mIsWasListenerRunning = true;
                }

                catch (Exception ex)
                {
                    this.mLogger.LogError("(ListeningManager/StartWasListening/Exception)", ErrorType.Undefined, ex);
                    throw ex;
                }
            }
        }