boolean (@Nullable PsiType type, @Nullable final Set<? super InferenceVariable> dependencies, final Function<? super PsiClassType, ? extends InferenceVariable> fun) { if (type == null) return true; final Boolean isProper = type.accept(new PsiTypeVisitor<Boolean>() { @Override public Boolean visitType(@NotNull PsiType type) { return true; } @Override public Boolean visitCapturedWildcardType(@NotNull PsiCapturedWildcardType capturedWildcardType) { return true; } @Override public Boolean visitArrayType(@NotNull PsiArrayType arrayType) { return arrayType.getComponentType().accept(this); } @Override public Boolean visitWildcardType(@NotNull PsiWildcardType wildcardType) { final PsiType bound = wildcardType.getBound(); if (bound == null) return true; return bound.accept(this); } @Override public Boolean visitClassType(@NotNull PsiClassType classType) { final InferenceVariable inferenceVariable = fun.fun(classType); if (inferenceVariable != null) { if (dependencies != null) { dependencies.add(inferenceVariable); return true; } return false; } PsiClassType.ClassResolveResult result = classType.resolveGenerics(); PsiClass aClass = result.getElement(); if (aClass != null) { PsiSubstitutor substitutor = result.getSubstitutor(); for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(aClass)) { PsiType psiType = substitutor.substitute(typeParameter); if (psiType != null && !psiType.accept(this)) return false; } } return true; } }); return dependencies != null ? !dependencies.isEmpty() : isProper; }