public static @NotNull List<PsiClassType> getThrownExceptions(@NotNull PsiElement element) {
    List<PsiClassType> result = new ArrayList<>();
    class Visitor extends JavaRecursiveElementWalkingVisitor {
      @Override
      public void visitElement(@NotNull PsiElement psiElement) {
        if (psiElement != element) {
          PsiElement parent = psiElement.getParent();
          // do not process any anonymous class children except its getArgumentList()
          //if the visitor was not called from inside anonymous class
          if (parent instanceof PsiAnonymousClass && !(psiElement instanceof PsiExpressionList)) {
            return;
          }
        }
        super.visitElement(psiElement);
      }

      @Override
      public void visitAnonymousClass(@NotNull PsiAnonymousClass aClass) {
        // process anonymous getArgumentList()
        visitElement(aClass);
      }

      @Override
      public void visitClass(@NotNull PsiClass aClass) {
        // do not go inside class declaration
      }

      @Override
      public void visitTemplateExpression(@NotNull PsiTemplateExpression expression) {
        addExceptions(result, getUnhandledProcessorExceptions(expression, element));
        super.visitTemplateExpression(expression);
      }

      @Override
      public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
        PsiReferenceExpression methodRef = expression.getMethodExpression();
        JavaResolveResult resolveResult = methodRef.advancedResolve(false);
        PsiMethod method = (PsiMethod)resolveResult.getElement();
        if (method != null) {
          addExceptions(result, getExceptionsByMethod(method, resolveResult.getSubstitutor(), element));
        }
        super.visitMethodCallExpression(expression);
      }

      @Override
      public void visitNewExpression(@NotNull PsiNewExpression expression) {
        JavaResolveResult resolveResult = expression.resolveMethodGenerics();
        PsiMethod method = (PsiMethod)resolveResult.getElement();
        if (method != null) {
          addExceptions(result, getExceptionsByMethod(method, resolveResult.getSubstitutor(), element));
        }
        super.visitNewExpression(expression);
      }

      @Override
      public void visitThrowStatement(@NotNull PsiThrowStatement statement) {
        final PsiExpression expr = statement.getException();
        if (expr != null) {
          addExceptions(result, ContainerUtil.filterIsInstance(getPreciseThrowTypes(expr), PsiClassType.class));
        }
        super.visitThrowStatement(statement);
      }

      @Override
      public void visitLambdaExpression(@NotNull PsiLambdaExpression expression) {
        // do not go inside lambda
      }

      @Override
      public void visitResourceList(@NotNull PsiResourceList resourceList) {
        for (PsiResourceListElement listElement : resourceList) {
          addExceptions(result, getCloserExceptions(listElement));
        }
        super.visitResourceList(resourceList);
      }

      @Override
      public void visitTryStatement(@NotNull PsiTryStatement statement) {
        addExceptions(result, getTryExceptions(statement));
        // do not call super: try exception goes into try body recursively
      }
    }
    element.accept(new Visitor());
    return result;
  }
public static @NotNull List<PsiClassType> getThrownExceptions(@NotNull PsiElement element)