/// <summary>
        /// Handles and accepts all incoming connections.
        /// </summary>
        /// <param name="result"></param>
        private void HandleIncomingConnection(IAsyncResult result)
        {
            try
            {
                Socket oldSocket = (Socket)result.AsyncState;

                if (acceptIncomingConnections)
                {
                    Socket newSocket = oldSocket.EndAccept(result);

                    uint   clientID = clientCount++;
                    Client client   = new Client(clientID, (IPEndPoint)newSocket.RemoteEndPoint);
                    clients.Add(newSocket, client);

                    ClientConnected(client);

                    //Send the other client an authentication request
                    TransferCommandObject m = new TransferCommandObject();
                    m.Command = "Login";
                    m.Value   = "x_891$UI.()";
                    SendDataObjectToSocket(0x1B, newSocket, ClientServerPipeline.BufferSerialize(m));

                    serverSocket.BeginAccept(new AsyncCallback(HandleIncomingConnection), serverSocket);
                }
                else
                {
                    ConnectionBlocked((IPEndPoint)oldSocket.RemoteEndPoint);
                }
            }

            catch (Exception e)
            {
                WriteLine(e.Message, ConsoleColor.Red);
            }
        }
        /// <summary>
        /// Receives and processes data from a socket.
        /// It triggers the message received event in
        /// case the client pressed the return key.
        /// </summary>
        private void ReceiveData(IAsyncResult result)
        {
            try
            {
                Socket clientSocket = (Socket)result.AsyncState;
                Client client       = GetClientBySocket(clientSocket);

                int bytesReceived = clientSocket.EndReceive(result);

                // guidelines for the received data:
                // first byte is check:
                //											0x1A: Response
                //											0x1B: Command
                //											0x1C: Data
                // second byte is data length:
                //											0x01: 1x 2029 bytes sets
                //											0x1B: 27x 2029 bytes sets
                //											0x22: 34x 2029 bytes sets etc...
                // third byte is series:
                //											0x01: 1/N byte set
                //											0x1A: 26/N byte set etc...
                // the next 16 bytes are unique id:
                //											0x00112233445566778899AABBCCDDFF00
                if (bytesReceived == 0)
                {
                    CloseSocket(clientSocket);
                    serverSocket.BeginAccept(new AsyncCallback(HandleIncomingConnection), serverSocket);
                }
                else if (client.Data[0] == 0x1A || client.Data[0] == 0x1B || client.Data[0] == 0x1C) //less than the max byte check
                {
                    int  length = client.Data[1];
                    int  series = client.Data[2];
                    Guid guid   = new Guid(client.Data.SubArray(3, 16)).ToLittleEndian();

                    DataBufferModel buffer = Buffers.FirstOrDefault(n => n.DataId == guid);
                    if (buffer != null)
                    {
                        buffer.BufferedData.Add(series, client.Data.SubArray(19, 2028));
                        buffer.LatestSeries = series;
                    }
                    else
                    {
                        //create a new buffer
                        buffer = new DataBufferModel();
                        buffer.BufferedData.Add(series, client.Data.SubArray(19, 2028));
                        buffer.DataId       = guid;
                        buffer.SeriesLength = length;
                        buffer.LatestSeries = series;
                        Buffers.Add(buffer);
                    }
                    WriteLine($"Received data with id: {guid.ToString()}", ConsoleColor.Magenta);
                    if (buffer.BufferedData.Count == buffer.SeriesLength)
                    {
                        bool handled = false;
                        switch (client.Data[0])
                        {
                        case 0x1A:
                            handled = HandleIncomingData(ClientServerPipeline.BufferDeserialize(buffer), client, DataEventType.RESPONSE);
                            break;

                        case 0x1B:
                            handled = HandleIncomingData(ClientServerPipeline.BufferDeserialize(buffer), client, DataEventType.COMMAND);
                            break;

                        case 0x1C:
                            handled = HandleIncomingData(ClientServerPipeline.BufferDeserialize(buffer), client, DataEventType.DATA);
                            break;
                        }
                        if (handled)
                        {
                            //remove the id from the buffer, else report it and set it up for future handling
                            //TODO: this^
                        }
                    }
                }
                client.Data = new byte[2048];
                clientSocket.BeginReceive(client.Data, 0, dataSize, SocketFlags.None, new AsyncCallback(ReceiveData), clientSocket);
            }
            catch (SocketException e)
            {
                Socket clientSocket = (Socket)result.AsyncState;
                Client client       = GetClientBySocket(clientSocket);
                KickClient(client);
            }
            catch (Exception e)
            {
                WriteLine($"Error occured: {e.Message}", ConsoleColor.Red);
            }
        }