private void doTask() {
      if (task != null) {
        task.cancel();
      }

      task =
          new BukkitRunnable() {
            @Override
            public void run() {
              pagination.remove(name);
            }
          }.runTaskLater(RecipeManager.getPlugin(), 20 * 60);
    }
  @Override
  public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
    if (args.length > 0) {
      String name = (sender instanceof Player ? sender.getName() : null);

      boolean next = args[0].equalsIgnoreCase("next");

      if (next || args[0].equalsIgnoreCase("prev")) {
        Pages pages = pagination.get(name);

        if (pages != null) {
          if (next ? pages.hasNext() : pages.hasPrev()) {
            String page = (next ? pages.next() : pages.prev());
            Messages.CMD_RECIPES_HEADER.print(
                sender,
                null,
                "{item}",
                Tools.Item.print(pages.item),
                "{num}",
                (pages.page + 1),
                "{total}",
                pages.pages.length);
            Messages.send(sender, page);

            if (pages.hasNext()) {
              Messages.CMD_RECIPES_MORE.print(
                  sender,
                  null,
                  "{cmdnext}",
                  "/" + label + " next",
                  "{cmdprev}",
                  "/" + label + " prev");
            } else {
              Messages.CMD_RECIPES_END.print(sender);
            }
          } else {
            if (next) {
              Messages.CMD_RECIPES_NONEXT.print(sender, null, "{command}", "/" + label + " prev");
            } else {
              Messages.CMD_RECIPES_NOPREV.print(sender, null, "{command}", "/" + label + " next");
            }
          }
        } else {
          Messages.CMD_RECIPES_NEEDQUERY.print(sender);
        }
      } else {
        ItemStack item;

        if (args[0].equalsIgnoreCase("this")) {
          if (sender instanceof Player) {
            Player player = (Player) sender;
            item = player.getItemInHand();

            if (item == null) {
              Messages.CMD_RECIPES_NOHAND.print(sender);
              return true;
            }
          } else {
            sender.sendMessage("The 'this' argument can't be used from console.");
            return true;
          }
        } else {
          item =
              Tools.parseItem(args[0], Vanilla.DATA_WILDCARD, ParseBit.NO_META | ParseBit.NO_PRINT);

          if (item == null) {
            Messages.CMD_RECIPES_INVALIDITEM.print(sender, null, "{arg}", args[0]);
            return true;
          }
        }

        boolean ingredient = (args.length > 1 && args[1].charAt(0) == 'i');

        List<String> list = new ArrayList<String>();

        for (Entry<BaseRecipe, RecipeInfo> e :
            RecipeManager.getRecipes().getRecipeList().entrySet()) {
          BaseRecipe recipe = e.getKey();

          if (hasItem(recipe, item, ingredient)) {
            list.add(recipe.printChat());
          }
        }

        if (!list.isEmpty()) {
          Pages pages = new Pages(name, item, list);
          pagination.put(name, pages);

          Messages.CMD_RECIPES_HEADER.print(
              sender,
              null,
              "{item}",
              Tools.Item.print(pages.item),
              "{num}",
              1,
              "{total}",
              pages.pages.length);
          Messages.send(sender, pages.next());

          if (pages.hasNext()) {
            Messages.CMD_RECIPES_MORE.print(
                sender,
                null,
                "{cmdnext}",
                "/" + label + " next",
                "{cmdprev}",
                "/" + label + " prev");
          } else {
            Messages.CMD_RECIPES_END.print(sender);
          }
        } else {
          Messages.CMD_RECIPES_NORESULTS.print(sender, null, "{item}", Tools.Item.print(item));
        }
      }
    } else {
      int mc = 0;
      int rm = 0;
      int other = 0;

      for (RecipeInfo info : RecipeManager.getRecipes().getRecipeList().values()) {
        switch (info.getOwner()) {
          case MINECRAFT:
            {
              mc++;
              break;
            }

          case RECIPEMANAGER:
            {
              rm++;
              break;
            }

          default:
            {
              other++;
            }
        }
      }

      Messages.CMD_RECIPES_USAGE.print(sender, null, "{command}", label);
      Messages.CMD_RECIPES_STATS_MC.print(sender, null, "{num}", mc);
      Messages.CMD_RECIPES_STATS_RM.print(sender, null, "{num}", rm);
      Messages.CMD_RECIPES_STATS_OTHER.print(sender, null, "{num}", other);
    }

    return true;
  }