PsiMethod (PsiMethod method, PsiType returnType, PsiElement element) { if (method.isConstructor()) { return null; } if (method.hasModifierProperty(PsiModifier.STATIC)) { return null; } if (method.hasModifierProperty(PsiModifier.PRIVATE)) { return null; } final PsiClass aClass = method.getContainingClass(); if (aClass == null) { return null; } final PsiReferenceList throwsList = method.getThrowsList(); final HashSet<PsiClassType> thrownTypes = ContainerUtil.newHashSet(throwsList.getReferencedTypes()); final PsiMethod[] superMethods = aClass.findMethodsBySignature(method, true); PsiMethod topSuper = null; PsiClass topSuperContainingClass = null; methodLoop: for (PsiMethod superMethod : superMethods) { final PsiClass superClass = superMethod.getContainingClass(); if (superClass == null) { continue; } if (aClass.equals(superClass)) { continue; } if (!isAccessibleFrom(superMethod, element)) { continue; } if (returnType != null) { final PsiType superReturnType = superMethod.getReturnType(); if (superReturnType == null) { continue; } if (!returnType.isAssignableFrom(superReturnType)) { continue; } } if (topSuper != null && superClass.isInheritor(topSuperContainingClass, true)) { continue; } final PsiReferenceList superThrowsList = superMethod.getThrowsList(); final PsiClassType[] superThrownTypes = superThrowsList.getReferencedTypes(); for (PsiClassType superThrownType : superThrownTypes) { if (!ExceptionUtil.isUncheckedException(superThrownType) && !thrownTypes.contains(superThrownType)) { continue methodLoop; } } topSuper = superMethod; topSuperContainingClass = superClass; } return topSuper; }