public static boolean is_full(ItemStack[] items, int check, boolean extraStack) {
   int amt = 1;
   for (ItemStack item : items) {
     int mx =
         !extraStack || noStack.contains(item == null ? 0 : item.getTypeId())
             ? JItems.getMaxStack(item)
             : 64;
     if (item == null
         || item.getAmount() == 0
         || (item.getTypeId() == check && (item.getAmount() + amt <= mx))) {
       return false;
     } else if (item.getTypeId() == check) {
       amt -= mx - item.getAmount();
     }
   }
   return true;
 }
 public static int amountCanHold(ItemStack[] items, ItemStack check, boolean extraStack) {
   int amt = 0;
   if (items == null) {
     return 0;
   } else if (check == null) {
     return emptySlots(items);
   } else {
     int max = !extraStack || noStack.contains(check.getTypeId()) ? JItems.getMaxStack(check) : 64;
     for (ItemStack item : items) {
       if (item == null
           || item.getAmount() == 0
           || (check.equals(item) && item.getAmount() <= max)) {
         amt += max - (item == null ? 0 : item.getAmount());
       }
     }
   }
   return amt;
 }
 /**
  * add an ItemStack to an array
  *
  * @param items
  * @param toAdd
  * @param extraStack whether to allow some nonstackable items to stack
  * @return
  */
 public static ItemStack add(ItemStack[] items, ItemStack toAdd, boolean extraStack) {
   ItemStack ret = toAdd.clone();
   int mx = !extraStack || noStack.contains(toAdd.getTypeId()) ? JItems.getMaxStack(toAdd) : 64;
   boolean firstRun = true;
   for (int i = 0; i < items.length; ++i) {
     if (!firstRun && (items[i] == null || items[i].getAmount() == 0)) {
       if (items[i] == null) {
         items[i] = toAdd;
       } else {
         items[i].setTypeId(toAdd.getTypeId());
         items[i].setDurability(toAdd.getDurability());
         items[i].addEnchantments(toAdd.getEnchantments());
       }
       items[i].setAmount(ret.getAmount());
       ret.setAmount(0);
       return ret;
     } else if (items[i] != null
         && items[i].getTypeId() == toAdd.getTypeId()
         && items[i].getDurability()
             == toAdd
                 .getDurability() // (!JItems.hasData(toAdd.getTypeId()) ||
                                  // items[i].getData().getData() == toAdd.getData().getData())
         && sameEnchants(items[i], toAdd)
         && items[i].getAmount() < mx) {
       // on first run, look for other stacks in array that could be incremented instead
       if (items[i].getAmount() + ret.getAmount() <= mx) {
         items[i].setAmount(items[i].getAmount() + ret.getAmount());
         ret.setAmount(0);
         return ret;
       } else {
         ret.setAmount(ret.getAmount() - (mx - items[i].getAmount()));
         items[i].setAmount(mx);
       }
     } else if (firstRun && i + 1 >= items.length) {
       firstRun = false;
       i = -1; // negative, because gets incremented again
     }
   }
   return ret;
 }