/// <summary>
        /// The Topological Sorting algorithm
        /// </summary>
        public static IEnumerable <T> Sort <T>(IGraph <T> Graph) where T : IComparable <T>
        {
            // If the graph is either null or is not a DAG, throw exception.
            if (Graph == null)
            {
                throw new ArgumentNullException();
            }
            else if (!Graph.IsDirected || CyclesDetector.IsCyclic <T>(Graph))
            {
                throw new Exception("The graph is not a DAG.");
            }

            var visited       = new HashSet <T>();
            var topoSortStack = new DataStructures.Lists.Stack <T>();

            foreach (var vertex in Graph.Vertices)
            {
                if (!visited.Contains(vertex))
                {
                    _topoSortHelper <T>(Graph, vertex, ref topoSortStack, ref visited);
                }
            }

            return(topoSortStack);
        }
        /// <summary>
        /// Returns an enumerable collection of nodes that specify the shortest path from the source vertex to the destination vertex.
        /// </summary>
        public IEnumerable <TVertex> ShortestPathTo(TVertex destination)
        {
            if (!_nodesToIndices.ContainsKey(destination))
            {
                throw new Exception("Graph doesn't have the specified vertex.");
            }
            else if (!HasPathTo(destination))
            {
                return(null);
            }

            int dstIndex = _nodesToIndices[destination];
            var stack    = new DataStructures.Lists.Stack <TVertex>();

            int index;

            for (index = dstIndex; _distances[index] != 0; index = _predecessors[index])
            {
                stack.Push(_indicesToNodes[index]);
            }

            // Push the source vertex
            stack.Push(_indicesToNodes[index]);

            return(stack);
        }
        /// <summary>
        /// Private recursive helper.
        /// </summary>
        private static void _topoSortHelper <T>(IGraph <T> graph, T source, ref DataStructures.Lists.Stack <T> topoSortStack, ref HashSet <T> visited) where T : IComparable <T>
        {
            visited.Add(source);

            foreach (var adjacent in graph.Neighbours(source))
            {
                if (!visited.Contains(adjacent))
                {
                    _topoSortHelper <T>(graph, adjacent, ref topoSortStack, ref visited);
                }
            }

            topoSortStack.Push(source);
        }