public static async Task Traverse(this CakeGraph graph, string target,
                                          Func <string, CancellationTokenSource, Task> executeTask)
        {
            if (!graph.Exist(target))
            {
                return;
            }
            if (graph.hasCircularReferences(target))
            {
                throw new CakeException("Graph contains circular references.");
            }

            var cancellationTokenSource = new CancellationTokenSource();
            var visitedNodes            = new Dictionary <string, Task>();
            await graph.traverse(target, executeTask, cancellationTokenSource, visitedNodes);
        }
        private static bool hasCircularReferences(this CakeGraph graph, string nodeName, Stack <string> visited = null)
        {
            visited = visited ?? new Stack <string>();

            if (visited.Contains(nodeName))
            {
                return(true);
            }

            visited.Push(nodeName);
            var hasCircularReference = graph.Edges
                                       .Where(_ => _.End.Equals(nodeName, StringComparison.OrdinalIgnoreCase))
                                       .Any(_ => graph.hasCircularReferences(_.Start, visited));

            visited.Pop();
            return(hasCircularReference);
        }