private static boolean mentionsTypeParametersOrUnboundedWildcard(@Nullable PsiType type,
                                                                   final Predicate<? super PsiTypeParameter> wantedTypeParameter) {
    if (type == null) return false;
    return type.accept(new PsiTypeVisitor<Boolean>() {
      @Override
      public Boolean visitType(@NotNull PsiType type) {
        return false;
      }

      @Override
      public Boolean visitWildcardType(@NotNull PsiWildcardType wildcardType) {
        final PsiType bound = wildcardType.getBound();
        return bound != null ? bound.accept(this) 
                             : Boolean.valueOf(false);
      }

      @Override
      public Boolean visitClassType(@NotNull PsiClassType classType) {
        PsiClassType.ClassResolveResult result = classType.resolveGenerics();
        final PsiClass psiClass = result.getElement();
        if (psiClass != null) {
          PsiSubstitutor substitutor = result.getSubstitutor();
          for (PsiTypeParameter parameter : PsiUtil.typeParametersIterable(psiClass)) {
            PsiType type = substitutor.substitute(parameter);
            if (type != null && type.accept(this)) return true;
          }
        }
        return psiClass instanceof PsiTypeParameter && wantedTypeParameter.test((PsiTypeParameter)psiClass);
      }

      @Override
      public Boolean visitIntersectionType(@NotNull PsiIntersectionType intersectionType) {
        for (PsiType conjunct : intersectionType.getConjuncts()) {
          if (conjunct.accept(this)) return true;
        }
        return false;
      }

      @Override
      public Boolean visitMethodReferenceType(@NotNull PsiMethodReferenceType methodReferenceType) {
        return false;
      }

      @Override
      public Boolean visitLambdaExpressionType(@NotNull PsiLambdaExpressionType lambdaExpressionType) {
        return false;
      }

      @Override
      public Boolean visitArrayType(@NotNull PsiArrayType arrayType) {
        return arrayType.getComponentType().accept(this);
      }
    });
  }
private static boolean mentionsTypeParametersOrUnboundedWildcard(@Nullable PsiType type,
                                                                   final Predicate<? super PsiTypeParameter> wantedTypeParameter)