public void TestComputeBestPath()
        {
            NStreamQueryPlanBuilder.BestChainResult bestChain = NStreamQueryPlanBuilder.ComputeBestPath(0, queryGraph, dependencyGraph);
            Assert.AreEqual(3, bestChain.Depth);
            Assert.IsTrue(Arrays.AreEqual(bestChain.Chain, new int[] { 2, 4, 3, 1 }));

            bestChain = NStreamQueryPlanBuilder.ComputeBestPath(3, queryGraph, dependencyGraph);
            Assert.AreEqual(4, bestChain.Depth);
            Assert.IsTrue(Arrays.AreEqual(bestChain.Chain, new int[] { 4, 2, 0, 1 }));

            // try a stream that is not connected in any way
            queryGraph = new QueryGraphForge(6, null, false);
            bestChain  = NStreamQueryPlanBuilder.ComputeBestPath(5, queryGraph, dependencyGraph);
            log.Debug(".testComputeBestPath bestChain=" + bestChain);
            Assert.AreEqual(0, bestChain.Depth);
            Assert.IsTrue(Arrays.AreEqual(bestChain.Chain, new int[] { 0, 1, 2, 3, 4 }));
        }
        private static void AddNotYetNavigated(
            int streamNo,
            int numStreams,
            IDictionary<int, int[]> substreamsPerStream,
            NStreamQueryPlanBuilder.BestChainResult bestChain)
        {
            // sum up all substreams (the query plan for each stream: nested iteration or cardinal)
            ISet<int> streams = new HashSet<int>();
            streams.Add(streamNo);
            RecursiveAdd(streamNo, streamNo, substreamsPerStream, streams, false);

            // we are done, all have navigated
            if (streams.Count == numStreams) {
                return;
            }

            var previous = streamNo;
            foreach (var stream in bestChain.Chain) {
                if (streams.Contains(stream)) {
                    previous = stream;
                    continue;
                }

                // add node as a nested join to the previous stream
                var substreams = substreamsPerStream.Get(previous);
                if (substreams == null) {
                    substreams = new int[0];
                }

                var added = CollectionUtil.AddValue(substreams, stream);
                substreamsPerStream.Put(previous, added);

                if (!substreamsPerStream.ContainsKey(stream)) {
                    substreamsPerStream.Put(stream, new int[0]);
                }

                previous = stream;
            }
        }