/**
   * Reload RecipeManager's settings, messages, etc and re-parse recipes.
   *
   * @param sender To whom to send the messages to, null = console.
   * @param check Set to true to only check recipes, settings are unaffected.
   */
  public void reload(CommandSender sender, boolean check, boolean firstTime) {
    Settings.getInstance().reload(sender); // (re)load settings
    Messages.getInstance().reload(sender); // (re)load messages from messages.yml
    Files.reload(sender); // (re)generate info files if they do not exist

    Updater.init(this, 32835, null);

    if (metrics == null) {
      if (Settings.getInstance().getMetrics()) { // start/stop metrics accordingly
        try {
          metrics = new Metrics(this);
          metrics.start();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    } else {
      metrics.stop();
    }
    if (!check) {
      if (Settings.getInstance().getClearRecipes() || !firstTime) {
        Vanilla.removeAllButSpecialRecipes();
        Recipes.getInstance().clean();
      }

      if (!firstTime && !Settings.getInstance().getClearRecipes()) {
        Vanilla.restoreAllButSpecialRecipes();
        Recipes.getInstance().index.putAll(Vanilla.initialRecipes);
      }
    }

    RecipeProcessor.reload(sender, check); // (re)parse recipe files
    Events.reload(); // (re)register events
  }
  @Override
  public void onDisable() {
    try {
      Bukkit.getScheduler().cancelTasks(this);

      if (plugin == null) {
        return;
      }

      Vanilla.removeCustomRecipes();

      Furnaces.save();
      Furnaces.clean();

      BrewingStands.save();
      BrewingStands.clean();

      Workbenches.clean();
      Players.clean();
      Vanilla.clean();

      recipes.clean();
      recipes = null;

      recipeBooks.clean();
      recipeBooks = null;

      events.clean();
      events = null;

      Settings.clean();

      Econ.getInstance().clean();
      Perms.getInstance().clean();

      if (metrics != null) {
        metrics.stop();
        metrics = null;
      }

      plugin = null;
    } catch (Throwable e) {
      MessageSender.getInstance().error(null, e, null);
    }
  }