@@ -0,0 +1,2233 @@
+package uk.ac.ebi.quickgo.ontology.traversal;%0A%0Aimport uk.ac.ebi.quickgo.ontology.model.AncestorGraph;%0Aimport uk.ac.ebi.quickgo.ontology.model.OntologyRelationType;%0Aimport uk.ac.ebi.quickgo.ontology.model.OntologyRelationship;%0A%0Aimport java.util.Deque;%0Aimport java.util.Objects;%0Aimport java.util.Optional;%0Aimport java.util.Set;%0A%0A/**%0A * @author Tony Wardell%0A * Date: 19/06/2017%0A * Time: 10:11%0A * Created with IntelliJ IDEA.%0A */%0Apublic class SubGraphCalculator %7B%0A%0A    public static Trampoline%3CAncestorGraph%3E createTrampoline(Deque%3CString%3E targetVertices, Set%3CString%3E stopNodes,%0A            OntologyRelationType%5B%5D targetRelations, AncestorGraph ancestorGraph, OntologyGraph ontologyGraph) %7B%0A%0A        String target = targetVertices.pollFirst();%0A%0A        //if target is null, or is a stop node, and we don't have any more to process then don't create any more%0A        if (Objects.isNull(target) %7C%7C stopNodes.contains(target) && targetVertices.isEmpty()) %7B%0A            return new Trampoline%3CAncestorGraph%3E()%7B%0A                public AncestorGraph getValue() %7B return ancestorGraph; %7D%0A            %7D;%0A        %7D%0A%0A        //If target has any parents, add to deque%0A        Set%3COntologyRelationship%3E parents = null;%0A        try %7B%0A            parents = ontologyGraph.parents(target, targetRelations);%0A        %7D catch (Exception e) %7B%0A%0A            //Finish up if we have an exception%0A            return new Trampoline%3CAncestorGraph%3E()%7B%0A                public AncestorGraph getValue() %7B return ancestorGraph; %7D%0A            %7D;%0A        %7D%0A%0A        //Add parents to work queue%0A        if (!parents.isEmpty()) %7B%0A            parents.stream()%0A                   .map(p -%3E p.parent)%0A                   .forEach(parent -%3E targetVertices.addLast(parent));%0A        %7D%0A%0A        //Add this vertex, and edges from this vertex to result%0A        ancestorGraph.vertices.add(target);%0A        ancestorGraph.edges.addAll(parents);%0A%0A        //Create new Trampoline with current work queue.%0A        return new Trampoline%3CAncestorGraph%3E() %7B%0A            public Optional%3CTrampoline%3CAncestorGraph%3E%3E nextTrampoline() %7B%0A                return Optional.of(createTrampoline(targetVertices, stopNodes, targetRelations, ancestorGraph, ontologyGraph));%0A            %7D%0A        %7D;%0A    %7D%0A%7D%0A

Use trampolining for sub graph iteration.