@Nullable
  public static PsiClass getContainingClass(@NotNull PsiElement psiElement) {
    for (ClassSearcher searcher : CLASS_SEARCHER_EP.getExtensionList()) {
      PsiClass aClass = searcher.findClass(psiElement);
      if (aClass != null) {
        return aClass;
      }
    }

    PsiClass containingClass = PsiTreeUtil.getParentOfType(psiElement, PsiClass.class, false);
    while (containingClass instanceof PsiTypeParameter) {
      containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class);
    }

    if (containingClass == null) {
      PsiFile containingFile = psiElement.getContainingFile();
      if (containingFile instanceof PsiClassOwner) {
        TextRange textRange = psiElement.getTextRange();
        PsiClass result = null;
        Queue<PsiClass> queue = new ArrayDeque<>(Arrays.asList(((PsiClassOwner)containingFile).getClasses()));
        while (!queue.isEmpty()) {
          PsiClass c = queue.remove();
          PsiElement navigationElement = c.getNavigationElement();
          TextRange classRange = navigationElement != null ? navigationElement.getTextRange() : null;
          if (classRange != null && classRange.contains(textRange)) {
            result = c;
            queue.clear();
            queue.addAll(Arrays.asList(c.getInnerClasses()));
          }
        }
        return result;
      }
      return null;
    }

    return containingClass;
  }
@Nullable
  public static PsiClass getContainingClass(@NotNull PsiElement psiElement)