gt: 		if (craftingTools) {
context: /*******************************************************************************
   * Copyright (c) 2011-2014 SirSengir.
   * All rights reserved. This program and the accompanying materials
   * are made available under the terms of the GNU Lesser Public License v3
   * which accompanies this distribution, and is available at
   * http://www.gnu.org/licenses/lgpl-3.0.txt
   *
   * Various Contributors including, but not limited to:
   * SirSengir (original work), CovertJaguar, Player, Binnie, MysteriousAges
   ******************************************************************************/
  package forestry.core.utils;
  
  import java.text.NumberFormat;
  import java.text.ParseException;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.List;
  import java.util.Random;
  
  import net.minecraft.block.Block;
  import net.minecraft.entity.item.EntityItem;
  import net.minecraft.entity.player.EntityPlayer;
  import net.minecraft.inventory.IInventory;
  import net.minecraft.item.Item;
  import net.minecraft.item.ItemBlock;
  import net.minecraft.item.ItemStack;
  import net.minecraft.nbt.NBTTagCompound;
  import net.minecraft.world.World;
  
  import net.minecraftforge.common.MinecraftForge;
  import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent;
  import net.minecraftforge.oredict.OreDictionary;
  
  import cpw.mods.fml.common.registry.GameData;
  
  import forestry.core.config.Defaults;
  import forestry.core.inventory.InvTools;
  import forestry.core.proxy.Proxies;
  
  public class StackUtils {
  
  	public static final ItemStack[] EMPTY_STACK_ARRAY = new ItemStack[0];
  
  	/**
  	 * Compares item id, damage and NBT. Accepts wildcard damage.
  	 */
  	public static boolean isIdenticalItem(ItemStack lhs, ItemStack rhs) {
  		if (lhs == null || rhs == null) {
  			return false;
  		}
  
  		if (lhs.getItem() != rhs.getItem()) {
  			return false;
  		}
  
  		if (lhs.getItemDamage() != Defaults.WILDCARD) {
  			if (lhs.getItemDamage() != rhs.getItemDamage()) {
  				return false;
  			}
  		}
  
  		return ItemStack.areItemStackTagsEqual(lhs, rhs);
  	}
  
  	public static boolean stowInInventory(ItemStack itemstack, IInventory inventory, boolean doAdd) {
  		return stowInInventory(itemstack, inventory, doAdd, 0, inventory.getSizeInventory());
  	}
  
  	public static boolean stowInInventory(ItemStack itemstack, IInventory inventory, boolean doAdd, int slot1, int count) {
  
  		boolean added = false;
  
  		for (int i = slot1; i < slot1 + count; i++) {
  			ItemStack inventoryStack = inventory.getStackInSlot(i);
  
  			// Grab those free slots
  			if (inventoryStack == null) {
  				if (doAdd) {
  					inventory.setInventorySlotContents(i, itemstack.copy());
  					itemstack.stackSize = 0;
  				}
  				return true;
  			}
  
  			// Already full
  			if (inventoryStack.stackSize >= inventoryStack.getMaxStackSize()) {
  				continue;
  			}
  
  			// Not same type
  			if (!inventoryStack.isItemEqual(itemstack)) {
  				continue;
  			}
  			if (!ItemStack.areItemStackTagsEqual(inventoryStack, itemstack)) {
  				continue;
  			}
  
  			int space = inventoryStack.getMaxStackSize() - inventoryStack.stackSize;
  
  			// Enough space to add all
  			if (space > itemstack.stackSize) {
  				if (doAdd) {
  					inventoryStack.stackSize += itemstack.stackSize;
  					itemstack.stackSize = 0;
  				}
  				return true;
  				// Only part can be added
  			} else {
  				if (doAdd) {
  					inventoryStack.stackSize = inventoryStack.getMaxStackSize();
  					itemstack.stackSize -= space;
  				}
  				added = true;
  			}
  
  		}
  
  		return added;
  	}
  
  	/**
  	 * Merges the giving stack into the receiving stack as far as possible
  	 */
  	public static void mergeStacks(ItemStack giver, ItemStack receptor) {
  		if (receptor.stackSize >= 64) {
  			return;
  		}
  
  		if (!receptor.isItemEqual(giver)) {
  			return;
  		}
  
  		if (giver.stackSize <= (receptor.getMaxStackSize() - receptor.stackSize)) {
  			receptor.stackSize += giver.stackSize;
  			giver.stackSize = 0;
  			return;
  		}
  
  		ItemStack temp = giver.splitStack(receptor.getMaxStackSize() - receptor.stackSize);
  		receptor.stackSize += temp.stackSize;
  		temp.stackSize = 0;
  	}
  
  	/**
  	 * Creates a split stack of the specified amount, preserving NBT data,
  	 * without decreasing the source stack.
  	 */
  	public static ItemStack createSplitStack(ItemStack stack, int amount) {
  		ItemStack split = new ItemStack(stack.getItem(), amount, stack.getItemDamage());
  		if (stack.getTagCompound() != null) {
  			NBTTagCompound nbttagcompound = (NBTTagCompound) stack.getTagCompound().copy();
  			split.setTagCompound(nbttagcompound);
  		}
  		return split;
  	}
  
  	/**
  	 */
  	public static ItemStack[] condenseStacks(ItemStack[] stacks) {
  		List<ItemStack> condensed = new ArrayList<ItemStack>();
  
  		for (ItemStack stack : stacks) {
  			if (stack == null) {
  				continue;
  			}
  			if (stack.stackSize <= 0) {
  				continue;
  			}
  
  			boolean matched = false;
  			for (ItemStack cached : condensed) {
  				if ((cached.isItemEqual(stack) && ItemStack.areItemStackTagsEqual(cached, stack))) {
  					cached.stackSize += stack.stackSize;
  					matched = true;
  				}
  			}
  
  			if (!matched) {
  				ItemStack cached = stack.copy();
  				condensed.add(cached);
  			}
  
  		}
  
  		return condensed.toArray(new ItemStack[condensed.size()]);
  	}
  
  	public static boolean containsItemStack(Iterable<ItemStack> list, ItemStack itemStack) {
  		for (ItemStack listStack : list) {
  			if (isIdenticalItem(listStack, itemStack)) {
  				return true;
  			}
  		}
  		return false;
  	}
  
  	/**
  	 * Counts how many full sets are contained in the passed stock
  	 */
  	public static int containsSets(ItemStack[] set, ItemStack[] stock) {
  		return containsSets(set, stock, false, false);
  	}
  
  	/**
  	 * Counts how many full sets are contained in the passed stock
  	 */
  	public static int containsSets(ItemStack[] set, ItemStack[] stock, boolean oreDictionary, boolean craftingTools) {
  		int totalSets = 0;
  
  		ItemStack[] condensedRequired = StackUtils.condenseStacks(set);
  		ItemStack[] condensedOffered = StackUtils.condenseStacks(stock);
  
  		for (ItemStack req : condensedRequired) {
  
  			int reqCount = 0;
  			for (ItemStack offer : condensedOffered) {
  				if (isCraftingEquivalent(req, offer, oreDictionary, craftingTools)) {
  					int stackCount = (int) Math.floor(offer.stackSize / req.stackSize);
  					reqCount = Math.max(reqCount, stackCount);
  				}
  			}
  
  			if (reqCount == 0) {
  				return 0;
  			} else if (totalSets == 0) {
  				totalSets = reqCount;
  			} else if (totalSets > reqCount) {
  				totalSets = reqCount;
  			}
  		}
  
  		return totalSets;
  	}
  
  	/**
  	 * Compare two item stacks for crafting equivalency without oreDictionary or craftingTools
  	 */
  	public static boolean isCraftingEquivalent(ItemStack base, ItemStack comparison) {
  		if (base == null || comparison == null) {
  			return false;
  		}
  
  		if (base.getItem() != comparison.getItem()) {
  			return false;
  		}
  
  		if (base.getItemDamage() != Defaults.WILDCARD) {
  			if (base.getItemDamage() != comparison.getItemDamage()) {
  				return false;
  			}
  		}
  
  		// When the base stackTagCompound is null or empty, treat it as a wildcard for crafting
  		if (base.stackTagCompound == null || base.stackTagCompound.hasNoTags()) {
  			return true;
  		} else {
  			return ItemStack.areItemStackTagsEqual(base, comparison);
  		}
  	}
  
  	/**
  	 * Compare two item stacks for crafting equivalency.
  	 */
  	public static boolean isCraftingEquivalent(ItemStack base, ItemStack comparison, boolean oreDictionary, boolean craftingTools) {
  		if (isCraftingEquivalent(base, comparison)) {
  			return true;
  		}
  
  		if (base == null || comparison == null) {
  			return false;
  		}
  
  		if (base.hasTagCompound() && !base.stackTagCompound.hasNoTags()) {
  			if (!ItemStack.areItemStacksEqual(base, comparison)) {
  				return false;
  			}
  		}
  
  		if (oreDictionary) {
  			int[] idsBase = OreDictionary.getOreIDs(base);
  			Arrays.sort(idsBase);
  			int[] idsComp = OreDictionary.getOreIDs(comparison);
  			Arrays.sort(idsComp);
  
  			// check if the sorted arrays "idsBase" and "idsComp" have any ID in common.
  			int iBase = 0;
  			int iComp = 0;
  			while (iBase < idsBase.length && iComp < idsComp.length) {
  				if (idsBase[iBase] < idsComp[iComp]) {
  					iBase++;
  				} else if (idsBase[iBase] > idsComp[iComp]) {
  					iComp++;
  				} else {
  					return true;
  				}
  			}
  		}
  
  