@Override
    public void run() {
        try {
            try {
                Logger.loginfo("Client started");
                try {
                    ConnectToServer();
                } catch (IOException e) {
                    Logger.logexception(e, "Cannot connect to server");
                    nv.popupMessage("Couldn't connect to "
                            + Settings.getInstance().getClientConnectAddr()
                            + ":"
                            + Settings.getInstance().getClientConnectPort());
                    return;
                }

                // TODO: fix: handle rejected player name
                nv.gameStarted();
                Logger.loginfo("Connected to server");
                while (!interrupted() && serverIsAlive) {
                    try {
                        Command cmd = nc.readCommand();
                        ClientCommandVisitor ccv = new ClientCommandVisitor(
                                game, game);
                        cmd.accept(ccv);
                    } catch (SocketTimeoutException e) {
                    } catch (SocketClosedException e) {
                        serverIsAlive = false;
                        Logger.loginfo("Server closed connection");
                        if (!game.isEnded()) {
                            nv.popupMessage("The server closed the connection");
                        }
                    } catch (IOException e) {
                        Logger.logexception(e, "Couldn't read Command");
                        serverIsAlive = false;
                        nv.popupMessage("The connection to the server has lost because of an unknown error");
                    }
                }
            } finally {
                onExit();
            }
        } catch (Exception e) {
            Logger.logexception(e, "Unhandled exception");
        }
    }