public static IEnumerable <IEnumerable <T> > TopologySortDesc <T> (
     this IEnumerable <T> source,
     Func <T, IEnumerable <T> > getDependencies,
     Func <IEnumerable <T>, IEnumerable <T> > subSort,
     TopologySortMissingDependencyBehavior missingDependencies
     )
 {
     return(TopologySort(source, getDependencies, subSort, missingDependencies).Reverse());
 }
            public void CalculateDependencies(Dictionary <object, Node <T> > nodes, TopologySortMissingDependencyBehavior missingDependencies)
            {
                _dependencies = new HashSet <Node <T> >();
                foreach (T dependency in _getDependencies(Content))
                {
                    Node <T> node;
                    if (!nodes.TryGetValue(dependency, out node))
                    {
                        switch (missingDependencies)
                        {
                        case TopologySortMissingDependencyBehavior.Ignore:
                            node = null;
                            break;

                        case TopologySortMissingDependencyBehavior.Respect:
                            node = new Node <T> (dependency, _getDependencies, false);
                            break;

                        case TopologySortMissingDependencyBehavior.Include:
                            node = new Node <T> (dependency, _getDependencies, true);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException("missingDependencies");
                        }
                        if (node != null)
                        {
                            nodes.Add(node.Content, node);
                            node.CalculateDependencies(nodes, missingDependencies);
                        }
                    }
                    if (node != null)
                    {
                        AddDependency(node);
                    }
                }
            }
        /// <summary>
        /// Sorts the objects given in <paramref name="source"/> using a topology-sort algorithm.
        /// The graph structure is defined by the <paramref name="getDependencies"/> delegate which should supply the
        /// dependencies for each object to sort, i.e. the edges of the graph.
        /// The <paramref name="subSort"/> delegate, if supplied, specifies how objects will be sorted whose sort-order cannot
        /// be determined by the graph structure.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <param name="getDependencies"></param>
        /// <param name="subSort"></param>
        /// <param name="missingDependencies">
        /// Controls how to process dependencies which were not included in the original <paramref name="source"/>.
        /// See <see cref="TopologySortMissingDependencyBehavior"/>.
        /// </param>
        /// <returns>Returns the sorted items of the topology grouped by their hierarchy level starting with the leave-nodes.</returns>
        public static IEnumerable <IEnumerable <T> > TopologySort <T> (
            this IEnumerable <T> source,
            Func <T, IEnumerable <T> > getDependencies,
            Func <IEnumerable <T>, IEnumerable <T> > subSort,
            TopologySortMissingDependencyBehavior missingDependencies
            )
        {
            ArgumentUtility.CheckNotNull("source", source);
            ArgumentUtility.CheckNotNull("getDependencies", getDependencies);

            var unsorted = source.Select(content => new Node <T> (content, getDependencies, true)).ToList();
            Dictionary <object, Node <T> > nodes;

            try
            {
                nodes = unsorted.ToDictionary(node => (object)node.Content);
            }
            catch (ArgumentException e)
            {
                throw new InvalidOperationException("elements to topology-sort are not unique or some element is null.", e);
            }
            unsorted.ForEach(node => node.CalculateDependencies(nodes, missingDependencies));

            if (missingDependencies == TopologySortMissingDependencyBehavior.Include)
            {
                unsorted = nodes.Values.Where(node => node.Included).ToList();
            }

            var sorted = new List <IEnumerable <T> >();

            while (unsorted.Count > 0)
            {
                var unreferred     = new List <Node <T> >();
                var toBeSortedNext = new List <Node <T> >();
                foreach (var node in unsorted)
                {
                    if (node.ReferrerCount == 0)
                    {
                        unreferred.Add(node);
                    }
                    else
                    {
                        toBeSortedNext.Add(node);
                    }
                }
                if (unreferred.Count == 0)
                {
                    throw new InvalidOperationException("Cyclic dependency detected - cannot perform topology sort");
                }

                unsorted = toBeSortedNext;

                var unreferredContents = unreferred.Select(node => node.DropDependencies().Content);
                if (subSort != null)
                {
                    unreferredContents = subSort(unreferredContents);
                }
                sorted.Add(unreferredContents.ToArray());
            }

            return(sorted);
        }