public static IReadOnlyList <Cycle <TVertex> > GetCycles <TVertex, TEdge>(
            this BidirectionalGraph <TVertex, TEdge> graph)
            where TEdge : IEdge <TVertex>
        {
            // Initialize vertex, and current stack tracking
            var visited = new HashSet <TVertex>();
            var stack   = new List <TVertex>();
            var cycles  = new List <Cycle <TVertex> >();

            // Call the recursive helper function to detect cycle in different DFS trees
            foreach (var vertex in graph.Vertices)
            {
                _logger.Debug($"Probing node '{vertex}' for cyclical dependencies...");
                graph.FindCycles(vertex, visited, stack, cycles);
            }

            return(cycles);
        }
        private static void FindCycles <TVertex, TEdge>(
            this BidirectionalGraph <TVertex, TEdge> executionGraph,
            TVertex vertex,
            HashSet <TVertex> visited,
            List <TVertex> stack,
            List <Cycle <TVertex> > cycles)
            where TEdge : IEdge <TVertex>
        {
            // Do we have a circular dependency?
            if (stack.Contains(vertex))
            {
                var cycle = new Cycle <TVertex>
                {
                    Vertex = vertex.ToString(),
                    Path   = stack.SkipWhile(x => !x.Equals(vertex))
                             .Concat(new[] { vertex })
                             .ToList()
                };

                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug($"Cycle found for vertex '{cycle.Vertex}': {string.Join(" --> ", cycle.Path.Select(x => x.ToString()))}");
                }

                cycles.Add(cycle);
                visited.Add(vertex);
                return;
            }

            // If we've already evaluated this vertex, stop now.
            if (visited.Contains(vertex))
            {
                return;
            }

            // Mark the current node as visited and part of recursion stack
            visited.Add(vertex);
            stack.Add(vertex);

            try
            {
                var children = executionGraph
                               .OutEdges(vertex)
                               .Select(x => x.Target)
                               .ToList();

                if (_logger.IsDebugEnabled)
                {
                    if (children.Any())
                    {
                        _logger.Debug($"Children of {vertex}: {string.Join(" => ", children.Select(x => x.ToString()))}");
                    }
                }

                foreach (var child in children)
                {
                    executionGraph.FindCycles(child, visited, stack, cycles);
                }
            }
            finally
            {
                stack.Remove(vertex);
            }
        }