/** Checks if the region of a crafting inventory is match for the recipe. */
  private boolean checkMatch(IInventory par1InventoryCrafting, int par2, int par3, boolean par4) {
    for (int var5 = 0; var5 < 3; ++var5) {
      for (int var6 = 0; var6 < 3; ++var6) {
        int var7 = var5 - par2;
        int var8 = var6 - par3;
        ItemStack var9 = null;

        if (var7 >= 0 && var8 >= 0 && var7 < this.recipeWidth && var8 < this.recipeHeight) {
          if (par4) {
            var9 = this.recipeItems[this.recipeWidth - var7 - 1 + var8 * this.recipeWidth];
          } else {
            var9 = this.recipeItems[var7 + var8 * this.recipeWidth];
          }
        }

        ItemStack var10 =
            ThaumcraftApiHelper.getStackInRowAndColumn(par1InventoryCrafting, var5, var6);

        if (var10 != null || var9 != null) {
          if (var10 == null && var9 != null || var10 != null && var9 == null) {
            return false;
          }

          if (var9.itemID != var10.itemID) {
            return false;
          }

          if (var9.getItemDamage() != -1 && var9.getItemDamage() != var10.getItemDamage()) {
            return false;
          }

          if (var9.hasTagCompound()) {
            NBTTagCompound tc = var9.getTagCompound();
            for (Object tag : tc.getTags().toArray()) {
              NBTBase base = (NBTBase) tag;
              Class nc = NBTBase.newTag(base.getId(), base.getName()).getClass();
              if (!(var10.hasTagCompound()
                  && nc.cast(var10.getTagCompound().getTag(base.getName()))
                      .equals(nc.cast(base)))) {
                return false;
              }
            }
          }
        }
      }
    }

    return true;
  }
  @Override
  public ShapedOreRecipe getRecipeFromNBT(NBTTagCompound nbtRecipe) {
    ArrayList<Object> input = new ArrayList<Object>(); // Becomes entire recipe input
    ItemStack output = ItemStack.loadItemStackFromNBT(nbtRecipe.getCompoundTag(NBT_output));

    NBTTagList inputs = nbtRecipe.getTagList(NBT_input);
    for (int i = 0; i < inputs.tagCount(); i++) input.add(((NBTTagString) inputs.tagAt(i)).data);
    NBTTagCompound map = nbtRecipe.getCompoundTag(NBT_map);
    for (NBTBase entry : (Collection<NBTBase>) map.getTags()) {
      input.add(entry.getName().charAt(0));
      if (entry instanceof NBTTagString) input.add(((NBTTagString) entry).data);
      else input.add(ItemStack.loadItemStackFromNBT((NBTTagCompound) entry));
    }

    return new ShapedOreRecipe(output, input.toArray())
        .setMirrored(nbtRecipe.getBoolean(NBT_mirror));
  }