@NotNull
  public static Iterable<PsiTypeParameter> typeParametersIterable(@NotNull PsiTypeParameterListOwner owner) {
    Iterable<PsiTypeParameter> result = null;

    PsiTypeParameterListOwner currentOwner = owner;
    while (currentOwner != null) {
      PsiTypeParameter[] typeParameters = currentOwner.getTypeParameters();
      if (typeParameters.length > 0) {
        Iterable<PsiTypeParameter> iterable = () -> new Iterator<PsiTypeParameter>() {
          int idx = typeParameters.length - 1;

          @Override
          public boolean hasNext() {
            return idx >= 0;
          }

          @Override
          public PsiTypeParameter next() {
            if (idx < 0) throw new NoSuchElementException();
            return typeParameters[idx--];
          }
        };
        if (result == null) {
          result = iterable;
        } else {
          result = ContainerUtil.concat(result, iterable);
        }
      }

      if (currentOwner.hasModifierProperty(PsiModifier.STATIC)) break;
      if (currentOwner instanceof PsiClass && isLocalClass((PsiClass)currentOwner)) {
        currentOwner = PsiTreeUtil.getParentOfType(currentOwner, PsiTypeParameterListOwner.class);
        continue;
      }
      currentOwner = currentOwner.getContainingClass();
    }

    if (result == null) return Collections.emptyList();
    return result;
  }
@NotNull
  public static Iterable<PsiTypeParameter> typeParametersIterable(@NotNull PsiTypeParameterListOwner owner)