@NotNull
  public static PyCodeFragment createCodeFragment(@NotNull final ScopeOwner owner,
                                                  @NotNull final PsiElement startInScope,
                                                  @NotNull final PsiElement endInScope) throws CannotCreateCodeFragmentException {
    final int start = startInScope.getTextOffset();
    final int end = endInScope.getTextOffset() + endInScope.getTextLength();
    final ControlFlow flow = ControlFlowCache.getControlFlow(owner);
    final List<Instruction> graph = Arrays.asList(flow.getInstructions());
    final List<Instruction> subGraph = getFragmentSubGraph(graph, start, end);
    final AnalysisResult subGraphAnalysis = analyseSubGraph(subGraph, start, end);
    if ((subGraphAnalysis.regularExits > 0 && subGraphAnalysis.returns > 0) ||
        subGraphAnalysis.outerLoopBreaks > 0) {
      throw new CannotCreateCodeFragmentException(PyPsiBundle.message("refactoring.extract.method.error.interrupted.execution.flow"));
    }
    if (subGraphAnalysis.starImports > 0) {
      throw new CannotCreateCodeFragmentException(PyPsiBundle.message("refactoring.extract.method.error.star.import"));
    }

    final Set<String> globalWrites = getGlobalWrites(subGraph, owner);
    final Set<String> nonlocalWrites = getNonlocalWrites(subGraph, owner);

    final Set<String> inputNames = new HashSet<>();
    for (PsiElement element : filterElementsInScope(getInputElements(subGraph, graph), owner)) {
      final String name = getName(element);
      if (name != null) {
        // Ignore "self" and "cls", they are generated automatically when extracting any method fragment
        if (resolvesToBoundMethodParameter(element)) {
          continue;
        }
        if (globalWrites.contains(name) || nonlocalWrites.contains(name)) {
          continue;
        }
        inputNames.add(name);
      }
    }

    final Set<String> outputNames = new HashSet<>();
    for (PsiElement element : getOutputElements(subGraph, graph)) {
      final String name = getName(element);
      if (name != null) {
        if (globalWrites.contains(name) || nonlocalWrites.contains(name)) {
          continue;
        }
        outputNames.add(name);
      }
    }

    final boolean yieldsFound = subGraphAnalysis.yieldExpressions > 0;
    if (yieldsFound && LanguageLevel.forElement(owner).isPython2()) {
      throw new CannotCreateCodeFragmentException(PyPsiBundle.message("refactoring.extract.method.error.yield"));
    }
    final boolean isAsync = owner instanceof PyFunction && ((PyFunction)owner).isAsync();

    return new PyCodeFragment(inputNames, outputNames, globalWrites, nonlocalWrites, subGraphAnalysis.returns > 0, yieldsFound, isAsync);
  }
@NotNull
  public static PyCodeFragment createCodeFragment(@NotNull final ScopeOwner owner,
                                                  @NotNull final PsiElement startInScope,
                                                  @NotNull final PsiElement endInScope)