@Override
  @NotNull
  public Collection<Group> group(@NotNull AbstractTreeNode<?> parent, @NotNull Collection<TreeElement> children) {
    if (isParentGrouped(parent)) return Collections.emptyList();
    Map<Group, SuperTypeGroup> groups = new HashMap<>();

    for (TreeElement child : children) {
      if (child instanceof PsiMethodTreeElement element) {
        PsiMethod method = element.getMethod();
        if (element.isInherited()) {
          PsiClass groupClass = method.getContainingClass();
          final SuperTypeGroup group = getOrCreateGroup(groupClass, SuperTypeGroup.OwnershipType.INHERITS, groups);
          group.addMethod(child);
        }
        else {
          PsiMethod[] superMethods = method.findSuperMethods();

          if (superMethods.length > 0) {
            //prefer interface, if there are any
            for (int i = 1; i < superMethods.length; i++) {
              PsiMethod superMethod = superMethods[i];
              PsiClass containingClass = superMethod.getContainingClass();
              if (containingClass != null && containingClass.isInterface()) {
                ArrayUtil.swap(superMethods, 0, i);
                break;
              }
            }

            PsiMethod superMethod = superMethods[0];
            method.putUserData(SUPER_METHOD_KEY, new WeakReference<>(superMethod));
            PsiClass groupClass = superMethod.getContainingClass();
            boolean overrides = methodOverridesSuper(method, superMethod);
            final SuperTypeGroup.OwnershipType ownershipType =
              overrides ? SuperTypeGroup.OwnershipType.OVERRIDES : SuperTypeGroup.OwnershipType.IMPLEMENTS;
            SuperTypeGroup group = getOrCreateGroup(groupClass, ownershipType, groups);
            group.addMethod(child);
          }
        }
      }
    }
    return groups.keySet();
  }
@Override
  @NotNull
  public Collection<Group> group(@NotNull AbstractTreeNode<?> parent, @NotNull Collection<TreeElement> children)