private static IEnumerable <List <V> > FindAllPathsInternal <V, E>(this IDirectedGraph <V, E> graph, V start, V destination, List <V> localPath, HashSet <V> alreadyUsed, IEqualityComparer <V> vertexComparer) { using (Trace.Entering()) { localPath.Add(start); var toGo = graph.GetEdgesGoingFrom(start) .Select(x => x.To) .ToHashSet(vertexComparer); foreach (var to in toGo) { if (vertexComparer.Equals(to, destination)) { localPath.Add(to); // Provide the whole path. List <V> result = localPath.ToList(); localPath.RemoveAt(localPath.Count - 1); yield return(result); // If the self-reference is not included yet. if (!vertexComparer.Equals(start, to)) { List <V> pathWithSelfreferencingDestination = null; bool selfReferencingDestination = graph.GetEdges(destination, destination).Any(); if (selfReferencingDestination) { pathWithSelfreferencingDestination = result.ToList(); pathWithSelfreferencingDestination.Add(destination); yield return(pathWithSelfreferencingDestination); } // If an edge to itself exists then include it to the result. if (toGo.Contains(start)) { var pathWithSelfReference = result.ToList(); pathWithSelfReference.Insert(result.Count - 1, start); yield return(pathWithSelfReference); if (selfReferencingDestination) { var pathWithBothSelfReferences = pathWithSelfReference.ToList(); pathWithBothSelfReferences.Add(destination); yield return(pathWithBothSelfReferences); } } } } else if (alreadyUsed.Add(to)) { IEnumerable <List <V> > foundPaths = graph.FindAllPathsInternal(to, destination, localPath, alreadyUsed, vertexComparer); foreach (var path in foundPaths) { // Return the path. yield return(path); } alreadyUsed.Add(start); } } localPath.RemoveAt(localPath.Count - 1); } }