//----------------< function to get dependency nodes >--------------------
        public List <CsNode <string, string> > getGraph(List <Tuple <string, string> > graph, List <string> files)
        {
            List <CsNode <string, string> > nodes = new List <CsNode <string, string> >();

            for (int i = 0; i < files.Count; i++)
            {
                CsNode <string, string> node = new CsNode <string, string>(files[i]);
                node.name = Path.GetFileName(files[i]);
                nodes.Add(node);
            }

            int n = graph.Count;

            for (int i = 0; i < graph.Count; i++)
            {
                int j = 0;
                for (j = 0; j < nodes.Count; j++)
                {
                    if (nodes[j].name == graph[i].Item1)
                    {
                        break;
                    }
                }
                for (int k = 0; k < nodes.Count; k++)
                {
                    if (nodes[k].name == graph[i].Item2 && j < graph.Count)
                    {
                        nodes[j].addChild(nodes[k], " ");
                    }
                }
            }

            return(nodes);
        }
        //----< depth first search from specific node >------------------------

        public void walk(CsNode <V, E> node)
        {
            // process this node

            gop.doNodeOp(node);
            node.visited = true;

            // visit children
            do
            {
                CsEdge <V, E> childEdge = node.getNextUnmarkedChild();
                if (childEdge == null)
                {
                    return;
                }
                else
                {
                    gop.doEdgeOp(childEdge.edgeValue);
                    walk(childEdge.targetNode);
                    if (node.hasUnmarkedChild() || showBackTrack)
                    {                         // popped back to predecessor node
                        gop.doNodeOp(node);   // more edges to visit so announce
                    }                         // location and next edge
                }
            } while (true);
        }
        //----------------< function to get strongly connected components >--------------------
        public List <string> Tarjan(List <CsNode <string, string> > m)
        {
            var index = 0;
            var S     = new Stack <CsNode <string, string> >();

            void StrongConnect(CsNode <string, string> v)
            {
                v.Index   = index;
                v.LowLink = index;
                string sccFiles = null;

                index++;
                S.Push(v);
                CsNode <string, string> w = null;

                for (int i = 0; i < v.children.Count; i++)
                {
                    w = v.children[i].targetNode;
                    if (w.Index < 0)
                    {
                        StrongConnect(w);
                        v.LowLink = Math.Min(v.LowLink, w.LowLink);
                    }
                    else if (S.Contains(w))
                    {
                        v.LowLink = Math.Min(v.LowLink, w.Index);
                    }
                }
                if (v.LowLink == v.Index)
                {
                    do
                    {
                        w        = S.Pop();
                        sccFiles = sccFiles + w.name + " , ";
                    } while (w != v);
                    sccNodes.Add(sccFiles);
                    sccFiles = null;
                }
            }

            foreach (var v in m)
            {
                if (v.Index < 0)
                {
                    StrongConnect(v);
                }
            }
            return(sccNodes);
        }
        static void Main(string[] args)
        {
            Console.WriteLine("----------< Test stub for Strongly connected component >---------");


            CsNode <string, string>         node1 = new CsNode <string, string>("node1");
            CsNode <string, string>         node2 = new CsNode <string, string>("node2");
            CsNode <string, string>         node3 = new CsNode <string, string>("node3");
            CsNode <string, string>         node4 = new CsNode <string, string>("node4");
            CsNode <string, string>         node5 = new CsNode <string, string>("node5");
            List <CsNode <string, string> > nodes = new List <CsNode <string, string> >();

            node1.addChild(node2, "edge12");
            node1.addChild(node3, "edge13");
            node2.addChild(node3, "edge23");
            node2.addChild(node4, "edge24");
            node3.addChild(node1, "edge31");
            node5.addChild(node1, "edge51");
            node5.addChild(node4, "edge54");
            List <string>            sccNodes = new List <string>();
            CsGraph <string, string> graph    = new CsGraph <string, string>("Fred");

            graph.addNode(node1);
            graph.addNode(node2);
            graph.addNode(node3);
            graph.addNode(node4);
            graph.addNode(node5);
            nodes.Add(node1);
            nodes.Add(node2);
            nodes.Add(node3);
            nodes.Add(node4);
            nodes.Add(node5);

            GraphTest T = new GraphTest();

            sccNodes = T.Tarjan(nodes);
            for (int i = 0; i < sccNodes.Count; i++)
            {
                Console.WriteLine(" scc" + (i + 1) + ": " + sccNodes[i]);
            }
            Console.Read();
        }
 override public bool doNodeOp(CsNode <string, string> node)
 {
     Console.Write("\n -- {0}", node.name);
     return(true);
 }
        //----< register an Operation with the graph >-------------------------

        //public Operation<V, E> setOperation(Operation<V, E> newOp)
        //{
        //    Operation<V, E> temp = gop;
        //    gop = newOp;
        //    return temp;
        //}
        //----< add vertex to graph adjacency list >---------------------------

        public void addNode(CsNode <V, E> node)
        {
            adjList.Add(node);
        }
        //----< graph.walk() calls this on every node >------------------------

        virtual public bool doNodeOp(CsNode <V, E> node)
        {
            Console.Write("\n  {0}", node.ToString());
            return(true);
        }
        //----< add child vertex and its associated edge value to vertex >-----

        public void addChild(CsNode <V, E> childNode, E edgeVal)
        {
            children.Add(new CsEdge <V, E>(childNode, edgeVal));
        }
 public CsEdge(CsNode <V, E> node, E value)
 {
     targetNode = node;
     edgeValue  = value;
 }