/** @return How much oxygen this network needs. */
  @Override
  public float getRequest(TileEntity... ignoreTiles) {
    List<Float> requests = new ArrayList<Float>();

    if (this.oxygenTiles.isEmpty()) this.refreshOxygenTiles();

    List<TileEntity> ignoreTilesList = Arrays.asList(ignoreTiles);
    for (TileEntity tileEntity : new HashSet<TileEntity>(this.oxygenTiles.keySet())) {
      if (ignoreTilesList.contains(tileEntity)) {
        continue;
      }

      if (tileEntity instanceof IOxygenReceiver
          && ((IOxygenReceiver) tileEntity).shouldPullOxygen()) {
        if (!tileEntity.isInvalid()) {
          if (tileEntity
                  .getWorldObj()
                  .getTileEntity(tileEntity.xCoord, tileEntity.yCoord, tileEntity.zCoord)
              == tileEntity) {
            for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) {
              BlockVec3 tileVec = new BlockVec3(tileEntity);
              TileEntity tile =
                  tileVec
                      .modifyPositionFromSide(direction, 1)
                      .getTileEntity(tileEntity.getWorldObj());

              if (((IOxygenReceiver) tileEntity).canConnect(direction, NetworkType.OXYGEN)
                  && this.pipes.contains(tile)) {
                requests.add(((IOxygenReceiver) tileEntity).getOxygenRequest(direction));
              }
            }
          }
        }
      }
    }

    float total = 0.0F;

    for (Float f : requests) {
      total += f;
    }

    return total;
  }
  @Override
  public float produce(float totalOxygen, TileEntity... ignoreTiles) {
    float remainingUsableOxygen = totalOxygen;

    if (this.oxygenTiles.isEmpty()) this.refreshOxygenTiles();

    if (!this.oxygenTiles.isEmpty()) {
      final float totalOxygenRequest = this.getRequest(ignoreTiles);

      if (totalOxygenRequest > 0) {
        List<TileEntity> ignoreTilesList = Arrays.asList(ignoreTiles);
        for (TileEntity tileEntity : new HashSet<TileEntity>(this.oxygenTiles.keySet())) {
          if (!ignoreTilesList.contains(tileEntity)) {
            if (tileEntity instanceof IOxygenReceiver) {
              IOxygenReceiver oxygenTile = (IOxygenReceiver) tileEntity;

              if (oxygenTile.shouldPullOxygen()) {
                for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) {
                  TileEntity tile =
                      new BlockVec3(tileEntity)
                          .modifyPositionFromSide(direction, 1)
                          .getTileEntity(tileEntity.getWorldObj());

                  if (oxygenTile.canConnect(direction, NetworkType.OXYGEN)
                      && this.pipes.contains(tile)) {
                    float oxygenToSend =
                        Math.max(
                            totalOxygen,
                            totalOxygen
                                * (oxygenTile.getOxygenRequest(direction) / totalOxygenRequest));

                    if (oxygenToSend > 0) {
                      remainingUsableOxygen -=
                          oxygenTile.receiveOxygen(direction, oxygenToSend, true);
                    }
                  }
                }
              }
            } else if (EnergyConfigHandler.isMekanismLoaded()
                && tileEntity instanceof IGasHandler) {
              IGasHandler gasHandler = (IGasHandler) tileEntity;

              for (ForgeDirection direction : ForgeDirection.VALID_DIRECTIONS) {
                TileEntity tile =
                    new BlockVec3(tileEntity)
                        .getTileEntityOnSide(tileEntity.getWorldObj(), direction);

                if (gasHandler.canReceiveGas(direction, (Gas) EnergyConfigHandler.gasOxygen)
                    && this.getTransmitters().contains(tile)) {
                  int oxygenToSend = (int) Math.floor(totalOxygen / this.oxygenTiles.size());

                  if (oxygenToSend > 0) {
                    try {
                      remainingUsableOxygen -=
                          gasHandler.receiveGas(
                              direction,
                              (new GasStack((Gas) EnergyConfigHandler.gasOxygen, oxygenToSend)));
                    } catch (Exception e) {
                    }
                  }
                }
              }
            }
          }
        }
      }
    }

    return remainingUsableOxygen;
  }