@Override
 public void setWorldObj(World worldIn) {
   // LOGGER.debug("setWorldObj: " + worldIn);
   super.setWorldObj(worldIn);
   if (worldIn != null && !worldIn.isRemote) {
     _workbench = new Workbench(worldIn);
     _broadcastHelper = new Broadcaster.BroadcastHelper(worldIn.provider.getDimensionId());
   } else {
     if (_workbench != null) _workbench.terminate();
     _workbench = null;
     _broadcastHelper = null;
   }
 }
  @Override
  public void writeToNBT(NBTTagCompound compound) {
    //        LOGGER.debug("writeToNBT");
    super.writeToNBT(compound);
    compound.setShort(NBT_TICKS_TO_CRAFT, (short) _ticksToCraft);
    compound.setShort(NBT_TICKS_CRAFTED, (short) _ticksCrafted);
    NBTTagList nbtItemList = new NBTTagList();

    for (int i = 0; i < _craftingMatrix.getSizeInventory(); ++i) {
      if (_craftingMatrix.getStackInSlot(i) != null) {
        //                LOGGER.debug("Adding slot=" + i + ", content:" +
        // _craftingMatrix.getStackInSlot(i));
        NBTTagCompound nbtTagCompound = new NBTTagCompound();
        nbtTagCompound.setByte(NBT_SLOT, (byte) i);
        _craftingMatrix.getStackInSlot(i).writeToNBT(nbtTagCompound);
        nbtItemList.appendTag(nbtTagCompound);
      }
    }

    if (_craftOutput.getStackInSlot(0) != null) {
      //            LOGGER.debug("Adding craftingOutput=" + _craftOutput.getStackInSlot(0));
      NBTTagCompound nbtTagCompound = new NBTTagCompound();
      nbtTagCompound.setByte(NBT_SLOT, (byte) 9);
      _craftOutput.getStackInSlot(0).writeToNBT(nbtTagCompound);
      nbtItemList.appendTag(nbtTagCompound);
    }

    if (_controls.getStackInSlot(0) != null) {
      //            LOGGER.debug("Adding controls=" + _controls.getStackInSlot(0));
      NBTTagCompound nbtTagCompound = new NBTTagCompound();
      nbtTagCompound.setByte(NBT_SLOT, (byte) 10);
      _controls.getStackInSlot(0).writeToNBT(nbtTagCompound);
      nbtItemList.appendTag(nbtTagCompound);
    }

    compound.setTag(NBT_ITEMS, nbtItemList);

    if (hasCustomName()) {
      compound.setString(NBT_CUSTOM_NAME, _customName);
    }

    LOGGER.debug("Finished writing NBT: " + compound);
  }
  @Override
  public void readFromNBT(NBTTagCompound compound) {
    LOGGER.debug("readFromNBT: " + compound);
    super.readFromNBT(compound);
    // NOTE:  10 is a type not a size...
    NBTTagList nbttaglist = compound.getTagList(NBT_ITEMS, 10);
    //        LOGGER.debug("after super read: " + compound);
    //        LOGGER.debug("Item="+nbttaglist);

    boolean enabled = false;
    for (int i = 0; i < nbttaglist.tagCount(); ++i) {
      NBTTagCompound nbtTagCompound = nbttaglist.getCompoundTagAt(i);
      byte b0 = nbtTagCompound.getByte(NBT_SLOT);

      // This is the output slot
      if (b0 == 9) {
        ItemStack stack = ItemStack.loadItemStackFromNBT(nbtTagCompound);
        _craftOutput.setInventorySlotContents(0, stack);
        //                LOGGER.debug("craftedOutput from NBT: slot=" + b0 +", stack=" + stack);
      }
      // Control slot
      else if (b0 == 10) {
        ItemStack stack = ItemStack.loadItemStackFromNBT(nbtTagCompound);
        _controls.setInventorySlotContents(0, stack);
        enabled = (stack != null && stack.stackSize > 0);
        //                LOGGER.debug("control from NBT: slot=" + b0 +", stack=" + stack);
      } else if (b0 >= 0 && b0 < _craftingMatrix.getSizeInventory()) {
        ItemStack stack = ItemStack.loadItemStackFromNBT(nbtTagCompound);
        _craftingMatrix.setInventorySlotContents(b0, stack);
        //                LOGGER.debug("itemStack from NBT: slot=" + b0 +", stack=" + stack);
      }
    }

    _ticksToCraft = compound.getShort(NBT_TICKS_TO_CRAFT);
    _ticksCrafted = compound.getShort(NBT_TICKS_CRAFTED);
    setEnabled(enabled);

    if (compound.hasKey(NBT_CUSTOM_NAME, 8)) {
      _customName = compound.getString(NBT_CUSTOM_NAME);
    }
  }