/** Looks for changes made in the container, sends them to every listener. */
  public void detectAndSendChanges() {
    super.detectAndSendChanges();

    for (int i = 0; i < this.crafters.size(); ++i) {
      ICrafting icrafting = (ICrafting) this.crafters.get(i);

      if (this.lastTimer != this.tileEntity.furnaceTimer
          || this.lastCookTime != this.tileEntity.furnaceCookTime
          || this.lastEnergyLevel != this.tileEntity.getEnergyLevel()
          || this.lastBatteryLevel != this.tileEntity.batteryLevel) {
        tileEntity.updateTE();
      }
    }

    this.lastTimer = this.tileEntity.furnaceTimer;
    this.lastEnergyLevel = this.tileEntity.getEnergyLevel();
    this.lastBatteryLevel = this.tileEntity.batteryLevel;
  }
  @Override
  protected boolean mergeItemStack(ItemStack stack, int start, int end, boolean backwards) {
    boolean flag1 = false;
    int k = (backwards ? end - 1 : start);
    Slot slot;
    ItemStack itemstack1;

    if (stack.isStackable()) {
      while (stack.stackSize > 0 && (!backwards && k < end || backwards && k >= start)) {
        slot = (Slot) inventorySlots.get(k);
        itemstack1 = slot.getStack();

        if (!slot.isItemValid(stack)) {
          continue;
        }

        if (itemstack1 != null
            && itemstack1.getItem() == stack.getItem()
            && (!stack.getHasSubtypes() || stack.getItemDamage() == itemstack1.getItemDamage())
            && ItemStack.areItemStackTagsEqual(stack, itemstack1)) {
          int l = itemstack1.stackSize + stack.stackSize;

          if (l <= stack.getMaxStackSize() && l <= slot.getSlotStackLimit()) {
            stack.stackSize = 0;
            itemstack1.stackSize = l;
            tileEntity.markDirty();
            flag1 = true;
          } else if (itemstack1.stackSize < stack.getMaxStackSize()
              && l < slot.getSlotStackLimit()) {
            stack.stackSize -= stack.getMaxStackSize() - itemstack1.stackSize;
            itemstack1.stackSize = stack.getMaxStackSize();
            tileEntity.markDirty();
            flag1 = true;
          }
        }

        k += (backwards ? -1 : 1);
      }
    }

    if (stack.stackSize > 0) {
      k = (backwards ? end - 1 : start);

      while (!backwards && k < end || backwards && k >= start) {
        slot = (Slot) inventorySlots.get(k);
        itemstack1 = slot.getStack();

        if (!slot.isItemValid(stack)) {
          continue;
        }

        if (itemstack1 == null) {
          int l = stack.stackSize;

          if (l <= slot.getSlotStackLimit()) {
            slot.putStack(stack.copy());
            stack.stackSize = 0;
            tileEntity.markDirty();
            flag1 = true;
            break;
          } else {
            putStackInSlot(
                k, new ItemStack(stack.getItem(), slot.getSlotStackLimit(), stack.getItemDamage()));
            stack.stackSize -= slot.getSlotStackLimit();
            tileEntity.markDirty();
            flag1 = true;
          }
        }

        k += (backwards ? -1 : 1);
      }
    }

    return flag1;
  }
 @Override
 public boolean canInteractWith(EntityPlayer entityplayer) {
   return tileEntity.isUseableByPlayer(entityplayer);
 }