private static PsiElement fixCatchBlock(GrTryCatchStatement tryCatch, PsiClassType[] exceptions) {
    if (exceptions.length == 0) return tryCatch;
    final GroovyPsiElementFactory factory =
        GroovyPsiElementFactory.getInstance(tryCatch.getProject());

    final GrCatchClause[] clauses = tryCatch.getCatchClauses();
    List<String> restricted =
        ContainerUtil.map(
            clauses,
            new Function<GrCatchClause, String>() {
              @Override
              @Nullable
              public String fun(GrCatchClause grCatchClause) {
                final GrParameter grParameter = grCatchClause.getParameter();
                return grParameter != null ? grParameter.getName() : null;
              }
            });

    restricted = ContainerUtil.skipNulls(restricted);
    final DefaultGroovyVariableNameValidator nameValidator =
        new DefaultGroovyVariableNameValidator(tryCatch, restricted);

    GrCatchClause anchor = clauses.length == 0 ? null : clauses[clauses.length - 1];
    for (PsiClassType type : exceptions) {
      final String[] names =
          GroovyNameSuggestionUtil.suggestVariableNameByType(type, nameValidator);
      final GrCatchClause catchClause = factory.createCatchClause(type, names[0]);
      final GrStatement printStackTrace =
          factory.createStatementFromText(names[0] + ".printStackTrace()");
      catchClause.getBody().addStatementBefore(printStackTrace, null);
      anchor = tryCatch.addCatchClause(catchClause, anchor);
      JavaCodeStyleManager.getInstance(anchor.getProject()).shortenClassReferences(anchor);
    }
    return tryCatch;
  }
 @Override
 public void visitCatchClause(GrCatchClause catchClause) {
   final GrParameter parameter = catchClause.getParameter();
   builder.append("catch (");
   writeVariableWithoutSemicolonAndInitializer(builder, parameter, context);
   builder.append(") ");
   final GrOpenBlock body = catchClause.getBody();
   if (body != null) {
     body.accept(this);
   }
 }
 @Override
 public void visitTryStatement(GrTryCatchStatement tryCatchStatement) {
   final GrOpenBlock tryBlock = tryCatchStatement.getTryBlock();
   final GrCatchClause[] catchClauses = tryCatchStatement.getCatchClauses();
   final GrFinallyClause finallyClause = tryCatchStatement.getFinallyClause();
   builder.append("try");
   tryBlock.accept(this);
   for (GrCatchClause catchClause : catchClauses) {
     catchClause.accept(this);
   }
   if (finallyClause != null) {
     finallyClause.accept(this);
   }
 }
 @Nullable
 private ExceptionInfo findCatch(PsiType thrownType) {
   final Iterator<ExceptionInfo> iterator = myCaughtExceptionInfos.descendingIterator();
   while (iterator.hasNext()) {
     final ExceptionInfo info = iterator.next();
     final GrCatchClause clause = info.myClause;
     final GrParameter parameter = clause.getParameter();
     if (parameter != null) {
       final PsiType type = parameter.getType();
       if (type.isAssignableFrom(thrownType)) return info;
     }
   }
   return null;
 }
 private static boolean catchClausesAreEquivalent(GrCatchClause clause1, GrCatchClause clause2) {
   return parametersAreEquivalent(clause1.getParameter(), clause2.getParameter())
       && openBlocksAreEquivalent(clause1.getBody(), clause2.getBody());
 }