// === TCP events firing =================================================================================================================================================

        /// Fire the Connected event if it exists.
        protected virtual void OnConnected(TcpServerEventArgs e)
        {
            if (Connected != null)
            {
                try
                {
                    Connected(this, e);
                    // Start Receiving message
                    e.ConnectionState.Connection.BeginReceive(e.ConnectionState.Buffer, 0, e.ConnectionState.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), e.ConnectionState);
                    // Push to array
                    csList.Add(e.ConnectionState);
                }
                catch (Exception ex)
                {
                    // Close the connection if the application threw an exception that is caught here by the server.
                    e.ConnectionState.Close();
                    TcpLibApplicationExceptionEventArgs appErr = new TcpLibApplicationExceptionEventArgs(ex);
                    YucoDebugger.instance.LogError("OnDataReceived: Connected(this, e) encountered exception", "OnConnected", "TCPServer");

                    try
                    {
                        OnHandleApplicationException(appErr);
                        YucoDebugger.instance.LogWarning("OnConnected: OnHandleApplicationException(appErr)", "OnConnected", "TCPServer");
                    }
                    catch (Exception ex2)
                    {
                        // the exception handler threw an exception...
                        YucoDebugger.instance.LogError("OnConnected: ex2" + ex2, "OnConnected", "TCPServer");
                    }
                }
            }
        }
        /// Fire the DataReceived event if it exists.
        protected virtual void OnDataReceived(TcpServerEventArgs e)
        {
            if (DataReceived != null)
            {
                try
                {
                    DataReceived(this, e);
                }
                catch (Exception ex)
                {
                    // Close the connection if the application threw an exception that is caught here by the server.
                    e.ConnectionState.Close();
                    csList.Remove(e.ConnectionState);
                    YucoDebugger.instance.LogError("OnDataReceived: DataReceived(this, e) encountered exception", "OnDataReceived", "TCPServer");
                    TcpLibApplicationExceptionEventArgs appErr = new TcpLibApplicationExceptionEventArgs(ex);

                    try
                    {
                        OnHandleApplicationException(appErr);
                        YucoDebugger.instance.Log("OnDataReceived: OnHandleApplicationException(appErr)", "OnDataReceived", "TCPServer");
                    }
                    catch (Exception ex2)
                    {
                        // the exception handler threw an exception...
                        YucoDebugger.instance.LogError("OnDataReceived: ex2" + ex2, "OnDataReceived", "TCPServer");
                    }
                }
            }
        }
        // === TCP special exception handlers =================================================================================================================================================

        /// Invokes the HandleApplicationException handler, if exists.
        protected virtual void OnHandleApplicationException(TcpLibApplicationExceptionEventArgs e)
        {
            if (HandleApplicationException != null)
            {
                YucoDebugger.instance.LogError("OnHandleApplicationException: " + e, "OnHandleApplicationException", "TCPServer");
                HandleApplicationException(this, e);
            }
        }
        /// Receive string data from connection and invokes any Received event handlers.
        protected void ReceiveCallback(IAsyncResult res)
        {
            ConnectionState cs = (ConnectionState)res.AsyncState;

            try
            {
                int bytesRead = 0;
                lock (this)
                {
                    bytesRead = cs.Connection.EndReceive(res);
                }

                if (bytesRead != 0)
                {
                    //YucoDebugger.instance.LogDebug("bytesRead = " + bytesRead.ToString(), "ReceiveCallback", "TCPServer");
                    // Assign no. of byte read
                    cs.BytesRead = bytesRead;
                    // Get string from data
                    cs.DataString = Encoding.UTF8.GetString(cs.Buffer, 0, bytesRead);
                    // Fire Connected event
                    OnDataReceived(new TcpServerEventArgs(cs));
                    // Begin receiving data
                    lock (this)
                    {
                        cs.Connection.BeginReceive(cs.Buffer, 0, cs.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), cs);
                    }
                }
                else
                {
                    YucoDebugger.instance.LogDebug("bytesRead = 0", "ReceiveCallback", "TCPServer");
                    cs.Close();
                    OnDisconnected(new TcpServerEventArgs(cs));
                }
            }
            catch (Exception ex)
            {
                // Close the connection if the application threw an exception that is caught here by the server.
                cs.Close();
                csList.Remove(cs);
                TcpLibApplicationExceptionEventArgs appErr = new TcpLibApplicationExceptionEventArgs(ex);
                YucoDebugger.instance.LogError("ReceiveCallback: cs.Close()");

                try
                {
                    OnHandleApplicationException(appErr);
                    YucoDebugger.instance.LogWarning("ReceiveCallback: OnHandleApplicationException(appErr)", "ReceiveCallback", "TCPServer");
                }
                catch (Exception ex2)
                {
                    // the exception handler threw an exception...
                    YucoDebugger.instance.LogError("ReceiveCallback: ex2" + ex2, "ReceiveCallback", "TCPServer");
                }
            }
        }