public class ... {

  /* Do not change anything below here! */

  /**
   * Checks whether the nth bit within an integer is set.
   * @param number The number to check
   * @param index The index of the bit to find
   * @return True if the nth bit is set. For example, (5, 1) is true
   *         since 5 = b101, and the ones place is set. Similarly, (5, 2)
   *         is false.
   */
  private static boolean nthBitSet(int number, int index) {
    int constant = 1 << (index - 1);
    return (number & constant) != 0;
  }

  /**
   * Prints an ascii representation of the tree.
   * @param root The current node to print
   * @param depth The level of the tree in which the current node lies.
   *              Levels are counted with the root starting at 0.
   * @param isLeft Whether the current node is a left child.
   * @param parBits A bitstring (integer) representing the parents
   *                in the path above this node. Used to 'fill in
   *                the gaps' in the drawing.
   * @param buffered Whether this was called to specifically include
   *                 additional whitespace on the left
   */
  public void printAscii(AvlNode<E> root, int depth, boolean isLeft, int parBits,
                         boolean buffered) {
    if (root == null) {
      return;
    }
    for (int i = 0; i < (depth - 1) * 3; i++) {
      if (i % 3 == 1 && nthBitSet(parBits, depth - (i / 3))) {
        System.out.print("|");
      } else {
        System.out.print(" ");
      }
    }
    if (isLeft && depth != 0 && !buffered) {
      System.out.print(" `- ");
    } else if (depth != 0 && !buffered) {
      System.out.print(" |- ");
    } else if (buffered) {
      for (int i = 0; i < depth * 3; i++) {
        System.out.print(" ");
      }
    }

    System.out.println(root.val);

    boolean hasLeft = root.left != null;
    int newParBits = parBits << 1;
    if (hasLeft) {
      newParBits++;
    }

    printAscii(root.right, depth + 1, !hasLeft, newParBits, false);
    printAscii(root.left, depth + 1, true, --newParBits, false);
  }

  /**
   * Prints an ascii representation of the tree.
   */
  public void printAscii(int depth) {
    printAscii(root, depth, false, 0, true);
  }

  public void printAscii() {
    printAscii(root, 0, false, 0, false);
  }
}
