@Nullable
  static RangeMarker inlineReferenceImpl(@NotNull GrCallExpression call,
                                         @NotNull GrMethod method,
                                         boolean resultOfCallExplicitlyUsed,
                                         boolean isTailMethodCall,
                                         @Nullable Editor editor) {
    try {
      GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(call.getProject());
      final Project project = call.getProject();

      // Variable declaration for qualifier expression
      GrVariableDeclaration qualifierDeclaration = null;
      GrReferenceExpression innerQualifier = null;
      GrExpression qualifier = null;
      if (call instanceof GrMethodCallExpression methodCall) {
        GrExpression invoked = methodCall.getInvokedExpression();
        if (invoked instanceof GrReferenceExpression ref && ref.getQualifierExpression() != null) {
          qualifier = ref.getQualifierExpression();
          if (PsiUtil.isSuperReference(qualifier)) {
            qualifier = null;
          }
          else if (!GroovyInlineMethodUtil.isSimpleReference(qualifier)) {
            String qualName = generateQualifierName(call, method, project, qualifier);
            qualifier = (GrExpression)PsiUtil.skipParentheses(qualifier, false);
            qualifierDeclaration = factory.createVariableDeclaration(ArrayUtilRt.EMPTY_STRING_ARRAY, qualifier, null, qualName);
            innerQualifier = (GrReferenceExpression)factory.createExpressionFromText(qualName);
          }
          else {
            innerQualifier = (GrReferenceExpression)qualifier;
          }
        }
      }


      GrMethod _method = prepareNewMethod(call, method, qualifier);
      GrExpression result = getAloneResultExpression(_method);
      if (result != null) {
        GrExpression expression = call.replaceWithExpression(result, false);
        TextRange range = expression.getTextRange();
        return editor != null ? editor.getDocument().createRangeMarker(range.getStartOffset(), range.getEndOffset(), true) : null;
      }

      GrMethod newMethod = prepareNewMethod(call, method, innerQualifier);
      String resultName = InlineMethodConflictSolver.suggestNewName("result", newMethod, call);

      // Add variable for method result
      Collection<GrStatement> returnStatements = ControlFlowUtils.collectReturns(newMethod.getBlock());
      final int returnCount = returnStatements.size();
      PsiType methodType = method.getInferredReturnType();
      GrOpenBlock body = newMethod.getBlock();
      assert body != null;


      GrExpression replaced;
      if (resultOfCallExplicitlyUsed && !isTailMethodCall) {
        GrExpression resultExpr = null;
        if (PsiTypes.voidType().equals(methodType)) {
          resultExpr = factory.createExpressionFromText("null");
        }
        else if (returnCount == 1) {
          final GrExpression returnExpression = ControlFlowUtils.extractReturnExpression(returnStatements.iterator().next());
          if (returnExpression != null) {
            resultExpr = factory.createExpressionFromText(returnExpression.getText());
          }
        }
        else if (returnCount > 1) {
          resultExpr = factory.createExpressionFromText(resultName);
        }

        if (resultExpr == null) {
          resultExpr = factory.createExpressionFromText("null");
        }
        replaced = call.replaceWithExpression(resultExpr, false);
      }
      else {
        replaced = call;
      }

      // Calculate anchor to insert before
      GrExpression enclosingExpr = GroovyRefactoringUtil.addBlockIntoParent(replaced);
      GrVariableDeclarationOwner owner = PsiTreeUtil.getParentOfType(enclosingExpr, GrVariableDeclarationOwner.class);
      assert owner != null;
      PsiElement element = enclosingExpr;
      while (element != null && element.getParent() != owner) {
        element = element.getParent();
      }
      assert element instanceof GrStatement;
      GrStatement anchor = (GrStatement) element;

      if (!resultOfCallExplicitlyUsed) {
        assert anchor == enclosingExpr;
      }

      // add qualifier reference declaration
      if (qualifierDeclaration != null) {
        owner.addVariableDeclarationBefore(qualifierDeclaration, anchor);
      }

      // Process method return statements
      if (returnCount > 1 && !PsiTypes.voidType().equals(methodType) && !isTailMethodCall) {
        PsiType type = methodType != null && methodType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) ? null : methodType;
        GrVariableDeclaration resultDecl = factory.createVariableDeclaration(ArrayUtilRt.EMPTY_STRING_ARRAY, "", type, resultName);
        GrStatement statement = ((GrStatementOwner) owner).addStatementBefore(resultDecl, anchor);
        JavaCodeStyleManager.getInstance(statement.getProject()).shortenClassReferences(statement);

        // Replace all return statements with assignments to 'result' variable
        for (GrStatement returnStatement : returnStatements) {
          GrExpression value = ControlFlowUtils.extractReturnExpression(returnStatement);
          if (value != null) {
            GrExpression assignment = factory.createExpressionFromText(resultName + " = " + value.getText());
            returnStatement.replaceWithStatement(assignment);
          } else {
            returnStatement.replaceWithStatement(factory.createExpressionFromText(resultName + " = null"));
          }
        }
      }
      if (!isTailMethodCall && resultOfCallExplicitlyUsed && returnCount == 1) {
        returnStatements.iterator().next().removeStatement();
      }
      else if (!isTailMethodCall && (PsiTypes.voidType().equals(methodType) || returnCount == 1)) {
        for (GrStatement returnStatement : returnStatements) {
          if (returnStatement instanceof GrReturnStatement) {
            final GrExpression returnValue = ((GrReturnStatement)returnStatement).getReturnValue();
            if (returnValue != null && GroovyRefactoringUtil.hasSideEffect(returnValue)) {
              returnStatement.replaceWithStatement(returnValue);
              continue;
            }
          }
          else if (GroovyRefactoringUtil.hasSideEffect(returnStatement)) {
            continue;
          }
          returnStatement.removeStatement();
        }
      }

      // Add all method statements
      GrStatement[] statements = body.getStatements();
      for (GrStatement statement : statements) {
        ((GrStatementOwner) owner).addStatementBefore(statement, anchor);
      }
      if (resultOfCallExplicitlyUsed && !isTailMethodCall) {
        TextRange range = replaced.getTextRange();
        RangeMarker marker = editor != null ? editor.getDocument().createRangeMarker(range.getStartOffset(), range.getEndOffset(), true) : null;
        reformatOwner(owner);
        return marker;
      } else {
        GrStatement stmt;
        if (isTailMethodCall && enclosingExpr.getParent() instanceof GrReturnStatement) {
          stmt = (GrReturnStatement) enclosingExpr.getParent();
        } else {
          stmt = enclosingExpr;
        }
        stmt.removeStatement();
        reformatOwner(owner);
        return null;
      }
    } catch (IncorrectOperationException e) {
      LOG.error(e);
    }
    return null;
  }
@Nullable
  static RangeMarker inlineReferenceImpl(@NotNull GrCallExpression call,
                                         @NotNull GrMethod method,
                                         boolean resultOfCallExplicitlyUsed,
                                         boolean isTailMethodCall,
                                         @Nullable Editor editor)