PsiSubstitutor (@NotNull PsiType lowerBound, @NotNull PsiClass derivedClass, @NotNull GlobalSearchScope scope, @NotNull PsiSubstitutor derivedSubstitutor) { if (lowerBound instanceof PsiClassType) { final PsiClassType.ClassResolveResult result = ((PsiClassType)lowerBound).resolveGenerics(); final PsiClass boundClass = result.getElement(); if (boundClass != null) { if (boundClass.equals(derivedClass)) { return derivedSubstitutor; } final PsiSubstitutor substitutor = getSuperSubstitutorWithCaching(boundClass, derivedClass, scope, result.getSubstitutor()); if (substitutor != null) { return composeSubstitutors(derivedSubstitutor, substitutor, boundClass); } } } else if (lowerBound instanceof PsiIntersectionType) { for (PsiType bound : ((PsiIntersectionType)lowerBound).getConjuncts()) { final PsiSubstitutor substitutor = processLowerBound(bound, derivedClass, scope, derivedSubstitutor); if (substitutor != null) { return substitutor; } } } else if (lowerBound instanceof PsiCapturedWildcardType) { return processLowerBound(((PsiCapturedWildcardType)lowerBound).getUpperBound(), derivedClass, scope, derivedSubstitutor); } return null; }