public static <T> void breadthFirstTraverseTree(
    @NotNull T root,
    @NotNull Function<T, Collection<? extends T>> action
  ) {
    Deque<T> queue = new ArrayDeque<>();
    queue.addLast(root);
    while (!queue.isEmpty()) {
      T parent = queue.removeFirst();
      Collection<? extends T> children = action.apply(parent);
      for (T child : children) {
        queue.addLast(child);
      }
    }
  }
public static <T> void breadthFirstTraverseTree(
    @NotNull T root,
    @NotNull Function<T, Collection<? extends T>> action
  )