public static boolean addRing(MapleCharacter chr, int itemId, int ringId) {
    MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
    MapleInventoryType type = ii.getInventoryType(itemId);
    IItem nEquip = ii.getEquipById(itemId, ringId);

    byte newSlot = chr.getInventory(type).addItem(nEquip);
    if (newSlot == -1) {
      return false;
    }
    chr.getClient().getSession().write(MaplePacketCreator.addInventorySlot(type, nEquip));
    return true;
  }
  public static boolean addById(
      MapleClient c, int itemId, short quantity, String owner, int petid) {
    if (quantity >= 4000 || quantity < 0) {
      AutobanManager.getInstance()
          .autoban(c.getPlayer().getClient(), "PE Item: " + quantity + "x " + itemId);
      return false;
    }
    MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
    MapleInventoryType type = ii.getInventoryType(itemId);
    if (!type.equals(MapleInventoryType.EQUIP)) {
      short slotMax = ii.getSlotMax(c, itemId);
      List<IItem> existing = c.getPlayer().getInventory(type).listById(itemId);
      if (!ii.isThrowingStar(itemId) && !ii.isBullet(itemId)) {
        if (existing.size() > 0) { // first update all existing slots to slotMax

          Iterator<IItem> i = existing.iterator();
          while (quantity > 0) {
            if (i.hasNext()) {
              Item eItem = (Item) i.next();
              short oldQ = eItem.getQuantity();
              if (oldQ < slotMax && (eItem.getOwner().equals(owner) || owner == null)) {
                short newQ = (short) Math.min(oldQ + quantity, slotMax);
                quantity -= (newQ - oldQ);
                eItem.setQuantity(newQ);
                c.getSession().write(MaplePacketCreator.updateInventorySlot(type, eItem));
              }
            } else {
              break;
            }
          }
        }
        // add new slots if there is still something left
        while (quantity > 0 || ii.isThrowingStar(itemId) || ii.isBullet(itemId)) {
          short newQ = (short) Math.min(quantity, slotMax);
          if (newQ != 0) {
            quantity -= newQ;
            Item nItem = new Item(itemId, (byte) 0, newQ, petid);
            byte newSlot = c.getPlayer().getInventory(type).addItem(nItem);
            if (newSlot == -1) {
              c.getSession().write(MaplePacketCreator.getInventoryFull());
              c.getSession().write(MaplePacketCreator.getShowInventoryFull());
              return false;
            }
            if (owner != null) {
              nItem.setOwner(owner);
            }
            c.getSession().write(MaplePacketCreator.addInventorySlot(type, nItem));
            if ((ii.isThrowingStar(itemId) || ii.isBullet(itemId)) && quantity == 0) {
              break;
            }
          } else {
            c.getSession().write(MaplePacketCreator.enableActions());
            return false;
          }
        }
      } else {
        // Throwing Stars and Bullets - Add all into one slot regardless of quantity.
        Item nItem = new Item(itemId, (byte) 0, quantity);
        byte newSlot = c.getPlayer().getInventory(type).addItem(nItem);

        if (newSlot == -1) {
          c.getSession().write(MaplePacketCreator.getInventoryFull());
          c.getSession().write(MaplePacketCreator.getShowInventoryFull());
          return false;
        }
        c.getSession().write(MaplePacketCreator.addInventorySlot(type, nItem));
        c.getSession().write(MaplePacketCreator.enableActions());
      }
    } else {
      if (quantity == 1) {
        IItem nEquip = ii.getEquipById(itemId);
        if (owner != null) {
          nEquip.setOwner(owner);
        }

        byte newSlot = c.getPlayer().getInventory(type).addItem(nEquip);
        if (newSlot == -1) {
          c.getSession().write(MaplePacketCreator.getInventoryFull());
          c.getSession().write(MaplePacketCreator.getShowInventoryFull());
          return false;
        }
        c.getSession().write(MaplePacketCreator.addInventorySlot(type, nEquip));
      } else {
        throw new InventoryException("Trying to create equip with non-one quantity");
      }
    }
    return true;
  }
  public static boolean addFromDrop(MapleClient c, IItem item, boolean show, String owner) {
    MapleItemInformationProvider ii = MapleItemInformationProvider.getInstance();
    MapleInventoryType type = ii.getInventoryType(item.getItemId());

    if (!c.getChannelServer().allowMoreThanOne()
        && ii.isPickupRestricted(item.getItemId())
        && c.getPlayer().haveItem(item.getItemId(), 1, true, false)) {
      c.getSession().write(MaplePacketCreator.getInventoryFull());
      c.getSession().write(MaplePacketCreator.showItemUnavailable());
      return false;
    }
    short quantity = item.getQuantity();
    if (quantity >= 4000 || quantity < 0) {
      AutobanManager.getInstance()
          .autoban(c.getPlayer().getClient(), "PE Item: " + quantity + "x " + item.getItemId());
      return false;
    }

    if (!type.equals(MapleInventoryType.EQUIP)) {
      short slotMax = ii.getSlotMax(c, item.getItemId());
      List<IItem> existing = c.getPlayer().getInventory(type).listById(item.getItemId());
      if (!ii.isThrowingStar(item.getItemId()) && !ii.isBullet(item.getItemId())) {
        if (existing.size() > 0) { // first update all existing slots to slotMax

          Iterator<IItem> i = existing.iterator();
          while (quantity > 0) {
            if (i.hasNext()) {
              Item eItem = (Item) i.next();
              short oldQ = eItem.getQuantity();
              if (oldQ < slotMax && item.getOwner().equals(eItem.getOwner())) {
                short newQ = (short) Math.min(oldQ + quantity, slotMax);
                quantity -= (newQ - oldQ);
                eItem.setQuantity(newQ);
                c.getSession().write(MaplePacketCreator.updateInventorySlot(type, eItem, true));
              }
            } else {
              break;
            }
          }
        }
        // add new slots if there is still something left
        while (quantity > 0
            || ii.isThrowingStar(item.getItemId())
            || ii.isBullet(item.getItemId())) {
          short newQ = (short) Math.min(quantity, slotMax);
          quantity -= newQ;
          Item nItem = new Item(item.getItemId(), (byte) 0, newQ);
          nItem.setOwner(item.getOwner());
          byte newSlot = c.getPlayer().getInventory(type).addItem(nItem);
          if (newSlot == -1) {
            c.getSession().write(MaplePacketCreator.getInventoryFull());
            c.getSession().write(MaplePacketCreator.getShowInventoryFull());
            item.setQuantity((short) (quantity + newQ));
            return false;
          }
          c.getSession().write(MaplePacketCreator.addInventorySlot(type, nItem, true));
        }
      } else {
        // Throwing Stars and Bullets - Add all into one slot regardless of quantity.
        Item nItem = new Item(item.getItemId(), (byte) 0, quantity);
        byte newSlot = c.getPlayer().getInventory(type).addItem(nItem);
        if (newSlot == -1) {
          c.getSession().write(MaplePacketCreator.getInventoryFull());
          c.getSession().write(MaplePacketCreator.getShowInventoryFull());
          return false;
        }
        c.getSession().write(MaplePacketCreator.addInventorySlot(type, nItem));
        c.getSession().write(MaplePacketCreator.enableActions());
      }
    } else {
      if (quantity == 1) {
        byte newSlot = c.getPlayer().getInventory(type).addItem(item);

        if (newSlot == -1) {
          c.getSession().write(MaplePacketCreator.getInventoryFull());
          c.getSession().write(MaplePacketCreator.getShowInventoryFull());
          return false;
        }
        c.getSession().write(MaplePacketCreator.addInventorySlot(type, item, true));
      } else {
        throw new RuntimeException("Trying to create equip with non-one quantity");
      }
    }
    if (owner != null) {
      item.setOwner(owner);
    }
    if (show) {
      c.getSession()
          .write(MaplePacketCreator.getShowItemGain(item.getItemId(), item.getQuantity()));
    }
    return true;
  }