@Override
 public void onNeighborChanged() {
   this.cachedTank = null;
   if (this.output) {
     PartP2PLiquids in = this.getInput();
     if (in != null) {
       in.onTunnelNetworkChange();
     }
   }
 }
  List<PartP2PLiquids> getOutputs(Fluid input) {
    List<PartP2PLiquids> outs = new LinkedList<PartP2PLiquids>();

    try {
      for (PartP2PLiquids l : this.getOutputs()) {
        IFluidHandler handler = l.getTarget();
        if (handler != null) {
          if (handler.canFill(l.side.getOpposite(), input)) {
            outs.add(l);
          }
        }
      }
    } catch (GridAccessException e) {
      // :P
    }

    return outs;
  }
  @Override
  public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
    Stack<PartP2PLiquids> stack = this.getDepth();

    for (PartP2PLiquids t : stack) {
      if (t == this) {
        return 0;
      }
    }

    stack.push(this);

    List<PartP2PLiquids> list = this.getOutputs(resource.getFluid());
    int requestTotal = 0;

    Iterator<PartP2PLiquids> i = list.iterator();
    while (i.hasNext()) {
      PartP2PLiquids l = i.next();
      IFluidHandler tank = l.getTarget();
      if (tank != null) {
        l.tmpUsed = tank.fill(l.side.getOpposite(), resource.copy(), false);
      } else {
        l.tmpUsed = 0;
      }

      if (l.tmpUsed <= 0) {
        i.remove();
      } else {
        requestTotal += l.tmpUsed;
      }
    }

    if (requestTotal <= 0) {
      if (stack.pop() != this) {
        throw new IllegalStateException("Invalid Recursion detected.");
      }

      return 0;
    }

    if (!doFill) {
      if (stack.pop() != this) {
        throw new IllegalStateException("Invalid Recursion detected.");
      }

      return Math.min(resource.amount, requestTotal);
    }

    int available = resource.amount;
    int used = 0;

    i = list.iterator();
    while (i.hasNext()) {
      PartP2PLiquids l = i.next();

      FluidStack insert = resource.copy();
      insert.amount = (int) Math.ceil(insert.amount * ((double) l.tmpUsed / (double) requestTotal));
      if (insert.amount > available) {
        insert.amount = available;
      }

      IFluidHandler tank = l.getTarget();
      if (tank != null) {
        l.tmpUsed = tank.fill(l.side.getOpposite(), insert.copy(), true);
      } else {
        l.tmpUsed = 0;
      }

      available -= insert.amount;
      used += insert.amount;
    }

    if (stack.pop() != this) {
      throw new IllegalStateException("Invalid Recursion detected.");
    }

    return used;
  }