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
      }
    }
  }
  @Nullable
  private static PsiExpression createDefaultValue(
      JavaChangeInfo changeInfo,
      final PsiElementFactory factory,
      final JavaParameterInfo info,
      final PsiExpressionList list)
      throws IncorrectOperationException {
    if (info.isUseAnySingleVariable()) {
      final PsiResolveHelper resolveHelper =
          JavaPsiFacade.getInstance(list.getProject()).getResolveHelper();
      final PsiType type = info.getTypeWrapper().getType(changeInfo.getMethod(), list.getManager());
      final VariablesProcessor processor =
          new VariablesProcessor(false) {
            protected boolean check(PsiVariable var, ResolveState state) {
              if (var instanceof PsiField
                  && !resolveHelper.isAccessible((PsiField) var, list, null)) return false;
              if (var instanceof PsiLocalVariable
                  && list.getTextRange().getStartOffset() <= var.getTextRange().getStartOffset())
                return false;
              if (PsiTreeUtil.isAncestor(var, list, false)) return false;
              final PsiType varType = state.get(PsiSubstitutor.KEY).substitute(var.getType());
              return type.isAssignableFrom(varType);
            }

            public boolean execute(PsiElement pe, ResolveState state) {
              super.execute(pe, state);
              return size() < 2;
            }
          };
      PsiScopesUtil.treeWalkUp(processor, list, null);
      if (processor.size() == 1) {
        final PsiVariable result = processor.getResult(0);
        return factory.createExpressionFromText(result.getName(), list);
      }
      if (processor.size() == 0) {
        final PsiClass parentClass = PsiTreeUtil.getParentOfType(list, PsiClass.class);
        if (parentClass != null) {
          PsiClass containingClass = parentClass;
          final Set<PsiClass> containingClasses = new HashSet<PsiClass>();
          while (containingClass != null) {
            if (type.isAssignableFrom(factory.createType(containingClass, PsiSubstitutor.EMPTY))) {
              containingClasses.add(containingClass);
            }
            containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class);
          }
          if (containingClasses.size() == 1) {
            return RefactoringUtil.createThisExpression(
                parentClass.getManager(),
                containingClasses.contains(parentClass)
                    ? null
                    : containingClasses.iterator().next());
          }
        }
      }
    }
    final PsiCallExpression callExpression =
        PsiTreeUtil.getParentOfType(list, PsiCallExpression.class);
    final String defaultValue = info.getDefaultValue();
    return callExpression != null
        ? info.getValue(callExpression)
        : defaultValue.length() > 0 ? factory.createExpressionFromText(defaultValue, list) : null;
  }