public void changeServerStage(ServerStage now) {
    stage = now;

    switch (stage) {
      case PLAYING:
        {
          voter = null;
        }
        break;
      case RESTARTING:
        {
          voter = null;
          track = null;
          race = null;
          starting = false;
          mode = RaceType.RACE;
          spectators.endSpectating();
        }
        break;
      case STARTING:
        {
          voter = null;
          Player[] online = Bukkit.getOnlinePlayers();
          for (Player player : online) {
            player.getInventory().clear();
          }
        }
        break;
      case WAITING:
        {
          if (voter == null) {
            voter = new VoteHandler();
          }
          spectators.endSpectating();
          Player[] online = Bukkit.getOnlinePlayers();
          for (Player player : online) {
            BossBar.removeBar(player);
            player.getInventory().clear();
            player.getInventory().addItem(item.clone());
            player.teleport(lobbyLoc);
            if (spectators.isSpectating(player)) {
              spectators.stopSpectating(player);
            }
            player.setGameMode(GameMode.SURVIVAL);
          }
        }
        break;
      case BUILDING:
        {
          Player[] online = Bukkit.getOnlinePlayers();
          for (Player player : online) {
            if (!player.hasPermission(BUILD_PERM)) {
              player.kickPlayer("Server now closed, sorry!");
            } else {
              player.sendMessage(ChatColor.GRAY + "Server is now in build mode...");
            }
          }
          if (voter != null) {
            voter.closeVotes();
            voter = null;
          }
        }
        break;
      default:
        break;
    }
  }
  public void trackSelected(final String trackName) {
    if (stage == ServerStage.BUILDING) { // Ignore
      return;
    }
    if (starting) {
      return;
    }
    starting = true;
    changeServerStage(ServerStage.STARTING);
    voter = null; // Stop voting stuff working

    int online = Bukkit.getOnlinePlayers().length;
    if (online < 2) {
      mode = RaceType.TIME_TRIAL;
    } else {
      mode = RaceType.RACE;
    }

    track = MarioKart.plugin.trackManager.getRaceTrack(trackName);
    if (track == null) {
      changeServerStage(ServerStage.WAITING);
      return;
    }

    Bukkit.broadcastMessage(
        ChatColor.BOLD + "" + ChatColor.DARK_RED + "------------------------------");
    Bukkit.broadcastMessage(
        ChatColor.BOLD + "" + ChatColor.DARK_RED + "Map: " + ChatColor.GOLD + trackName);
    Bukkit.broadcastMessage(
        ChatColor.BOLD
            + ""
            + ChatColor.DARK_RED
            + "Mode: "
            + ChatColor.GOLD
            + mode.name().toLowerCase());
    Bukkit.broadcastMessage(
        ChatColor.BOLD + "" + ChatColor.DARK_RED + "------------------------------");

    Bukkit.broadcastMessage(
        ChatColor.BOLD
            + ""
            + ChatColor.DARK_RED
            + "Please wait "
            + ChatColor.GOLD
            + "10s"
            + ChatColor.DARK_RED
            + " for the game to start!");

    Player[] o = Bukkit.getOnlinePlayers();
    for (Player player : o) {
      BossBar.removeBar(player);
    }

    Bukkit.getScheduler()
        .runTaskLater(
            MarioKart.plugin,
            new Runnable() {

              @Override
              public void run() {
                Player[] o = Bukkit.getOnlinePlayers();
                for (Player player : o) {
                  BossBar.setMessage(player, ChatColor.RED + "Starting...", 9);
                }
                return;
              }
            },
            20l);

    Bukkit.getScheduler()
        .runTaskLater(
            MarioKart.plugin,
            new Runnable() {

              @Override
              public void run() {
                // Start the game!
                changeServerStage(ServerStage.PLAYING);

                Player[] players = Bukkit.getOnlinePlayers();
                if (players.length < 1
                    || track == null
                    || track.getTrackName() == null
                    || mode == null) {
                  changeServerStage(ServerStage.WAITING); // Reset the server, nobody is on anymore
                  return;
                }
                race = new Race(track, track.getTrackName(), mode);
                List<Player> q = new ArrayList<Player>(Arrays.asList(Bukkit.getOnlinePlayers()));
                for (Player p : q) {
                  if (p != null && p.isOnline()) {
                    if (race.getUsers().size() < race.getTrack().getMaxPlayers()) {
                      race.join(p);
                    } else {
                      p.sendMessage(
                          ChatColor.RED
                              + "Sorry, there are not enough slots for you to join in with this race :(");
                      sendToLobby(p);
                    }
                  }
                }
                if (race.getUsers().size() > 0) {
                  MarioKart.plugin.raceScheduler.startRace(race.getTrackName(), race);
                }
                return;
              }
            },
            10 * 20l);
  }