public static List<SmartPsiFileRange> extractFromExpression(@NotNull final Project project,
                                                              @NotNull final Editor editor,
                                                              @NotNull final PyCodeFragment fragment,
                                                              @NotNull final PsiElement expression,
                                                              final Boolean processDuplicates) {
    List<SmartPsiFileRange> pointers = new ArrayList<>();

    if (!fragment.getOutputVariables().isEmpty()) {
      CommonRefactoringUtil.showErrorHint(project, editor,
                                          PyPsiBundle.message("refactoring.extract.method.error.local.variable.modifications"),
                                          RefactoringBundle.message("error.title"), "refactoring.extractMethod");
      return pointers;
    }

    if (fragment.isReturnInstructionInside()) {
      CommonRefactoringUtil.showErrorHint(project, editor,
                                          PyPsiBundle.message("refactoring.extract.method.error.returns"),
                                          RefactoringBundle.message("error.title"), "refactoring.extractMethod");
      return pointers;
    }

    final PyFunction function = PsiTreeUtil.getParentOfType(expression, PyFunction.class);
    final PyUtil.MethodFlags flags = function == null ? null : PyUtil.MethodFlags.of(function);
    final boolean isClassMethod = flags != null && flags.isClassMethod();
    final boolean isStaticMethod = flags != null && flags.isClassMethod();

    final Pair<String, AbstractVariableData[]> data = getNameAndVariableData(project, fragment, expression, isClassMethod, isStaticMethod);
    if (data.first == null || data.second == null) {
      return pointers;
    }

    final String methodName = data.first;
    final AbstractVariableData[] variableData = data.second;

    final SimpleDuplicatesFinder finder = new SimpleDuplicatesFinder(expression, expression, fragment.getOutputVariables(), variableData);
    if (fragment.getOutputVariables().isEmpty()) {
      CommandProcessor.getInstance().executeCommand(project, () -> {
        // Generate method
        final boolean isAsync = fragment.isAsync();
        final PyFunction generatedMethod = generateMethodFromExpression(methodName, variableData, expression, flags, isAsync);
        final PyFunction insertedMethod = WriteAction.compute(() -> insertGeneratedMethod(expression, generatedMethod));

        // Process parameters
        final boolean isMethod = PyPsiUtils.isMethodContext(expression);
        WriteAction.run(() -> processParameters(project, insertedMethod, variableData, isMethod, isClassMethod, isStaticMethod));

        // Generating call element
        final StringBuilder builder = new StringBuilder();
        if (isAsync) {
          builder.append("async ");
        }
        builder.append("def f():\n    ");
        if (isAsync) {
          builder.append("await ");
        }
        else if (fragment.isYieldInside()) {
          builder.append("yield from ");
        }
        else {
          builder.append("return ");
        }
        if (isMethod) {
          appendSelf(expression, builder, isStaticMethod);
        }
        builder.append(methodName);
        builder.append("(").append(createCallArgsString(variableData)).append(")");
        final PyElementGenerator generator = PyElementGenerator.getInstance(project);
        final PyFunction function1 = generator.createFromText(LanguageLevel.forElement(expression), PyFunction.class,
                                                              builder.toString());
        final PyElement generated = function1.getStatementList().getStatements()[0];
        final PsiElement callElement;
        if (generated instanceof PyReturnStatement) {
          callElement = ((PyReturnStatement)generated).getExpression();
        }
        else if (generated instanceof PyExpressionStatement) {
          callElement = ((PyExpressionStatement)generated).getExpression();
        }
        else {
          callElement = null;
        }

        PyPsiUtils.assertValid(expression);
        List<SimpleMatch> duplicates = collectDuplicates(finder, expression, insertedMethod);
        // When a single reference is extracted into an identity function, prevent unrelated expressions being replaced with calls to it
        if (expression instanceof PyReferenceExpression) {
          duplicates = ContainerUtil.filter(duplicates, it -> it.getStartElement() == it.getEndElement() &&
                                                              expression.getText().equals(it.getStartElement().getText()));
        }

        // replace statements with call
        PsiElement insertedCallElement = null;
        PsiFile file = expression.getContainingFile();
        SmartPointerManager pointerManager = SmartPointerManager.getInstance(project);
        if (processDuplicates) {
          pointers.addAll(ContainerUtil.map(duplicates, p -> pointerManager.createSmartPsiFileRangePointer(file, p.getStartElement().getTextRange())));
        }
        if (callElement != null) {
          insertedCallElement = WriteAction.compute(() -> PyReplaceExpressionUtil.replaceExpression(expression, callElement));
          if (insertedCallElement != null) {
            pointers.add(0, pointerManager.createSmartPsiFileRangePointer(file, insertedMethod.getNameIdentifier().getTextRange()));
            pointers.add(pointerManager.createSmartPsiFileRangePointer(file, insertedCallElement.getTextRange()));
            if (processDuplicates) {
              processDuplicates(duplicates, insertedCallElement, editor);
            }
          }
        }
        setSelectionAndCaret(editor, insertedCallElement);
        // Set editor
      }, PyPsiBundle.message("refactoring.extract.method"), null);
    }
    return pointers;
  }
public static List<SmartPsiFileRange> extractFromExpression(@NotNull final Project project,
                                                              @NotNull final Editor editor,
                                                              @NotNull final PyCodeFragment fragment,
                                                              @NotNull final PsiElement expression,
                                                              final Boolean processDuplicates)