private void advance() {
    if (current == null) {
      if (!subGraphIterator.hasNext()) return;

      current = subGraphIterator.next();
      pathsIterator = null;
    }

    if (pathsIterator == null) {
      Set<FlowElement> sources = findSources(current, FlowElement.class);
      Set<FlowElement> sinks = findSinks(current, FlowElement.class);

      if (sources.size() > 1 || sinks.size() > 1)
        throw new IllegalArgumentException("only supports single source and single sink graphs");

      FlowElement source = getFirst(sources);
      FlowElement sink = getFirst(sinks);

      pairs.add(new Pair<>(source, sink));

      List<GraphPath<FlowElement, Scope>> paths = getAllShortestPathsBetween(current, source, sink);

      if (longestFirst) Collections.reverse(paths); // break off longest paths into own partitions

      pathsIterator = paths.iterator();
    }
  }
  @Override
  public boolean hasNext() {
    if (pathsIterator == null) advance();

    if (current == null || pathsIterator == null) return false;

    boolean hasNextPath = pathsIterator.hasNext();

    if (hasNextPath) return true;

    return subGraphIterator.hasNext();
  }