public static PowerSourceList combine(
      PowerSourceList in1, PowerSourceList in2, ShaftMerger caller) {
    PowerSourceList psl = new PowerSourceList();
    psl.engines.addAll(in1.engines);
    psl.engines.addAll(in2.engines);

    psl.mergers.addAll(in1.mergers);
    psl.mergers.addAll(in2.mergers);

    if (psl.mergers.contains(caller)) {
      psl.isLooping = true;
    }

    psl.caller = caller;

    return psl;
  }
  public static PowerSourceList getAllFrom(
      World world,
      ForgeDirection dir,
      int x,
      int y,
      int z,
      PowerSourceTracker io,
      ShaftMerger caller) {
    PowerSourceList pwr = new PowerSourceList();

    TileEntity tile = world.getTileEntity(x, y, z);

    if (caller != null) {
      if (pwr.passesThrough(caller)
          || (tile instanceof ShaftMerger && pwr.passesThrough((ShaftMerger) tile))
          || tile == caller) {
        pwr.isLooping = true;
        caller.onPowerLooped(pwr);
        return pwr;
      }
    }

    if (tile instanceof ShaftMerger) {
      pwr.mergers.add((ShaftMerger) tile);
      if (tile == caller) {
        pwr.isLooping = true;
      }
    }

    try {
      if (tile instanceof TileEntityIOMachine) {
        TileEntityIOMachine te = (TileEntityIOMachine) tile;
        if (!te.isWritingTo(io) && !te.isWritingTo2(io)) {
          return pwr;
        }
        if (te.isReadingFrom(io)
            || te.isReadingFrom2(io)
            || te.isReadingFrom3(io)
            || te.isReadingFrom4(io)) {
          return pwr;
        }
        pwr.addAll(te.getPowerSources(io, caller));
      } else if (tile instanceof PowerSourceTracker) {
        pwr.addAll(((PowerSourceTracker) tile).getPowerSources(io, caller));
      } else if (tile instanceof PowerGenerator) {
        pwr.addSource((PowerGenerator) tile);
      } else if (tile instanceof WorldRift) {
        WorldLocation loc = ((WorldRift) tile).getLinkTarget();
        if (loc != null) {
          int dx = loc.xCoord + dir.offsetX;
          int dy = loc.yCoord + dir.offsetY;
          int dz = loc.zCoord + dir.offsetZ;
          return getAllFrom(world, dir, dx, dy, dz, io, caller);
        }
      }
      pwr.caller = caller;

      if (pwr.passesThrough(caller)) {
        pwr.isLooping = true;
      }

      return pwr;
    } catch (StackOverflowError e) {
      // e.printStackTrace();
      RotaryCraft.logger.logError("PowerSourceList SOE!");
      return pwr;
    }
  }