@Override
  public int charge(ItemStack stack, int energyInput) {
    IItemElectric item = (IItemElectric) Item.itemsList[stack.itemID];

    double wattsInput = energyInput / getPowerSystem().getInternalEnergyPerOutput();

    ElectricityPack consumed = item.onReceive(ElectricityPack.getFromWatts(wattsInput, 120), stack);

    return MathHelper.floor_double(
        (wattsInput - consumed.getWatts()) * getPowerSystem().getInternalEnergyPerOutput());
  }
  @Override
  public boolean produceUE(ForgeDirection outputDirection) {
    if (!this.worldObj.isRemote
        && outputDirection != null
        && outputDirection != ForgeDirection.UNKNOWN) {
      float provide = this.getProvide(outputDirection);

      if (provide > 0) {
        TileEntity outputTile =
            VectorHelper.getConnectorFromSide(this.worldObj, new Vector3(this), outputDirection);
        IElectricityNetwork outputNetwork =
            ElectricityHelper.getNetworkFromTileEntity(outputTile, outputDirection);
        if (outputNetwork != null) {
          ElectricityPack powerRequest = outputNetwork.getRequest(this);

          if (powerRequest.getWatts() > 0) {
            ElectricityPack sendPack =
                ElectricityPack.min(
                    ElectricityPack.getFromWatts(this.getEnergyStored(), this.getVoltage()),
                    ElectricityPack.getFromWatts(provide, this.getVoltage()));
            float rejectedPower = outputNetwork.produce(sendPack, this);
            this.provideElectricity(sendPack.getWatts() - rejectedPower, true);
            return true;
          }
        } else if (outputTile instanceof IElectrical) {
          float requestedEnergy =
              ((IElectrical) outputTile).getRequest(outputDirection.getOpposite());

          if (requestedEnergy > 0) {
            ElectricityPack sendPack =
                ElectricityPack.min(
                    ElectricityPack.getFromWatts(this.getEnergyStored(), this.getVoltage()),
                    ElectricityPack.getFromWatts(provide, this.getVoltage()));
            float acceptedEnergy =
                ((IElectrical) outputTile)
                    .receiveElectricity(outputDirection.getOpposite(), sendPack, true);
            this.setEnergyStored(this.getEnergyStored() - acceptedEnergy);
            return true;
          }
        }
      }
    }

    return false;
  }
  @RuntimeInterface(clazz = "ic2.api.energy.tile.IEnergySink", modID = "IC2")
  public double injectEnergyUnits(ForgeDirection direction, double amount) {
    if (this.getInputDirections().contains(direction)) {
      float convertedEnergy = (float) (amount * Compatibility.IC2_RATIO);
      ElectricityPack toSend = ElectricityPack.getFromWatts(convertedEnergy, this.getVoltage());
      float receive = this.receiveElectricity(direction, toSend, true);

      // Return the difference, since injectEnergy returns left over
      // energy, and
      // receiveElectricity returns energy used.
      return Math.round(amount - receive * Compatibility.TO_IC2_RATIO);
    }

    return amount;
  }
  @Override
  public void updateEntity() {
    super.updateEntity();

    if (!this.worldObj.isRemote) {
      if (!this.isDisabled() && this.isActive()) {
        if (this.isInversed && Settings.ENABLE_ELECTRICITY) {
          // Convert Fortron to Electricity
          double watts = Math.min(this.getFortronEnergy() * FORTRON_UE_RATIO, WATTAGE);

          ElectricityPack remainder = this.produce(watts);

          double electricItemGiven = 0;

          if (remainder.getWatts() > 0) {
            electricItemGiven =
                ElectricItemHelper.chargeItem(
                    this.getStackInSlot(SLOT_BATTERY), remainder.getWatts(), this.getVoltage());
          }

          this.requestFortron(
              (int) ((watts - (remainder.getWatts() - electricItemGiven)) / FORTRON_UE_RATIO),
              true);

          this.animation++;
        } else {
          // Convert Electricity to Fortron
          this.wattsReceived +=
              ElectricItemHelper.dechargeItem(
                  this.getStackInSlot(SLOT_BATTERY), WATTAGE, this.getVoltage());

          if (this.wattsReceived >= TileEntityCoercionDeriver.WATTAGE
              || !Settings.ENABLE_ELECTRICITY) {
            int production = 3;

            if (this.isStackValidForSlot(SLOT_FUEL, this.getStackInSlot(SLOT_FUEL))) {
              production *= NORMAL_PRODUCTION;
            }

            this.fortronTank.fill(
                FortronHelper.getFortron(production + this.worldObj.rand.nextInt(production)),
                true);

            if (this.processTime == 0) {
              this.decrStackSize(SLOT_FUEL, 1);
              this.processTime = REQUIRED_TIME;

              if (this.getModuleCount(ModularForceFieldSystem.itemModuleSpeed) > 0) {
                this.processTime =
                    this.processTime
                        * this.getModuleCount(ModularForceFieldSystem.itemModuleSpeed)
                        / 30;
              }
            }

            if (this.processTime > 0) {
              // We are processing
              this.processTime--;

              if (this.processTime < 1) {
                this.processTime = 0;
              }
            } else {
              this.processTime = 0;
            }

            this.wattsReceived -= WATTAGE;
          }
        }
      }
    } else if (this.isActive()) {
      this.animation++;
    }
  }