// Path: src/main/java/com/pengyifan/commons/lang/StringUtils.java
// public final class StringUtils {
// 
//   // │
//   public static final String BAR    = bar(1);
//   // └
//   public static final String END    = bar(2);
//   // ├
//   public static final String MIDDLE = bar(3);
// 
//   private StringUtils() throws InstantiationException {
//     throw new InstantiationException("This class is not for instantiation");
//   }
// 
//   private static String bar(int i) {
//     try {
//       switch (i) {
//       case 1:
//         return new String(new byte[] { -30, -108, -126 }, "utf8");
//       case 2:
//         return new String(new byte[] { -30, -108, -108 }, "utf8");
//       case 3:
//         return new String(new byte[] { -30, -108, -100 }, "utf8");
//       }
//     } catch (UnsupportedEncodingException e) {
//       e.printStackTrace();
//     }
//     return null;
//   }
// 
// }


import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.pengyifan.commons.lang.StringUtils;
import edu.stanford.nlp.util.ErasureUtils;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.Stack;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkElementIndex;
import static com.google.common.base.Preconditions.checkNotNull;
   * <pre>
   * └ a
   *   ├ b
   *   ├ c
   *   │ ├ e
   *   │ └ f
   *   └ d
   * </pre>
   */
  public static class PrettyPrint<E, T extends Tree<E, T>> implements Function<T, String> {

    @Override
    public String apply(T tree) {
      StringBuilder sb = new StringBuilder();
      Iterator<T> itr = tree.preorderIterator();
      while (itr.hasNext()) {
        T tn = itr.next();
        // add prefix
        for (T p : tn.getPathFromRoot()) {
          // if parent has sibling node
          if (p == tn) {
            ;
          } else if (p.hasNextSiblingNode()) {
            sb.append(StringUtils.BAR).append(' ');
          } else {
            sb.append("  ");
          }
        }
        // if root has sibling node
        if (tn.hasNextSiblingNode()) {
// Path: src/main/java/com/pengyifan/commons/lang/StringUtils.java
// public final class StringUtils {
// 
//   // │
//   public static final String BAR    = bar(1);
//   // └
//   public static final String END    = bar(2);
//   // ├
//   public static final String MIDDLE = bar(3);
// 
//   private StringUtils() throws InstantiationException {
//     throw new InstantiationException("This class is not for instantiation");
//   }
// 
//   private static String bar(int i) {
//     try {
//       switch (i) {
//       case 1:
//         return new String(new byte[] { -30, -108, -126 }, "utf8");
//       case 2:
//         return new String(new byte[] { -30, -108, -108 }, "utf8");
//       case 3:
//         return new String(new byte[] { -30, -108, -100 }, "utf8");
//       }
//     } catch (UnsupportedEncodingException e) {
//       e.printStackTrace();
//     }
//     return null;
//   }
// 
// }


// Path: src/main/java/com/pengyifan/commons/collections/tree/Tree.java
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.pengyifan.commons.lang.StringUtils;
import edu.stanford.nlp.util.ErasureUtils;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.Stack;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkElementIndex;
import static com.google.common.base.Preconditions.checkNotNull;

   * <pre>
   * └ a
   *   ├ b
   *   ├ c
   *   │ ├ e
   *   │ └ f
   *   └ d
   * </pre>
   */
  public static class PrettyPrint<E, T extends Tree<E, T>> implements Function<T, String> {

    @Override
    public String apply(T tree) {
      StringBuilder sb = new StringBuilder();
      Iterator<T> itr = tree.preorderIterator();
      while (itr.hasNext()) {
        T tn = itr.next();
        // add prefix
        for (T p : tn.getPathFromRoot()) {
          // if parent has sibling node
          if (p == tn) {
            ;
          } else if (p.hasNextSiblingNode()) {
            sb.append(StringUtils.BAR).append(' ');
          } else {
            sb.append("  ");
          }
        }
        // if root has sibling node
        if (tn.hasNextSiblingNode()) {
          sb.append(StringUtils.MIDDLE);