public class Pair { public Pair() { } public Pair(T first, U second) { this.First = first; this.Second = second; } public T First { get; set; } public U Second { get; set; } }; sealed class Dumper { static public string Dump(Node root) { StringBuilder fulltree = new StringBuilder(); if (root == null) return string.Empty; fulltree.Append(root.Text + "\n"); Stack>> browser = new Stack>>(); browser.Push(new Pair>(0, root.Children)); // customize tree const string branch = "├", lastbranch = "└", vertical = "│", space = " ", horizontal = "─"; List currPath = new List(); // for each list of children while (browser.Count != 0) { Pair> current = browser.Peek(); if (current.First >= current.Second.Count) { // stop! browser.Pop(); if (currPath.Count > 0) currPath.RemoveAt(currPath.Count - 1); } else { if ((current.First + 1) == current.Second.Count) { Node n = current.Second[current.First]; string path = string.Join(space, currPath.ToArray()); if (!string.IsNullOrEmpty(path)) path += space; fulltree.Append(path + lastbranch + horizontal + n.Text + "\n"); if (n.Children.Count > 0) { currPath.Add(space); browser.Push(new Pair>(0, n.Children)); } } else { Node n = current.Second[current.First]; string path = string.Join(space, currPath.ToArray()); if (!string.IsNullOrEmpty(path)) path += space; fulltree.Append(path + branch + horizontal + n.Text + "\n"); if (n.Children.Count > 0) { browser.Push(new Pair>(0, n.Children)); currPath.Add(vertical); } } current.First++; } } return fulltree.ToString(); } }