private void ListenState()
        {
            NetworkChannel channel = null;

            try
            {
                // Connect
                if (!Connected)
                {
                    State  = DemonState.Restart;
                    Status = DemonStatus.Info;
                    return;
                }

                // NOTE: No need to close the channel
                channel = new NetworkChannel(Connection);
                Status  = DemonStatus.Success;

                // Request
                HttpRequest httpRequest;
                channel.Receive(out httpRequest);
                if (httpRequest == null)
                {
                    Status = DemonStatus.Warning;
                    return;
                }

                // TODO: Version check
                //
                // Message
                SessionComponent session            = Owner.Get <SessionComponent>();
                string           decrypted          = session.Decrypt(httpRequest.Data);
                JsonPacket       jsonRequest        = JsonPacket.Parse(decrypted);
                JsonMessage      jsonRequestMessage = JsonMessage.Parse(jsonRequest.Message);
                JsonType         jsonType           = jsonRequestMessage.Type;

                switch (jsonType)
                {
                case JsonType.Ping:
                {
                    PingResponseCommand command = new PingResponseCommand(Owner, Connection);
                    command.Execute(httpRequest, jsonRequest);
                    break;
                }

                case JsonType.Search:
                {
                    JsonAction action = jsonRequestMessage.Action;

                    switch (action)
                    {
                    case JsonAction.Request:
                    {
                        SearchRequestCommand command = new SearchRequestCommand(Owner, Connection);
                        command.Execute(httpRequest, jsonRequest);
                        break;
                    }

                    case JsonAction.Response:
                    {
                        SearchResponseCommand command = new SearchResponseCommand(Owner, Connection);
                        List <FileComponent>  list    = command.Execute(httpRequest, jsonRequest);
                        OnListAdded(list);
                        break;
                    }

                    default:
                    {
                        channel.SendBadRequest();
                        break;
                    }
                    }

                    break;
                }

                case JsonType.Browse:
                {
                    BrowseResponseCommand command = new BrowseResponseCommand(Owner, Connection);
                    command.Execute(httpRequest, jsonRequest);
                    break;
                }

                case JsonType.Download:
                {
                    // TODO
                    //
                    DownloadResponseCommand command = new DownloadResponseCommand(Owner, Connection);                            // { Handler = UploadEvent };
                    command.Execute(httpRequest, jsonRequest);
                    break;
                }

                default:
                {
                    channel.SendBadRequest();
                    State  = DemonState.Restart;
                    Status = DemonStatus.Info;
                    return;
                }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Status = DemonStatus.Error;

                if (channel != null)
                {
                    try
                    {
                        channel.SendInternalServerError();
                    }
                    catch (Exception) { }
                }
            }
        }
        private void ProcessState(object obj)
        {
            Socket         socket  = (Socket)obj;
            NetworkChannel channel = null;

            JsonAction action   = JsonAction.None;
            JsonType   jsonType = JsonType.None;

            try
            {
                do
                {
                    // Connect
                    channel = new NetworkChannel(socket);

                    // Receive
                    HttpRequest httpRequest;
                    channel.Receive(out httpRequest);
                    if (httpRequest == null)
                    {
                        channel.SendBadRequest();
                        return;
                    }

                    // Data
                    Status = DemonStatus.Success;

                    // Handshake
                    if (httpRequest.Session == null)
                    {
                        ServerStatusComponent    status  = Owner.Get <ServerStatusComponent>();
                        HandshakeResponseCommand command = new HandshakeResponseCommand(Owner, socket)
                        {
                            Listener = status.Update
                        };
                        command.Execute(httpRequest);
                        break;
                    }

                    // Session
                    SessionMapComponent sessions = Owner.Get <SessionMapComponent>();
                    Entity entity = sessions.Get(httpRequest.Session);
                    if (entity == null)
                    {
                        channel.SendUnauthorized();
                        break;
                    }

                    // TODO: Version check
                    //
                    // Message
                    SessionComponent session            = entity.Get <SessionComponent>();
                    string           decrypted          = session.Decrypt(httpRequest.Data);
                    JsonPacket       jsonRequest        = JsonPacket.Parse(decrypted);
                    JsonMessage      jsonRequestMessage = JsonMessage.Parse(jsonRequest.Message);
                    jsonType = jsonRequestMessage.Type;

                    switch (jsonType)
                    {
                    case JsonType.Handshake:
                    {
                        HandshakeResponseCommand command = new HandshakeResponseCommand(Owner, socket);
                        command.Execute(httpRequest, jsonRequest, session);
                        break;
                    }

                    case JsonType.Ping:
                    {
                        PingResponseCommand command = new PingResponseCommand(Owner, socket);
                        command.Execute(httpRequest, jsonRequest, session);
                        break;
                    }

                    case JsonType.Info:
                    {
                        InfoResponseCommand command = new InfoResponseCommand(Owner, socket);
                        command.Execute(httpRequest, jsonRequest, session);
                        break;
                    }

                    case JsonType.Join:
                    {
                        JoinResponseCommand command = new JoinResponseCommand(Owner, socket);
                        command.Execute(httpRequest, jsonRequest, session);
                        break;
                    }

                    case JsonType.Tunnel:
                    {
                        TunnelResponseCommand command = new TunnelResponseCommand(Owner, socket);
                        command.Execute(httpRequest, jsonRequest, session);
                        break;
                    }

                    case JsonType.Search:
                    {
                        SearchResponseCommand command = new SearchResponseCommand(Owner, socket);
                        command.Execute(httpRequest, jsonRequest, session);
                        break;
                    }

                    case JsonType.Group:
                    {
                        GroupResponseCommand command = new GroupResponseCommand(Owner, socket);
                        command.Execute(httpRequest, jsonRequest, session);
                        break;
                    }

                    case JsonType.Browse:
                    {
                        BrowseResponseCommand command = new BrowseResponseCommand(Owner, socket);
                        command.Execute(httpRequest, jsonRequest, session);
                        break;
                    }

                    case JsonType.Download:
                    {
                        // TODO: Add max transfer check!
                        //
                        DownloadResponseCommand command = new DownloadResponseCommand(Owner, socket);
                        action = command.Execute(httpRequest, jsonRequest, session);
                        break;
                    }

                    case JsonType.Upload:
                    {
                        UploadResponseCommand command = new UploadResponseCommand(Owner, socket);
                        action = command.Execute(httpRequest, jsonRequest, session);
                        break;
                    }

                    case JsonType.Quit:
                    {
                        QuitResponseCommand command = new QuitResponseCommand(Owner, socket);
                        command.Execute(httpRequest, jsonRequest, session);
                        break;
                    }

                    default:
                    {
                        channel.SendBadRequest();
                        return;
                    }
                    }
                }while (action != JsonAction.None);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Status = DemonStatus.Error;
                channel.SendInternalServerError();
            }
            finally
            {
                if (channel != null)
                {
                    channel.Shutdown();
                }

                if (jsonType != JsonType.Tunnel)
                {
                    socket.Shutdown(SocketShutdown.Both);
                    socket.Close();
                }
            }
        }