//----< 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);
        }
        static void Main(string[] args)
        {
            Console.Write("\n  Testing CsGraph class");
            Console.Write("\n =======================");

            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");

            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");

            CsGraph <string, string> graph = new CsGraph <string, string>("Fred");

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



            graph.startNode = node1;
            Console.Write("\n\n  starting walk at {0}", graph.startNode.name);
            Console.Write("\n  not showing backtracks");
            graph.walk();

            graph.startNode = node2;
            Console.Write("\n\n  starting walk at {0}", graph.startNode.name);
            graph.showBackTrack = true;
            Console.Write("\n  show backtracks");
            graph.setOperation(new demoOperation());
            graph.walk();

            graph.startNode = node3;
            Console.Write("\n\n  starting walk at {0}", graph.startNode.name);
            graph.showBackTrack = true;
            Console.Write("\n  show backtracks");
            graph.setOperation(new demoOperation());
            graph.walk();



            Console.Write("\n\n");
        }
        //----< 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;
 }
 override public bool doNodeOp(CsNode <string, string> node)
 {
     Console.Write("\n -- {0}", node.name);
     return(true);
 }
        //----< 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);
        }