Set<NodeSource> (Iterable<NodeSource> sources, Iterable<NodeSource> deletedSources) { // ensure initial sources are in the result Set<NodeSource> result = Iterators.collect(sources, new HashSet<>()); // todo: check if a special hashing-policy set is required here Set<NodeSource> deleted = Iterators.collect(deletedSources, new HashSet<>()); Set<Node<?, ?>> affectedNodes = Iterators.collect(Iterators.flat(Iterators.map(Iterators.flat(result, deleted), s -> getNodes(s))), new HashSet<>()); for (var node : affectedNodes) { Iterators.collect(Iterators.filter(getSources(node.getReferenceID()), s -> !result.contains(s) && !deleted.contains(s) && Iterators.filter(getNodes(s).iterator(), affectedNodes::contains).hasNext()), result); } return result; }