@Override
  public void createLobbyByPlayerID(int playerID, ILobbyInformation lobbyInformation) {

    DebugOutputHandler.printDebug("Player " + playerID + " created a new Lobby");

    int currentPlayerSession = getSessionFromClient(playerID);

    if (currentPlayerSession != NO_LOBBY_ID) return;

    int sessionID =
        createAndAddLobby(
            lobbyInformation.getMaxPlayers(),
            lobbyInformation.getLobbyName(),
            lobbyInformation.getTrackId());

    if (sessionID == NO_LOBBY_ID) {
      return;
    }

    // set new lobby without players but with the right parameters
    setLobbyParameters(sessionID, lobbyInformation);

    // let the player join set new lobby
    joinLobby(playerID, sessionID);
  }
 /**
  * Checks if the lobby is empty and deltes it from the list if necessary
  *
  * @param lobbyID
  */
 private void deleteEmptyLobbies(int lobbyID) {
   DebugOutputHandler.printDebug("Checking for an empty Lobby...");
   if (lobbyID == NO_LOBBY_ID) return;
   Lobby l = lobbyMap.get(lobbyID);
   Player[] playersInLobby = l.getPlayerList();
   boolean deleteLobby = true;
   for (int i = 0; i < playersInLobby.length; i++) {
     if (playersInLobby[i] != null) {
       if (!playersInLobby[i].isDummyPlayer()) deleteLobby = false;
     }
   }
   if (deleteLobby) {
     DebugOutputHandler.printDebug("Found empty Lobby, and deleting it");
     lobbyMap.remove(lobbyID);
   }
 }
  @Override
  public boolean didGameStartById(int playerID) {
    int sessionID = getSessionFromClient(playerID);
    boolean isRunning = lobbyMap.get(sessionID).isGameRunning();

    DebugOutputHandler.printDebug("is game running in session " + sessionID + ": " + isRunning);

    return isRunning;
  }
  /**
   * Creates a new LobbyObject, adds it to the list and sets the lobbyname
   *
   * @param maxPlayers
   * @param lobbyName
   * @param trackID
   * @return
   */
  private int createAndAddLobby(int maxPlayers, String lobbyName, int trackID) {

    DebugOutputHandler.printDebug("A new Lobby has been created");
    Lobby newLobby = new Lobby(++lobbyIdCounter, maxPlayers, lobbyName, trackID, this);
    if (lobbyMap.get(lobbyIdCounter) == null) {
      lobbyMap.put(lobbyIdCounter, newLobby);
      return lobbyIdCounter;
    } else {
      return -1;
    }
  }
  @Override
  public void joinLobby(int playerID, int sessionID) {
    // cant join session -1, to get to session -1 a player needs to leave his lobby and get back
    // to lobby list
    if (sessionID == NO_LOBBY_ID) return;
    // check if the player is already in an other lobby
    int playerSession = getSessionFromClient(playerID);

    if (playerSession == NO_LOBBY_ID) {
      lobbyMap.get(sessionID).addPlayer(getPlayerMap().get(playerID));
      DebugOutputHandler.printDebug(
          "Player "
              + getPlayerMap().get(playerID).getName()
              + " now is in lobby "
              + getPlayerMap().get(playerID).getSessionID());
    }
  }
  /**
   * generates a message object beeing sent to every client in a specific session informing them,
   * that one player disconnects
   *
   * @param playerToDisconnect the player which disconnected
   * @param session the session in which the player dropped
   * @return RaceTrackMessage containing information about the disconnected player, and the next
   *     player to move
   */
  private RaceTrackMessage generateDisconnectMessage(
      int playerToDisconnect, int session, List<Integer> playersInSameSession) {
    RaceTrackMessage answer = null;
    DebugOutputHandler.printDebug(
        "Player: " + playerToDisconnect + " disconnected, sending now a message to each client");

    if (session != NO_LOBBY_ID && lobbyMap.get(session) != null) {
      //			lobbyMap.get(session).playerDisconnected(playerToDisconnect);
      int nextPlayer = lobbyMap.get(session).getNextPlayer();
      answer = new DisconnectMessage(playerToDisconnect, nextPlayer);

      for (int i : playersInSameSession) {
        answer.addClientID(i);
      }
    }

    return answer;
  }
  @Override
  public void setLobbyParametersByPlayerID(int playerID, ILobbyInformation lobbyInformation) {
    // sessionID = lobbyInformation.getSessionID() check for same IDs
    int sessionID = getSessionFromClient(playerID);

    // if lobby changes are valid, only then change them
    if (lobbyMap.get(sessionID).validateInformation(lobbyInformation, playerID)) {

      if (lobbyMap.get(sessionID).updateInformation(lobbyInformation)) {
        int nextPlayer = getNextPlayerToMove(playerID);
        int nextPlayerID = getPlayerIDByGroupPosition(nextPlayer, sessionID);
        moveTimerMap.put(
            sessionID,
            new MoveTimer(nextPlayerID, this, lobbyMap.get(sessionID).getCurrentPlayMode()));
        moveTimerMap.get(sessionID).start();
      }

    } else {

      DebugOutputHandler.printDebug("Administration: Incoming LobbyInformation was not valid");
    }
  }
  @Override
  public void moveClientDefaultVelocity(int playerID) {
    RaceTrackMessage answer = null;

    int sessionID = getSessionFromClient(playerID);

    // Move player and get collisionpoint if there was one
    if (lobbyMap.get(sessionID) != null
        && sessionID != NO_LOBBY_ID
        && getPlayerMap().get(playerID) != null) {

      if (lobbyMap.get(sessionID).isFirstRound()) {
        setRandomStartingPoint(playerID, sessionID);
        return;
      }

      List<Integer> playersInSameSession = null;

      if (getPlayerIdsInSameSession(playerID) != null) {
        playersInSameSession = getPlayerIdsInSameSession(playerID);
      }

      int playerWhoMoved = getGroupPositionByPlayerID(playerID);

      Player player = getPlayerMap().get(playerID);

      if (player.hasCrashed() || !player.isParticipating()) {
        return;
      }

      Point2D collisionPointFromPlayer = lobbyMap.get(sessionID).makeDefaultMoveForPlayer(player);

      Point2D playerPosition = player.getCurrentPosition();

      startNextRoundByPlayerID(playerID);

      int nextPlayerToMove = getNextPlayerToMove(playerID);

      int playerWhoWon = getPlayerWhoWonByPlayerID(playerID);

      boolean didAPlayerWin = playerWhoWon != -1;

      int round = getPlayerRoundByPlayerID(playerID);

      Point2D playerVelocity = getCurrentPlayerVelocityByPlayerID(playerID);

      if (didAPlayerWin) {
        DebugOutputHandler.printDebug("Player " + playerWhoWon + " did win the game.");

        answer =
            VectorMessageServerHandler.generatePlayerWonMessage(
                playerWhoMoved, playerWhoWon, playerPosition);
        closeGameByPlayerID(playerID);

      } else {
        answer =
            VectorMessageServerHandler.generateBroadcastMoveMessage(
                playerWhoMoved,
                playerPosition,
                collisionPointFromPlayer,
                nextPlayerToMove,
                playerVelocity,
                round);
      }

      for (int p : playersInSameSession) answer.addClientID(p);
      // method on lobby and game which just moves the player by his velocity again! not just by a
      // specific point
    }

    sendMessage(answer);
  }
  @Override
  public void leaveLobby(int playerID) {

    int sessionID = getPlayerMap().get(playerID).getSessionID();

    DebugOutputHandler.printDebug(
        getPlayerMap().get(playerID).getName()
            + " was in lobby: "
            + getPlayerMap().get(playerID).getSessionID()
            + " and left");

    // cant "leave" list of lobby as a lobby

    if (sessionID != NO_LOBBY_ID
        && lobbyMap.get(sessionID) != null
        && getPlayerMap().get(playerID) != null) {

      int playerToDisconnectPosition = lobbyMap.get(sessionID).getGroupPositionByClientID(playerID);

      List<Integer> playersInSameSession = getPlayerIdsInSameSession(playerID);

      if (lobbyMap.get(sessionID).isGameRunning()) {

        lobbyMap.get(sessionID).deletePlayer(getPlayerMap().get(playerID));

        resetPlayer(playerID);

        if (moveTimerMap.get(sessionID) != null && lobbyMap.get(sessionID) != null) {
          int currentPlayer =
              getPlayerIDByGroupPosition(lobbyMap.get(sessionID).getNextPlayer(), sessionID);
          if (moveTimerMap.get(sessionID).getPlayer() == currentPlayer) {

            moveTimerMap.get(sessionID).setFinished(true);

            if (lobbyMap.get(sessionID).isGameRunning()) {
              moveTimerMap.put(
                  sessionID,
                  new MoveTimer(currentPlayer, this, lobbyMap.get(sessionID).getCurrentPlayMode()));
            }
          }
        }
        RaceTrackMessage playerDisconnectsMessage =
            generateDisconnectMessage(playerToDisconnectPosition, sessionID, playersInSameSession);

        sendMessage(playerDisconnectsMessage);
        DebugOutputHandler.printDebug("Up to the first occurence I am happy");
        deleteEmptyLobbies(sessionID);
        DebugOutputHandler.printDebug("After to the first occurence I am still happy");

        sendWinnerMessage(playerDisconnectsMessage);

        return;
      }

      DebugOutputHandler.printDebug("Are we here rights");
      lobbyMap.get(sessionID).deletePlayer(getPlayerMap().get(playerID));
      resetPlayer(playerID);
    }
    // check if a lobby is empty now. if it is, delete it
    DebugOutputHandler.printDebug("Up to the second occurence I am happy");
    deleteEmptyLobbies(sessionID);
    DebugOutputHandler.printDebug("After to the second occurence I am still happy");
  }