public static void doCreate(PsiClass targetClass,
                              PsiMethod method,
                              boolean shouldBeAbstract,
                              List<? extends Pair<PsiExpression, PsiType>> arguments,
                              PsiSubstitutor substitutor,
                              ExpectedTypeInfo[] expectedTypes,
                              final @Nullable PsiElement context) {

    method = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(method);

    if (method == null) {
      return;
    }
    final Project project = targetClass.getProject();
    final PsiFile targetFile = targetClass.getContainingFile();
    Document document = PsiDocumentManager.getInstance(project).getDocument(targetFile);
    if (document == null) return;

    TemplateBuilderImpl builder = new TemplateBuilderImpl(method);

    CreateFromUsageUtils.setupMethodParameters(method, builder, context, substitutor, arguments);
    final PsiTypeElement returnTypeElement = method.getReturnTypeElement();
    if (returnTypeElement != null) {
      new GuessTypeParameters(project, JavaPsiFacade.getElementFactory(project), builder, substitutor)
        .setupTypeElement(returnTypeElement, expectedTypes, context, targetClass);
    }
    PsiCodeBlock body = method.getBody();
    builder.setEndVariableAfter(shouldBeAbstract || body == null ? method : body.getLBrace());
    method = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(method);
    if (method == null) return;

    RangeMarker rangeMarker = document.createRangeMarker(method.getTextRange());
    final Editor newEditor = CodeInsightUtil.positionCursor(project, targetFile, method);
    if (newEditor == null) return;
    Template template = builder.buildTemplate();
    newEditor.getCaretModel().moveToOffset(rangeMarker.getStartOffset());
    newEditor.getDocument().deleteString(rangeMarker.getStartOffset(), rangeMarker.getEndOffset());
    rangeMarker.dispose();

    if (!shouldBeAbstract) {
      startTemplate(newEditor, template, project, new TemplateEditingAdapter() {
        @Override
        public void templateFinished(@NotNull Template template, boolean brokenOff) {
          if (brokenOff) return;
          WriteCommandAction.runWriteCommandAction(project, () -> {
            PsiDocumentManager.getInstance(project).commitDocument(newEditor.getDocument());
            final int offset = newEditor.getCaretModel().getOffset();
            PsiMethod method1 = PsiTreeUtil.findElementOfClassAtOffset(targetFile, offset - 1, PsiMethod.class, false);
            if (method1 != null) {
              try {
                CreateFromUsageUtils.setupMethodBody(method1);
              }
              catch (IncorrectOperationException e) {
                LOG.error(e);
              }

              CreateFromUsageUtils.setupEditor(method1, newEditor);
            }
          });
        }
      });
    }
    else {
      startTemplate(newEditor, template, project);
    }
  }
public static void doCreate(PsiClass targetClass,
                              PsiMethod method,
                              boolean shouldBeAbstract,
                              List<? extends Pair<PsiExpression, PsiType>> arguments,
                              PsiSubstitutor substitutor,
                              ExpectedTypeInfo[] expectedTypes,
                              final @Nullable PsiElement context)