private void collectUncaughtExceptions(@NotNull PsiMethod method) {
    if (isExternalOverride()) return;
    if (getRefManager().isOfflineView()) return;
    @NonNls final String name = method.getName();
    if (getOwnerClass().isTestCase() && name.startsWith("test")) return;

    if (getSuperMethods().isEmpty()) {
      PsiClassType[] throwsList = method.getThrowsList().getReferencedTypes();
      if (throwsList.length > 0) {
        myUnThrownExceptions =
            throwsList.length == 1
                ? new SmartList<String>()
                : new ArrayList<String>(throwsList.length);
        for (final PsiClassType type : throwsList) {
          PsiClass aClass = type.resolve();
          String fqn = aClass == null ? null : aClass.getQualifiedName();
          if (fqn != null) {
            myUnThrownExceptions.add(fqn);
          }
        }
      }
    }

    final PsiCodeBlock body = method.getBody();
    if (body == null) return;

    final Collection<PsiClassType> exceptionTypes =
        ExceptionUtil.collectUnhandledExceptions(body, method, false);
    for (final PsiClassType exceptionType : exceptionTypes) {
      updateThrowsList(exceptionType);
    }
  }
  private static void fixExceptions(PsiElement ref, PsiClassType[] newExceptions)
      throws IncorrectOperationException {
    // methods' throws lists are already modified, may use ExceptionUtil.collectUnhandledExceptions
    newExceptions = filterCheckedExceptions(newExceptions);

    PsiElement context = PsiTreeUtil.getParentOfType(ref, PsiTryStatement.class, PsiMethod.class);
    if (context instanceof PsiTryStatement) {
      PsiTryStatement tryStatement = (PsiTryStatement) context;
      PsiCodeBlock tryBlock = tryStatement.getTryBlock();

      // Remove unused catches
      Collection<PsiClassType> classes =
          ExceptionUtil.collectUnhandledExceptions(tryBlock, tryBlock);
      PsiParameter[] catchParameters = tryStatement.getCatchBlockParameters();
      for (PsiParameter parameter : catchParameters) {
        final PsiType caughtType = parameter.getType();

        if (!(caughtType instanceof PsiClassType)) continue;
        if (ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType) caughtType)) continue;

        if (!isCatchParameterRedundant((PsiClassType) caughtType, classes)) continue;
        parameter.getParent().delete(); // delete catch section
      }

      PsiClassType[] exceptionsToAdd = filterUnhandledExceptions(newExceptions, tryBlock);
      addExceptions(exceptionsToAdd, tryStatement);

      adjustPossibleEmptyTryStatement(tryStatement);
    } else {
      newExceptions = filterUnhandledExceptions(newExceptions, ref);
      if (newExceptions.length > 0) {
        // Add new try statement
        PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(ref.getProject());
        PsiTryStatement tryStatement =
            (PsiTryStatement)
                elementFactory.createStatementFromText("try {} catch (Exception e) {}", null);
        PsiStatement anchor = PsiTreeUtil.getParentOfType(ref, PsiStatement.class);
        LOG.assertTrue(anchor != null);
        tryStatement.getTryBlock().add(anchor);
        tryStatement = (PsiTryStatement) anchor.getParent().addAfter(tryStatement, anchor);

        addExceptions(newExceptions, tryStatement);
        anchor.delete();
        tryStatement.getCatchSections()[0].delete(); // Delete dummy catch section
      }
    }
  }