/**
   * Get a block.
   *
   * @param id
   */
  @Override
  public void fetchItem(BaseItem item) throws BlockBagException {
    final int id = item.getType();
    final int damage = item.getDamage();
    int amount = (item instanceof BaseItemStack) ? ((BaseItemStack) item).getAmount() : 1;
    assert (amount == 1);
    boolean usesDamageValue = ItemType.usesDamageValue(id);

    if (id == BlockID.AIR) {
      throw new IllegalArgumentException("Can't fetch air block");
    }

    loadInventory();

    boolean found = false;

    for (int slot = 0; slot < items.length; ++slot) {
      ItemStack bukkitItem = items[slot];

      if (bukkitItem == null) {
        continue;
      }

      if (bukkitItem.getTypeId() != id) {
        // Type id doesn't fit
        continue;
      }

      if (usesDamageValue && bukkitItem.getDurability() != damage) {
        // Damage value doesn't fit.
        continue;
      }

      int currentAmount = bukkitItem.getAmount();
      if (currentAmount < 0) {
        // Unlimited
        return;
      }

      if (currentAmount > 1) {
        bukkitItem.setAmount(currentAmount - 1);
        found = true;
      } else {
        items[slot] = null;
        found = true;
      }

      break;
    }

    if (!found) {
      throw new OutOfBlocksException();
    }
  }
  /**
   * Store a block.
   *
   * @param id
   */
  @Override
  public void storeItem(BaseItem item) throws BlockBagException {
    final int id = item.getType();
    final int damage = item.getDamage();
    int amount = (item instanceof BaseItemStack) ? ((BaseItemStack) item).getAmount() : 1;
    assert (amount <= 64);
    boolean usesDamageValue = ItemType.usesDamageValue(id);

    if (id == BlockID.AIR) {
      throw new IllegalArgumentException("Can't store air block");
    }

    loadInventory();

    int freeSlot = -1;

    for (int slot = 0; slot < items.length; ++slot) {
      ItemStack bukkitItem = items[slot];

      if (bukkitItem == null) {
        // Delay using up a free slot until we know there are no stacks
        // of this item to merge into

        if (freeSlot == -1) {
          freeSlot = slot;
        }
        continue;
      }

      if (bukkitItem.getTypeId() != id) {
        // Type id doesn't fit
        continue;
      }

      if (usesDamageValue && bukkitItem.getDurability() != damage) {
        // Damage value doesn't fit.
        continue;
      }

      int currentAmount = bukkitItem.getAmount();
      if (currentAmount < 0) {
        // Unlimited
        return;
      }
      if (currentAmount >= 64) {
        // Full stack
        continue;
      }

      int spaceLeft = 64 - currentAmount;
      if (spaceLeft >= amount) {
        bukkitItem.setAmount(currentAmount + amount);
        return;
      }

      bukkitItem.setAmount(64);
      amount -= spaceLeft;
    }

    if (freeSlot > -1) {
      items[freeSlot] = new ItemStack(id, amount);
      return;
    }

    throw new OutOfSpaceException(id);
  }