@Nullable
  public Runnable startNonCustomTemplates(
      final Map<TemplateImpl, String> template2argument,
      final Editor editor,
      @Nullable final PairProcessor<String, String> processor) {
    final int caretOffset = editor.getCaretModel().getOffset();
    final Document document = editor.getDocument();
    final CharSequence text = document.getCharsSequence();

    if (template2argument == null || template2argument.isEmpty()) {
      return null;
    }
    if (!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), myProject)) {
      return null;
    }

    return () -> {
      if (template2argument.size() == 1) {
        TemplateImpl template = template2argument.keySet().iterator().next();
        String argument = template2argument.get(template);
        int templateStart = getTemplateStart(template, argument, caretOffset, text);
        startTemplateWithPrefix(editor, template, templateStart, processor, argument);
      } else {
        ListTemplatesHandler.showTemplatesLookup(myProject, editor, template2argument);
      }
    };
  }
 private static boolean containsTemplateStartingBefore(
     Map<TemplateImpl, String> template2argument, int offset, int caretOffset, CharSequence text) {
   for (TemplateImpl template : template2argument.keySet()) {
     String argument = template2argument.get(template);
     int templateStart = getTemplateStart(template, argument, caretOffset, text);
     if (templateStart < offset) {
       return true;
     }
   }
   return false;
 }