/**
   * 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);
    }
  }
  @Override
  public void onEnable() {
    if (loaded) {
      MessageSender.getInstance().info(ChatColor.RED + "Plugin is already enabled");
      return;
    }

    plugin = this;
    Locale.setDefault(Locale.ENGLISH); // avoid needless complications

    PluginManager pm = getServer().getPluginManager();

    FurnaceData.init(); // dummy caller
    BrewingStandData.init();
    Furnaces.load(); // load saved furnaces...
    BrewingStands.load();

    events = new Events();
    recipes = new Recipes();

    setupVault(pm);

    Vanilla.init(); // get initial recipes...

    Args.init(); // dummy method to avoid errors on 'reload' with updating
    ArgBuilder.init();

    flagLoader = new FlagLoader();

    // wait for all plugins to load then enable this
    new BukkitRunnable() {
      public void run() {
        onEnablePost();
      }
    }.runTask(this);
  }