public static /*<V, E>*/ List <V> GetShortestPath <V, E>(IGraph <V, E> graph, V node1, V node2, bool directionSensitive)
        {
            if (node1.Equals(node2))
            {
                //return Collections.singletonList(node2);
                return(new List <V>()
                {
                    node2
                });
            }

            Set <V> visited        = new Util.HashSet <V>();
            var     previous       = new Dictionary <V, V>();
            var     unsettledNodes = new BinaryHeapPriorityQueue <V>();

            unsettledNodes.Add(node1, 0);

            while (unsettledNodes.Size() > 0)
            {
                var distance = unsettledNodes.GetPriority();
                var u        = unsettledNodes.RemoveFirst();
                visited.Add(u);

                if (u.Equals(node2))
                {
                    break;
                }

                unsettledNodes.Remove(u);

                var candidates = ((directionSensitive) ? graph.GetChildren(u) : new ReadOnlyCollection <V>(graph.GetNeighbors(u)));
                foreach (var candidate in candidates)
                {
                    var alt = distance - 1;
                    // nodes not already present will have a priority of -inf
                    if (alt > unsettledNodes.GetPriority(candidate) && !visited.Contains(candidate))
                    {
                        unsettledNodes.RelaxPriority(candidate, alt);
                        previous[candidate] = u;
                    }
                }
            }

            if (!previous.ContainsKey(node2))
            {
                return(null);
            }
            var path = new List <V>
            {
                node2
            };
            var n = node2;

            while (previous.ContainsKey(n))
            {
                path.Add(previous[n]);
                n = previous[n];
            }
            path.Reverse();
            return(path);
        }