/// <summary>
 /// Adds all nodes and edges reachable from this node to the subgraph.
 /// Uses an explicit stack to avoid a large depth of recursion.
 /// </summary>
 /// <param name="startNode"></param>
 /// <param name="subgraph"></param>
 private void AddReachable(Node startNode, Subgraph subgraph)
 {
     Stack nodeStack = new Stack();
     nodeStack.Push(startNode);
     while (!(nodeStack.Count == 0))
     {
         Node node = (Node)nodeStack.Pop();
         AddEdges(node, nodeStack, subgraph);
     }
 }
 /// <summary>
 /// Adds the argument node and all its out edges to the subgraph.
 /// </summary>
 /// <param name="node"></param>
 /// <param name="nodeStack"></param>
 /// <param name="subgraph"></param>
 private void AddEdges(Node node, Stack nodeStack, Subgraph subgraph)
 {
     node.Visited = true;
     IEnumerator i = ((DirectedEdgeStar)node.OutEdges).GetEnumerator();
     while(i.MoveNext())
     {
         DirectedEdge de = (DirectedEdge)i.Current;
         subgraph.Add(de.Edge);
         Node toNode = de.ToNode;
         if (!toNode.IsVisited) 
             nodeStack.Push(toNode);
     }
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="graph"></param>
 /// <returns></returns>
 private static Node FindLowestDegreeNode(Subgraph graph)
 {
     int minDegree = Int32.MaxValue;
     Node minDegreeNode = null;            
     IEnumerator i = graph.GetNodeEnumerator();
     while (i.MoveNext())
     {
         Node node = (Node) i.Current;
         if (minDegreeNode == null || node.Degree < minDegree)
         {
             minDegree = node.Degree;
             minDegreeNode = node;
         }
     }            
     return minDegreeNode;
 }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="graph"></param>
        /// <returns></returns>
        private IList FindSequence(Subgraph graph)
        {            
            GraphComponent.SetVisited(graph.GetEdgeEnumerator(), false);

            Node startNode = FindLowestDegreeNode(graph);                        
            
            // HACK: we need to reverse manually the order: maybe sorting error?
            ArrayList list = (ArrayList) startNode.OutEdges.Edges;
            list.Reverse();

            IEnumerator ie = list.GetEnumerator();                        
            ie.MoveNext();

            DirectedEdge startDE = (DirectedEdge) ie.Current;            
            DirectedEdge startDESym = startDE.Sym;
            
            LinkedList<DirectedEdge> seq = new LinkedList<DirectedEdge>();
            LinkedListNode<DirectedEdge> pos = AddReverseSubpath(startDESym, null, seq, false);            
            while (pos != null)
            {
                DirectedEdge prev = pos.Value;
                DirectedEdge unvisitedOutDE = FindUnvisitedBestOrientedDE(prev.FromNode);
                if (unvisitedOutDE != null)
                {
                    DirectedEdge toInsert = unvisitedOutDE.Sym;
                    pos = AddReverseSubpath(toInsert, pos, seq, true);
                }
                else pos = pos.Previous;                
            }                       

            /*
             * At this point, we have a valid sequence of graph DirectedEdges, but it
             * is not necessarily appropriately oriented relative to the underlying geometry.
             */
            IList orientedSeq = Orient(new ArrayList(seq));
            return orientedSeq;
        }
 /// <summary>
 /// Tests whether a complete unique path exists in a graph
 /// using Euler's Theorem.
 /// </summary>
 /// <param name="graph">The <see cref="Subgraph" /> containing the edges.</param>
 /// <returns><c>true</c> if a sequence exists.</returns>
 private bool HasSequence(Subgraph graph)
 {
     int oddDegreeCount = 0;
     IEnumerator i = graph.GetNodeEnumerator();
     while(i.MoveNext())
     {
         Node node = (Node) i.Current;
         if (node.Degree % 2 == 1)
             oddDegreeCount++;
     }
     return oddDegreeCount <= 2;
 }
 private Subgraph FindSubgraph(Node node)
 {
     Subgraph subgraph = new Subgraph(graph);
     AddReachable(node, subgraph);
     return subgraph;
 }