public void deny(ItemStack template) {
   Key key = Key.of(template);
   Element e = _elements.get(key);
   log.debug("deny", "template", template, "key", key, "e", e);
   if (e == null || !e.whitelisted()) return;
   log.debug("deny: whitelisted: removing...", "empty", e.empty());
   e.whitelisted(false);
   _whitelist.remove(key);
   if (e.empty()) _elements.remove(key);
 }
 public void dump() {
   log.debug("DUMP", "total", _total);
   for (Element e : _elements.values())
     log.debug(
         "DUMP: element",
         "key",
         e.key().stack(),
         "whitelisted",
         e.whitelisted(),
         "count",
         e.count());
 }
 public ItemStack put(ItemStack stack) {
   log.debug("put", "stack", stack, "size", stack.stackSize);
   if (stack == null) return null;
   Key key = Key.of(stack);
   Element e = _elements.get(key);
   if (e == null) return stack;
   int amount = stack.stackSize;
   amount = Math.min(amount, _maxTotal - _total);
   amount = e.put(amount, _maxPerKey);
   if (amount == 0) return stack;
   _total += amount;
   log.debug("put: done", "amount", amount);
   return stack.splitStack(amount);
 }
 public ItemStack take(int amount) {
   log.debug("take", "amount", amount);
   for (Element e : _elements.values()) {
     if (e.empty()) continue;
     int taken = e.take(amount);
     if (taken > 0) {
       ItemStack stack = e.key().stack().copy();
       stack.stackSize = taken;
       _total = Math.max(0, _total - taken);
       if (e.empty() && !_whitelist.contains(e.key())) _elements.remove(e.key());
       log.debug("take: done", "amount", stack.stackSize);
       return stack;
     }
   }
   return null;
 }
 public int delete(ItemStack template, int amount) {
   Key key = Key.of(template);
   Element e = _elements.get(key);
   log.debug("take", "template", template, "key", key, "e", e);
   if (e == null) return 0;
   int taken = e.take(amount);
   _total = Math.max(0, _total - taken);
   return taken;
 }
 @Override // IInventory
 public ItemStack decrStackSize(int slot, int amount) {
   log.debug("decrStackSize", "slot", slot, "amount", amount);
   switch (slot) {
     case SLOT_IMPORT:
     default:
       return null;
     case SLOT_EXPORT:
       return _inventory.takeExport(amount);
   }
 }
 public boolean allow(ItemStack template) {
   log.debug("allow", "template", template);
   if (_whitelist.size() >= _maxKeys) return false;
   Key key = Key.of(template);
   Element e = _elements.get(key);
   if (e == null) {
     e = Element.of(key, 0, true);
     _elements.put(key, e);
     _whitelist.add(key);
   } else if (!e.whitelisted()) {
     e.whitelisted(true);
     _whitelist.add(key);
   }
   return true;
 }
 @Override // IInventory
 public void setInventorySlotContents(int slot, ItemStack stack) {
   log.debug("setInventorySlotContents", "slot", slot, "stack", stack);
   switch (slot) {
     case SLOT_IMPORT:
       if (stack == null || stack.stackSize == 0) return;
       _inventory.put(stack);
       markDirty();
       break;
     case SLOT_EXPORT:
       _inventory.setExport(stack);
       break;
     default:
       break;
   }
 }
 public boolean has(ItemStack template) {
   Key key = Key.of(template);
   Element e = _elements.get(key);
   log.debug("has", "template", template, "key", key, "e", e);
   return e != null && !e.empty();
 }
 public int put(int amount, int max) {
   log.debug("put", "amount", amount, "max", max, "count", _count);
   amount = Math.min(amount, max - _count);
   _count += amount;
   return amount;
 }
 @Override // IInventory
 public ItemStack getStackInSlotOnClosing(int slot) {
   log.debug("getStackInSlotOnClosing", "slot", slot);
   return null;
 }