PsiSubstitutor (@NotNull PsiClass superClass, @NotNull PsiClass derivedClass, @NotNull GlobalSearchScope scope, @NotNull PsiSubstitutor derivedSubstitutor) { if (InheritanceImplUtil.hasObjectQualifiedName(superClass)) return PsiSubstitutor.EMPTY; List<PsiType> bounds = null; if (superClass instanceof InferenceVariable) { bounds = ((InferenceVariable)superClass).getBounds(InferenceBound.LOWER); } else if (superClass instanceof PsiTypeParameter) { final PsiType lowerBound = TypeConversionUtil.getInferredLowerBoundForSynthetic((PsiTypeParameter)superClass); if (lowerBound != null) { bounds = Collections.singletonList(lowerBound); } } if (bounds != null) { for (PsiType lowerBound : bounds) { if (lowerBound != null) { final PsiSubstitutor substitutor = processLowerBound(lowerBound, derivedClass, scope, derivedSubstitutor); if (substitutor != null) { return substitutor; } } } } return derivedClass instanceof PsiTypeParameter ? processTypeParameter((PsiTypeParameter)derivedClass, scope, superClass, new HashSet<>(), derivedSubstitutor) : getSuperSubstitutorWithCaching(superClass, derivedClass, scope, derivedSubstitutor); }