static @NotNull UnhandledExceptions collect(@NotNull PsiElement element,
                                              @Nullable PsiElement topElement,
                                              @NotNull Predicate<? super PsiCall> callFilter) {
    Collection<PsiClassType> unhandledExceptions = null;
    boolean hasUnresolvedCalls = false;
    if (element instanceof PsiCallExpression) {
      PsiCallExpression expression = (PsiCallExpression)element;
      unhandledExceptions = ExceptionUtil.getUnhandledExceptions(expression, topElement, callFilter);
      if (!MethodCandidateInfo.isOverloadCheck() && 
          expression.resolveMethodGenerics() == JavaResolveResult.EMPTY && !isNonMethodNewExpression(expression)) {
        hasUnresolvedCalls = true;
      }
    }
    else if (element instanceof PsiTemplateExpression) {
      unhandledExceptions = ExceptionUtil.getUnhandledProcessorExceptions((PsiTemplateExpression)element, topElement);
    }
    else if (element instanceof PsiMethodReferenceExpression) {
      PsiExpression qualifierExpression = ((PsiMethodReferenceExpression)element).getQualifierExpression();
      return qualifierExpression != null ? collect(qualifierExpression, topElement, callFilter) : EMPTY;
    }
    else if (element instanceof PsiLambdaExpression) {
      return EMPTY;
    }
    else if (element instanceof PsiThrowStatement) {
      PsiThrowStatement statement = (PsiThrowStatement)element;
      unhandledExceptions = ExceptionUtil.getUnhandledExceptions(statement, topElement);
    }
    else if (element instanceof PsiCodeBlock &&
             element.getParent() instanceof PsiMethod &&
             ((PsiMethod)element.getParent()).isConstructor() &&
             JavaPsiConstructorUtil.findThisOrSuperCallInConstructor((PsiMethod)element.getParent()) == null) {
      // there is implicit parent constructor call
      final PsiMethod constructor = (PsiMethod)element.getParent();
      final PsiClass aClass = constructor.getContainingClass();
      final PsiClass superClass = aClass == null ? null : aClass.getSuperClass();
      final PsiMethod[] superConstructors = superClass == null ? PsiMethod.EMPTY_ARRAY : superClass.getConstructors();
      Set<PsiClassType> unhandled = new HashSet<>();
      for (PsiMethod superConstructor : superConstructors) {
        if (!superConstructor.hasModifierProperty(PsiModifier.PRIVATE) && superConstructor.getParameterList().isEmpty()) {
          final PsiClassType[] exceptionTypes = superConstructor.getThrowsList().getReferencedTypes();
          for (PsiClassType exceptionType : exceptionTypes) {
            if (!ExceptionUtil.isUncheckedException(exceptionType) &&
                ExceptionUtil.getHandlePlace(element, exceptionType, topElement) == ExceptionUtil.HandlePlace.UNHANDLED) {
              unhandled.add(exceptionType);
            }
          }
          break;
        }
      }

      // plus all exceptions thrown in instance class initializers
      if (aClass != null) {
        final PsiClassInitializer[] initializers = aClass.getInitializers();
        for (PsiClassInitializer initializer : initializers) {
          if (initializer.hasModifierProperty(PsiModifier.STATIC)) continue;
          UnhandledExceptions byInitializer = collect(initializer.getBody(), initializer, callFilter);
          for (PsiClassType thrown : byInitializer.exceptions()) {
            if (ExceptionUtil.getHandlePlace(constructor.getBody(), thrown, topElement) == ExceptionUtil.HandlePlace.UNHANDLED) {
              unhandled.add(thrown);
            }
          }
          hasUnresolvedCalls |= byInitializer.hasUnresolvedCalls();
        }
      }
      unhandledExceptions = unhandled;
    }
    else if (element instanceof PsiResourceListElement) {
      final List<PsiClassType> unhandled = ExceptionUtil.getUnhandledCloserExceptions((PsiResourceListElement)element, topElement);
      if (!unhandled.isEmpty()) {
        unhandledExceptions = new HashSet<>(unhandled);
      }
    }

    UnhandledExceptions exceptions = from(unhandledExceptions, hasUnresolvedCalls);

    for (PsiElement child = element.getFirstChild(); child != null; child = child.getNextSibling()) {
      UnhandledExceptions foundInChild = collect(child, topElement, callFilter);
      exceptions = exceptions.merge(foundInChild);
    }

    return exceptions;
  }
static @NotNull UnhandledExceptions collect(@NotNull PsiElement element,
                                              @Nullable PsiElement topElement,
                                              @NotNull Predicate<? super PsiCall> callFilter)