/// <summary>
        /// The Start
        /// </summary>
        /// <param name="port">The port<see cref="int"/></param>
        /// <returns>The <see cref="Task"/></returns>
        public async Task Start(int port = 8990)
        {
            Port = port;
            if (started)
            {
                Console.WriteLine("WebSocket server already started");
                return;
            }

            started = true;
            TcpListener listener = new TcpListener(IPAddress.Any, port);

            listener.Start();
            Console.WriteLine("WebSocket server started");

            while (true)
            {
                Console.WriteLine("Waiting for new connection..");
                var client = new WebSocketClient(await listener.AcceptTcpClientAsync());

                m_connectedClients.Add(client);

                Console.WriteLine($"New client from {client.RemoteEndPoint}");
                Console.WriteLine($"Actually there are {m_connectedClients.Count} connected");

#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                Task.Factory.StartNew(() =>
                {
                    client.Handshake += onClientHandshake;
                    client.Message   += onClientMessage;

                    client.StartListen().ContinueWith((o) =>
                    {
                        m_connectedClients.Remove(client);
                        client.Dispose();
                        Console.WriteLine($"Client removed, now there are {m_connectedClients.Count} connected");
                    });
                });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            }
        }
        /// <summary>
        /// The onClientMessage
        /// </summary>
        /// <param name="sender">The sender<see cref="WebSocketClient"/></param>
        /// <param name="e">The e<see cref="WebSocketDataEventArgs"/></param>
        private void onClientMessage(WebSocketClient sender, WebSocketDataEventArgs e)
        {
            /*
             * Parse message as described in
             * https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_server#collapse-3
             */

            var byte1 = e.Data[0]; // should be 129 for text

            var received = getBytesBit(byte1);
            var opCode   = convertBitArrayToNumber(new[] { received[4], received[5], received[6], received[7] });

#if FULL_LOG
            Console.WriteLine($"{received[0]} - FIN");
            Console.WriteLine($"{received[1]} - RSV1");
            Console.WriteLine($"{received[2]} - RSV2");
            Console.WriteLine($"{received[3]} - RSV3");
            Console.WriteLine($"{opCode} - Opcode");
#endif
            try
            {
                switch (opCode)
                {
                case 0x0:
                    Console.WriteLine($"Received unmanaged `binary` from client {sender.RemoteEndPoint}");
                    break;    // denotes a continuation frame

                case 0x1:     // denotes a text frame
                    Console.WriteLine($"Received `text` from client {sender.RemoteEndPoint}");
                    manageTextReceived(sender, e.Data);
                    break;

                case 0x2: break;     // reserved for further non-control frames

                case 0x3: break;

                case 0x4: break;

                case 0x5: break;

                case 0x6: break;

                case 0x7: break;

                case 0x8:
                    Console.WriteLine($"Received `close connection` from client {sender.RemoteEndPoint}");
                    sender.Dispose();
                    break;    // denotes a connection close

                case 0x9:
                    Console.WriteLine($"Received `ping` from client {sender.RemoteEndPoint}, send `pong`");
                    SendPong(sender);
                    break;    // denotes a ping

                case 0xA:
                    Console.WriteLine($"Received `pong` from client {sender.RemoteEndPoint}, it's alive");
                    break;       // denotes a pong

                case 0xB: break; //reserved for further control frames

                case 0xC: break;

                case 0xD: break;

                case 0xE: break;

                case 0xF: break;

                default:
                    Console.WriteLine($"Received unknown opcode `{opCode}`. Close connection.");
                    sender.Dispose();
                    break;
                }
            }
            catch (Exception)
            {
                sender.Dispose();
            }
        }