@Override
  public boolean matches(
      ArrayList<ItemStack> input, ItemStack in, World world, EntityPlayer player) {
    if (in == null || !(in.getItem() instanceof ItemEtherealFamiliar))
      return false; // We call it "FamiliarAugment" Recipe for a reason..
    if (getRecipeInput() == null || !(getRecipeInput().getItem() instanceof ItemEtherealFamiliar))
      return false; // A bit late but still working..

    if ((this.research.length() > 0)
        && (!ThaumcraftApiHelper.isResearchComplete(
            player.getCommandSenderName(), this.research))) {
      return false;
    }

    FamiliarAugment.FamiliarAugmentList list = ItemEtherealFamiliar.getAugments(in);

    int level;
    if (list.contains(toAdd)) {
      level = list.getLevel(toAdd);
    } else {
      level = 0;
    }
    if (requiredPreviousLevel > level) return false; // Requires higher level to do this infusion.

    if (!toAdd.checkConditions(list, level + 1)) {
      return false; // Preconditions not met.
    }

    // Normal infusionrecipe stuff...

    ItemStack inCopy;
    ArrayList<ItemStack> ii = new ArrayList<ItemStack>();
    for (ItemStack is : input) {
      ii.add(is.copy());
    }
    for (ItemStack comp : getComponents()) {
      boolean b = false;
      for (int a = 0; a < ii.size(); a++) {
        inCopy = ii.get(a).copy();
        if (comp.getItemDamage() == 32767) {
          inCopy.setItemDamage(32767);
        }
        if (areItemStacksEqual(inCopy, comp, true)) {
          ii.remove(a);
          b = true;
          break;
        }
      }
      if (!b) {
        return false;
      }
    }
    return true;
  }
 @Override
 public Object getRecipeOutput(ItemStack in) {
   ItemStack inputCopy = in.copy();
   ItemEtherealFamiliar.incrementAugmentLevel(inputCopy, toAdd);
   return inputCopy;
 }