@Override
 public boolean equalsExceptOutput(ShapedOreRecipe recipe1, ShapedOreRecipe recipe2)
     throws IllegalAccessException {
   return Helper.inputEquals(recipe1.getInput(), recipe2.getInput())
       && (ShapedOreRecipe_mirror.getBoolean(recipe1)
           == ShapedOreRecipe_mirror.getBoolean(recipe2));
 }
  @SuppressWarnings("unchecked")
  public void generateRecyclingRecipes() {

    Collections.addAll(blacklist, Config.alloyFurnaceBlacklist);
    List<Item> blacklist = new ArrayList<Item>();
    for (String configString : this.blacklist) {
      Item item = GameData.getItemRegistry().getObject(configString);
      if (item != null) {
        blacklist.add(item);
      } else {
        BluePower.log.info(
            "Config entry \""
                + configString
                + "\" not an existing item/block name! Will not be added to the blacklist");
      }
    }

    List<IRecipe> registeredRecipes = new ArrayList<IRecipe>();
    for (ItemStack recyclingItem : bufferedRecyclingItems) {
      List<IRecipe> recipes = CraftingManager.getInstance().getRecipeList();
      for (IRecipe recipe : recipes) {
        try {
          int recyclingAmount = 0;
          if (recipe instanceof ShapedRecipes) {
            ShapedRecipes shaped = (ShapedRecipes) recipe;
            if (shaped.recipeItems != null) {
              for (ItemStack input : shaped.recipeItems) {
                if (input != null && ItemStackUtils.isItemFuzzyEqual(input, recyclingItem)) {
                  recyclingAmount++;
                }
              }
            }
          } else if (recipe instanceof ShapelessRecipes) {
            ShapelessRecipes shapeless = (ShapelessRecipes) recipe;
            if (shapeless.recipeItems != null) {
              for (ItemStack input : (List<ItemStack>) shapeless.recipeItems) {
                if (input != null && ItemStackUtils.isItemFuzzyEqual(input, recyclingItem)) {
                  recyclingAmount++;
                }
              }
            }
          } else if (recipe instanceof ShapedOreRecipe) {
            ShapedOreRecipe shapedOreRecipe = (ShapedOreRecipe) recipe;
            if (shapedOreRecipe.getInput() != null) {
              for (Object input : shapedOreRecipe.getInput()) {
                if (input != null) {
                  List<ItemStack> itemList;
                  if (input instanceof ItemStack) {
                    itemList = new ArrayList<ItemStack>();
                    itemList.add((ItemStack) input);
                  } else {
                    itemList = (List<ItemStack>) input;
                  }
                  for (ItemStack item : itemList) {
                    if (item != null && ItemStackUtils.isItemFuzzyEqual(item, recyclingItem)) {
                      recyclingAmount++;
                      break;
                    }
                  }
                }
              }
            }
          } else if (recipe instanceof ShapelessOreRecipe) {
            ShapelessOreRecipe shapeless = (ShapelessOreRecipe) recipe;
            for (Object input : shapeless.getInput()) {
              if (input != null) {
                List<ItemStack> itemList;
                if (input instanceof ItemStack) {
                  itemList = new ArrayList<ItemStack>();
                  itemList.add((ItemStack) input);
                } else {
                  itemList = (List<ItemStack>) input;
                }
                for (ItemStack item : itemList) {
                  if (item != null && ItemStackUtils.isItemFuzzyEqual(item, recyclingItem)) {
                    recyclingAmount++;
                    break;
                  }
                }
              }
            }
          }
          if (recyclingAmount > 0 && !registeredRecipes.contains(recipe)) {
            if (blacklist.contains(recipe.getRecipeOutput().getItem())) {
              BluePower.log.info(
                  "Skipped adding item/block "
                      + recipe.getRecipeOutput().getDisplayName()
                      + " to the Alloy Furnace recipes.");
              continue;
            }
            registeredRecipes.add(recipe);
            addRecipe(
                new ItemStack(
                    recyclingItem.getItem(), recyclingAmount, recyclingItem.getItemDamage()),
                recipe.getRecipeOutput());
          }
        } catch (Throwable e) {
          BluePower.log.error(
              "Error when generating an Alloy Furnace recipe for item "
                  + recyclingItem.getDisplayName()
                  + ", recipe output: "
                  + recipe.getRecipeOutput().getDisplayName());
          e.printStackTrace();
        }
      }
    }
  }
 public static void addShapedOre(ShapedOreRecipe recipe) {
   if (CalculatorConfig.isEnabled(recipe.getRecipeOutput())) {
     GameRegistry.addRecipe(recipe);
   }
 }
  @Override
  public NBTTagCompound getNBTFromRecipe(ShapedOreRecipe recipe, ItemStack newOutput)
      throws IllegalAccessException {
    NBTTagCompound nbtRecipe = new NBTTagCompound();
    NBTTagList NBTInput = new NBTTagList();

    int width = ShapedOreRecipe_width.getInt(recipe);
    int height = ShapedOreRecipe_height.getInt(recipe);

    /** Build a map to convert the object array into recipe format. */
    HashBiMap<Character, Object> map = HashBiMap.create();
    HashMap<ArrayList, Object> arrayListMap =
        new HashMap<ArrayList, Object>(); // Lookup map for oredict entries.
    for (Object o : recipe.getInput()) {
      if (o == null) continue;
      if (map.containsValue(o)) continue;
      if (o instanceof ArrayList) {
        for (String name : OreDictionary.getOreNames()) {
          if (OreDictionary.getOres(name).equals(o)) {
            if (map.containsValue(name)) break;
            map.put(DUMMY_CHARS.charAt(map.size()), name);
            arrayListMap.put((ArrayList) o, name);
            break;
          }
        }
      } else {
        map.put(DUMMY_CHARS.charAt(map.size()), o);
      }
    }

    /** Make the recipe strings aka: "aa ", "aa ", "aa " */
    char[][] chars = new char[height][width];
    for (int h = 0; h < height; h++) {
      for (int w = 0; w < width; w++) {
        int i = h * width + w;
        if (recipe.getInput()[i] == null) chars[h][w] = ' ';
        else if (recipe.getInput()[i] instanceof ArrayList)
          chars[h][w] = map.inverse().get(arrayListMap.get(recipe.getInput()[i]));
        else chars[h][w] = map.inverse().get(recipe.getInput()[i]);
      }
      String line = new String(chars[h]);
      NBTInput.appendTag(new NBTTagString(null, line));
    }
    nbtRecipe.setTag(NBT_input, NBTInput);

    /** Add the char to itemstack thing aka: 'a' = "plank" */
    NBTTagCompound nbtMap = new NBTTagCompound();
    for (Map.Entry<Character, Object> entry : map.entrySet()) {
      if (entry.getValue() instanceof String)
        nbtMap.setString(entry.getKey().toString(), entry.getValue().toString());
      else if (entry.getValue() instanceof ItemStack)
        nbtMap.setCompoundTag(
            entry.getKey().toString(),
            ((ItemStack) entry.getValue()).writeToNBT(new NBTTagCompound()));
      else {
        CrayCrafting.logger.severe(
            "NBT RECIPE ERROR: " + entry.getValue() + " IS NOT STRING OR ITEMSTACK ???");
      }
    }
    nbtRecipe.setCompoundTag(NBT_map, nbtMap);
    nbtRecipe.setCompoundTag(NBT_output, newOutput.writeToNBT(new NBTTagCompound()));
    nbtRecipe.setBoolean(NBT_mirror, ShapedOreRecipe_mirror.getBoolean(recipe));

    return nbtRecipe;
  }