@Override
  public boolean validateBeforeStart(
      EntityRef instigator, EntityRef workstation, EntityRef processEntity) {
    if (!workstation.hasComponent(WorkstationInventoryComponent.class)) {
      return false;
    }

    // Defer the heat calculation until it is actually needed
    Float heat = null;

    for (int slot : WorkstationInventoryUtils.getAssignedSlots(workstation, "INPUT")) {
      HeatProcessedComponent processed =
          InventoryUtils.getItemAt(workstation, slot).getComponent(HeatProcessedComponent.class);
      if (processed != null) {
        float heatRequired = processed.heatRequired;
        if (heat == null) {
          heat =
              HeatUtils.calculateHeatForEntity(
                  workstation, CoreRegistry.get(BlockEntityRegistry.class));
        }
        if (heatRequired <= heat) {
          final String result =
              processed.blockResult != null ? processed.blockResult : processed.itemResult;
          if (canOutputResult(workstation, result)) {
            processEntity.addComponent(new SpecificInputSlotComponent(slot));
            processEntity.addComponent(new OutputTypeComponent(result));
            return true;
          }
        }
      }
    }

    return false;
  }
 private boolean isInputSlot(EntityRef workstation, int slotNo) {
   for (int slot : WorkstationInventoryUtils.getAssignedSlots(workstation, "INPUT")) {
     if (slot == slotNo) {
       return true;
     }
   }
   return false;
 }
 @Override
 public boolean isResponsibleForSlot(EntityRef workstation, int slotNo) {
   if (isInputSlot(workstation, slotNo)) {
     return true;
   }
   for (int slot : WorkstationInventoryUtils.getAssignedSlots(workstation, "OUTPUT")) {
     if (slot == slotNo) {
       return true;
     }
   }
   return false;
 }
 private boolean canOutputResult(EntityRef workstation, String resultObject) {
   EntityRef resultItem = createResultItem(resultObject);
   try {
     for (int outputSlot : WorkstationInventoryUtils.getAssignedSlots(workstation, "OUTPUT")) {
       if (InventoryUtils.canStackInto(
           resultItem, InventoryUtils.getItemAt(workstation, outputSlot))) {
         return true;
       }
     }
   } finally {
     resultItem.destroy();
   }
   return false;
 }
  @Override
  public void executeEnd(EntityRef instigator, EntityRef workstation, EntityRef processEntity) {
    OutputTypeComponent output = processEntity.getComponent(OutputTypeComponent.class);
    EntityRef toGive = createResultItem(output.type);

    if (CoreRegistry.get(InventoryManager.class)
        .giveItem(
            workstation,
            instigator,
            toGive,
            WorkstationInventoryUtils.getAssignedSlots(workstation, "OUTPUT"))) {
      return;
    }
    toGive.destroy();
  }