protected Match tryStatementsMatch(@NotNull PsiTryStatement statement1, @NotNull PsiTryStatement statement2) {
    final PsiCodeBlock tryBlock1 = statement1.getTryBlock();
    final PsiCodeBlock tryBlock2 = statement2.getTryBlock();
    if (!codeBlocksMatch(tryBlock1, tryBlock2).isExactMatch()) {
      return EXACT_MISMATCH;
    }
    final PsiCodeBlock finallyBlock1 = statement1.getFinallyBlock();
    final PsiCodeBlock finallyBlock2 = statement2.getFinallyBlock();
    if (!codeBlocksMatch(finallyBlock1, finallyBlock2).isExactMatch()) {
      return EXACT_MISMATCH;
    }
    final PsiCatchSection @NotNull [] catchSections1 = statement1.getCatchSections();
    final PsiCatchSection @NotNull [] catchSections2 = statement2.getCatchSections();
    if (catchSections1.length != catchSections2.length) {
      return EXACT_MISMATCH;
    }
    for (int i = 0; i < catchSections2.length; i++) {
      PsiCatchSection section1 = catchSections1[i];
      PsiCatchSection section2 = catchSections2[i];
      PsiParameter parameter1 = section1.getParameter();
      PsiParameter parameter2 = section2.getParameter();
      if (parameter1 == null || parameter2 == null) {
        return Match.exact(parameter1 == parameter2);
      }
      if (!variableSignatureMatch(parameter1, parameter2)) {
        return EXACT_MISMATCH;
      }
      if (!codeBlocksMatch(section1.getCatchBlock(), section2.getCatchBlock()).isExactMatch()) {
        return EXACT_MISMATCH;
      }
    }
    final PsiResourceList resourceList1 = statement1.getResourceList();
    final PsiResourceList resourceList2 = statement2.getResourceList();
    if (resourceList1 == null || resourceList2 == null) {
      return Match.exact(resourceList1 == resourceList2);
    }
    if (resourceList1.getResourceVariablesCount() != resourceList2.getResourceVariablesCount()) {
      return EXACT_MISMATCH;
    }
    final List<PsiResourceListElement> resources1 = PsiTreeUtil.getChildrenOfTypeAsList(resourceList1, PsiResourceListElement.class);
    final List<PsiResourceListElement> resources2 = PsiTreeUtil.getChildrenOfTypeAsList(resourceList2, PsiResourceListElement.class);
    for (int i = 0, size = resources1.size(); i < size; i++) {
      final PsiResourceListElement resource1 = resources1.get(i);
      final PsiResourceListElement resource2 = resources2.get(i);
      if (resource1 instanceof PsiResourceVariable && resource2 instanceof PsiResourceVariable) {
        if (!variablesAreEquivalent((PsiLocalVariable)resource1, (PsiLocalVariable)resource2).isExactMatch()) {
          return EXACT_MISMATCH;
        }
      }
      else if (resource1 instanceof PsiResourceExpression && resource2 instanceof PsiResourceExpression) {
        if (!expressionsMatch(((PsiResourceExpression)resource1).getExpression(),
                              ((PsiResourceExpression)resource2).getExpression()).isExactMatch()) {
          return EXACT_MISMATCH;
        }
      }
      else {
        return EXACT_MISMATCH;
      }
    }
    final PsiParameter[] catchParameters1 = statement1.getCatchBlockParameters();
    final PsiParameter[] catchParameters2 = statement2.getCatchBlockParameters();
    if (catchParameters1.length != catchParameters2.length) {
      return EXACT_MISMATCH;
    }
    for (int i = 0; i < catchParameters2.length; i++) {
      if (!variablesAreEquivalent(catchParameters2[i], catchParameters1[i]).isExactMatch()) {
        return EXACT_MISMATCH;
      }
    }
    return EXACT_MATCH;
  }
protected Match tryStatementsMatch(@NotNull PsiTryStatement statement1, @NotNull PsiTryStatement statement2)