PsiSubstitutor (PsiTypeParameter parameter, GlobalSearchScope scope, PsiClass superClass, Set<? super PsiTypeParameter> visited, PsiSubstitutor derivedSubstitutor) { if (parameter.getManager().areElementsEquivalent(parameter, superClass)) return PsiSubstitutor.EMPTY; if (!visited.add(parameter)) return null; for (PsiClassType type : parameter.getExtendsListTypes()) { PsiClassType.ClassResolveResult result = type.resolveGenerics(); PsiClass psiClass = result.getElement(); if (psiClass == null) continue; PsiSubstitutor answer; if (psiClass instanceof PsiTypeParameter) { answer = processTypeParameter((PsiTypeParameter)psiClass, scope, superClass, visited, derivedSubstitutor); if (answer != null) { return answer; } } else { answer = getSuperSubstitutorWithCaching(superClass, psiClass, scope, result.getSubstitutor()); if (answer != null) { return composeSubstitutors(derivedSubstitutor, answer, superClass); } } } return null; }