protected void doInvoke(@NotNull Project project, Editor editor, PsiFile file) {
    if (!editor.getSelectionModel().hasSelection()) {
      String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("no.selection"));
      CommonRefactoringUtil.showErrorHint(project, editor, message, getRefactoringName(), HELP_ID);
      return;
    }
    final int start = editor.getSelectionModel().getSelectionStart();
    final int end = editor.getSelectionModel().getSelectionEnd();

    final Pair<T, T> children = findPairToExtract(start, end);
    if (children == null) {
      String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("selection.does.not.form.a.fragment.for.extraction"));
      CommonRefactoringUtil.showErrorHint(project, editor, message, getRefactoringName(), HELP_ID);
      return;
    }

    if (!verifyChildRange(children.getFirst(), children.getSecond())) {
      String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("cannot.extract.selected.elements.into.include.file"));
      CommonRefactoringUtil.showErrorHint(project, editor, message, getRefactoringName(), HELP_ID);
      return;
    }

    FileType fileType = getLanguageForExtract(children.getFirst()).getAssociatedFileType();
    if (fileType == null) {
      String message = RefactoringBundle.message("the.language.for.selected.elements.has.no.associated.file.type");
      CommonRefactoringUtil.showErrorHint(project, editor, message, getRefactoringName(), HELP_ID);
      return;
    }

    if (!CommonRefactoringUtil.checkReadOnlyStatus(project, file)) return;


    Pair<PsiDirectory, String> directoryAndFileName = getTargetDirectoryAndFileName(file, fileType, children);
    if (directoryAndFileName.first == null || directoryAndFileName.second == null) {
      return;
    }

    CommandProcessor.getInstance().executeCommand(project, () -> ApplicationManager.getApplication().runWriteAction(() -> {
      try {
        final List<IncludeDuplicate<T>> duplicates = new ArrayList<>();
        final T first = children.getFirst();
        final T second = children.getSecond();
        PsiEquivalenceUtil.findChildRangeDuplicates(first, second, file, (start1, end1) -> duplicates.add(
          new IncludeDuplicate<>((T)start1, (T)end1)));
        String includePath = processPrimaryFragment(first, second, directoryAndFileName.first, directoryAndFileName.second, file);
        editor.getCaretModel().moveToOffset(first.getTextRange().getStartOffset());

        ApplicationManager.getApplication().invokeLater(() -> replaceDuplicates(includePath, duplicates, editor, project));
      }
      catch (IncorrectOperationException e) {
        CommonRefactoringUtil.showErrorMessage(getRefactoringName(), e.getMessage(), null, project);
      }

      editor.getSelectionModel().removeSelection();
    }), getRefactoringName(), null);
  }
protected void doInvoke(@NotNull Project project, Editor editor, PsiFile file)