public ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) {
    EnumFacing enumfacing = BlockDispenser.b(isourceblock.h());
    double d0 = isourceblock.getX() + (double) enumfacing.c();
    double d1 = (double) ((float) isourceblock.getBlockY() + 0.2F);
    double d2 = isourceblock.getZ() + (double) enumfacing.e();

    // CraftBukkit start
    World world = isourceblock.k();
    ItemStack itemstack1 = itemstack.a(1);
    org.bukkit.block.Block block =
        world
            .getWorld()
            .getBlockAt(
                isourceblock.getBlockX(), isourceblock.getBlockY(), isourceblock.getBlockZ());
    CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1);

    BlockDispenseEvent event =
        new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1, d2));
    if (!BlockDispenser.eventFired) {
      world.getServer().getPluginManager().callEvent(event);
    }

    if (event.isCancelled()) {
      itemstack.count++;
      return itemstack;
    }

    if (!event.getItem().equals(craftItem)) {
      itemstack.count++;
      // Chain to handler for new item
      ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem());
      IDispenseBehavior idispensebehavior =
          (IDispenseBehavior) BlockDispenser.a.a(eventStack.getItem());
      if (idispensebehavior != IDispenseBehavior.a && idispensebehavior != this) {
        idispensebehavior.a(isourceblock, eventStack);
        return itemstack;
      }
    }

    itemstack1 = CraftItemStack.asNMSCopy(event.getItem());
    EntityFireworks entityfireworks =
        new EntityFireworks(
            isourceblock.k(),
            event.getVelocity().getX(),
            event.getVelocity().getY(),
            event.getVelocity().getZ(),
            itemstack1);

    isourceblock.k().addEntity(entityfireworks);
    // itemstack.a(1); // Handled during event processing
    // CraftBukkit end

    return itemstack;
  }
  public ItemStack b(IBlockSource iblocksource, ItemStack itemstack) {
    EnumFacing enumfacing = BlockDispenser.j_(iblocksource.h());
    World world = iblocksource.k();
    double d0 = iblocksource.a() + (double) ((float) enumfacing.c() * 1.125F);
    double d1 = iblocksource.b() + (double) ((float) enumfacing.d() * 1.125F);
    double d2 = iblocksource.c() + (double) ((float) enumfacing.e() * 1.125F);
    int i0 = iblocksource.d() + enumfacing.c();
    int i1 = iblocksource.e() + enumfacing.d();
    int i2 = iblocksource.f() + enumfacing.e();
    int i3 = world.a(i0, i1, i2);
    double d3;

    if (BlockRailBase.d_(i3)) {
      d3 = 0.0D;
    } else {
      if (i3 != 0 || !BlockRailBase.d_(world.a(i0, i1 - 1, i2))) {
        return this.b.a(iblocksource, itemstack);
      }

      d3 = -1.0D;
    }

    EntityMinecart entityminecart =
        EntityMinecart.a(world, d0, d1 + d3, d2, ((ItemMinecart) itemstack.b()).a);

    // CanaryMod: Dispense
    DispenseHook hook =
        new DispenseHook(
            ((TileEntityDispenser) iblocksource.j()).getCanaryDispenser(),
            entityminecart.getCanaryEntity());

    Canary.hooks().callHook(hook);
    if (!hook.isCanceled()) {
      world.d((Entity) entityminecart);
      itemstack.a(1);
    }
    //
    return itemstack;
  }
  public ItemStack b(IBlockSource iblocksource, ItemStack itemstack) {
    EnumFacing enumfacing = BlockDispenser.j_(iblocksource.h());
    World world = iblocksource.k();
    int i0 = iblocksource.d() + enumfacing.c();
    int i1 = iblocksource.e() + enumfacing.d();
    int i2 = iblocksource.f() + enumfacing.e();
    Material material = world.g(i0, i1, i2);
    int i3 = world.h(i0, i1, i2);
    Item item;

    if (Material.h.equals(material) && i3 == 0) {
      item = Item.ay;
    } else {
      if (!Material.i.equals(material) || i3 != 0) {
        return super.b(iblocksource, itemstack);
      }

      item = Item.az;
    }

    world.i(i0, i1, i2);
    if (--itemstack.a == 0) {
      // CanaryMod: Dispense
      DispenseHook hook =
          new DispenseHook(((TileEntityDispenser) iblocksource.j()).getCanaryDispenser(), null);

      Canary.hooks().callHook(hook);
      if (!hook.isCanceled()) {
        itemstack.c = item.cp;
        itemstack.a = 1;
      }
      //
    } else if (((TileEntityDispenser) iblocksource.j()).a(new ItemStack(item)) < 0) {
      this.b.a(iblocksource, new ItemStack(item));
    }

    return itemstack;
  }