@Override
  public void performSwitch() {
    // get Game instance and the player
    Game game = Game.getInstance();
    MovableModel<?> player = game.getPlayerModel();

    // load level
    Level level;
    LevelAppState state = null;
    if (targetLevel == null) {
      level = game.getCurrentLevel();
    } else {
      Game.LevelInfo info = game.findLevel(targetLevel);
      level = game.loadLevel(info);
      state = new LevelAppState(level);
    }
    if (level == null) {
      LOG.log(java.util.logging.Level.SEVERE, "unable to load level {0}", targetLevel);
      return;
    }
    LOG.log(java.util.logging.Level.INFO, "level {0} loaded", targetLevel);

    // find target map switch
    MapSwitchModel target = null;
    for (BaseModel<?> m : level.getObjects().getModels()) {
      if (m instanceof MapSwitchModel && targetEntry.equals(m.getName())) {
        target = (MapSwitchModel) m;
        break;
      }
    }
    if (target == null) {
      LOG.log(java.util.logging.Level.SEVERE, "unable to find target entry {0}", targetEntry);
      return;
    }

    // collect players
    final CharacterModel<?> oldPlayer = game.getCurrentLevel().getPlayer();
    final CharacterModel<?> newPlayer = level.getPlayer();
    assert (oldPlayer != null);
    assert (newPlayer != null);

    // switch to the new level
    //		game.switchLevel(level);
    if (state != null) {
      HashMap<Object, Object> properties = new HashMap<Object, Object>();
      properties.put(KEY_SOURCE_SWITCH, this);
      properties.put(KEY_TARGET_SWITCH, target);
      // add hook that moves the player to the target switch
      final MapSwitchModel target2 = target;
      properties.put(
          LevelAppState.KEY_ACTIVATION_HOOKS,
          Collections.singletonList(
              new LevelAppState.ActivationHook() {
                @Override
                public void onActivated(
                    Map<Object, Object> properties,
                    ExtAppState lastState,
                    LevelAppState currentLevel) {
                  target2.entry(oldPlayer, newPlayer, AbstractMapSwitchModel.this);
                }
              }));
      // Call next level
      //			Game.getInstance().getApplication().getStateManager().callNext(state, properties);
      FadeAppState fade =
          new FadeAppState(state, FadeAppState.FADE_OUT_DOOR, FadeAppState.FADE_IN_DOOR);
      Game.getInstance().getApplication().getStateManager().pushStack(fade, properties);
    } else {
      // move player to the target switch
      target.entry(oldPlayer, newPlayer, this);
    }

    // done
    LOG.log(
        java.util.logging.Level.INFO,
        "player switched to {0} in {1}",
        new Object[] {targetEntry, targetLevel});
  }