@NotNull
  private static InitialInfo buildInfo(@NotNull Project project,
                                       @NotNull PsiFile file,
                                       int start,
                                       int end,
                                       boolean forceStatements,
                                       @NotNull SelectionModel selectionModel,
                                       @Nullable GrVariable variable) throws GrRefactoringError {
    PsiElement[] elements = getElementsInOffset(file, start, end, forceStatements);
    //if (elements.length == 1 && elements[0] instanceof GrExpression) {
    //  selectionModel.setSelection(start, elements[0].getTextRange().getEndOffset());
    //}

    GrStatement[] statements = getStatementsByElements(elements);

    if (statements.length == 0) {
      throw new GrRefactoringError(GroovyRefactoringBundle.message("selected.block.should.represent.a.statement.set"));
    }

    for (GrStatement statement : statements) {
      if (GroovyRefactoringUtil.isSuperOrThisCall(statement, true, true)) {
        throw new GrRefactoringError(GroovyRefactoringBundle.message("selected.block.contains.invocation.of.another.class.constructor"));
      }
    }

    GrStatement statement0 = statements[0];
    PsiClass owner = PsiUtil.getContextClass(statement0);
    GrStatementOwner declarationOwner = GroovyRefactoringUtil.getDeclarationOwner(statement0);
    if (owner == null || declarationOwner == null && !ExtractUtil.isSingleExpression(statements)) {
      throw new GrRefactoringError(GroovyRefactoringBundle.message("refactoring.is.not.supported.in.the.current.context"));
    }
    if (declarationOwner == null &&
        ExtractUtil.isSingleExpression(statements) &&
        statement0 instanceof GrExpression &&
        PsiTypes.voidType().equals(((GrExpression)statement0).getType())) {
      throw new GrRefactoringError(GroovyRefactoringBundle.message("selected.expression.has.void.type"));
    }

    if (ExtractUtil.isSingleExpression(statements) && GrIntroduceHandlerBase.expressionIsIncorrect((GrExpression)statement0, true)) {
      throw new GrRefactoringError(GroovyRefactoringBundle.message("selected.block.should.represent.an.expression"));
    }

    if (ExtractUtil.isSingleExpression(statements) &&
        statement0.getParent() instanceof GrAssignmentExpression &&
        ((GrAssignmentExpression)statement0.getParent()).getLValue() == statement0) {
      throw new GrRefactoringError(GroovyRefactoringBundle.message("selected.expression.should.not.be.lvalue"));
    }

    // collect information about return statements in selected statement set

    Set<GrStatement> allReturnStatements = new HashSet<>();
    GrControlFlowOwner controlFlowOwner = ControlFlowUtils.findControlFlowOwner(statement0);
    LOG.assertTrue(controlFlowOwner != null);
    final GroovyControlFlow flow = ControlFlowBuilder.buildControlFlow(controlFlowOwner, GrAllVarsInitializedPolicy.getInstance());
    allReturnStatements.addAll(ControlFlowUtils.collectReturns(flow.getFlow(), controlFlowOwner, true));

    ArrayList<GrStatement> returnStatements = new ArrayList<>();
    for (GrStatement returnStatement : allReturnStatements) {
      for (GrStatement statement : statements) {
        if (PsiTreeUtil.isAncestor(statement, returnStatement, false)) {
          returnStatements.add(returnStatement);
          break;
        }
      }
    }

    // collect information about variables in selected block
    FragmentVariableInfos fragmentVariableInfos =
      ReachingDefinitionsCollector.obtainVariableFlowInformation(statement0, statements[statements.length - 1], controlFlowOwner, flow);
    VariableInfo[] inputInfos = fragmentVariableInfos.getInputVariableNames();
    VariableInfo[] outputInfos = fragmentVariableInfos.getOutputVariableNames();
    if (outputInfos.length == 1 && !returnStatements.isEmpty()) {
      throw new GrRefactoringError(GroovyRefactoringBundle.message("multiple.output.values"));
    }

    boolean hasInterruptingStatements = false;

    for (GrStatement statement : statements) {
      hasInterruptingStatements = GroovyRefactoringUtil.hasWrongBreakStatements(statement) || GroovyRefactoringUtil
        .hasWrongContinueStatements(statement);
      if (hasInterruptingStatements) break;
    }

    // must be replaced by return statement
    boolean hasReturns = !returnStatements.isEmpty();
    List<GrStatement> returnStatementsCopy = new ArrayList<>(returnStatements.size());
    returnStatementsCopy.addAll(returnStatements);
    boolean isReturnStatement = isReturnStatement(statements[statements.length - 1], returnStatementsCopy);
    boolean isLastStatementOfMethod = isLastStatementOfMethodOrClosure(statements);
    if (hasReturns && !isLastStatementOfMethod && !isReturnStatement || hasInterruptingStatements) {
      throw new GrRefactoringError(
        GroovyRefactoringBundle.message("refactoring.is.not.supported.when.return.statement.interrupts.the.execution.flow"));
    }

    return new InitialInfo(inputInfos, outputInfos, elements, statements, returnStatements, null, project, variable);
  }
@NotNull
  private static InitialInfo buildInfo(@NotNull Project project,
                                       @NotNull PsiFile file,
                                       int start,
                                       int end,
                                       boolean forceStatements,
                                       @NotNull SelectionModel selectionModel,
                                       @Nullable GrVariable variable)