private static void psiToBuffer(Appendable buffer,
                                  PsiElement root,
                                  int indent,
                                  boolean showWhitespaces,
                                  boolean showRanges,
                                  boolean showChildrenRanges,
                                  boolean showClassNames,
                                  @Nullable PairConsumer<? super PsiElement, ? super Consumer<? super PsiElement>> extra) {
    if (!showWhitespaces && root instanceof PsiWhiteSpace) return;

    StringUtil.repeatSymbol(buffer, ' ', indent);
    try {
      buffer.append(root.toString());
      PsiElement child = root.getFirstChild();
      if (child == null) {
        String text = root.getText();
        assert text != null : "text is null for <" + root + ">";
        buffer.append("('").append(fixWhiteSpaces(text)).append("')");
      }

      if (showRanges) buffer.append(root.getTextRange().toString());
      if (showClassNames) buffer.append("[").append(getPsiClassName(root)).append("]");
      buffer.append("\n");
      while (child != null) {
        psiToBuffer(buffer, child, indent + 2, showWhitespaces, showChildrenRanges, showChildrenRanges, showClassNames, extra);
        child = child.getNextSibling();
      }
      if (extra != null) {
        Consumer<PsiElement> consumer =
          element -> psiToBuffer(buffer, element, indent + 2, !showWhitespaces, showChildrenRanges, showChildrenRanges, showClassNames,
                                 null);
        extra.consume(root, consumer);
      }
    }
    catch (IOException e) {
      LOG.error(e);
    }
  }
private static void psiToBuffer(Appendable buffer,
                                  PsiElement root,
                                  int indent,
                                  boolean showWhitespaces,
                                  boolean showRanges,
                                  boolean showChildrenRanges,
                                  boolean showClassNames,
                                  @Nullable PairConsumer<? super PsiElement, ? super Consumer<? super PsiElement>> extra)