public static void runTemplate(List<? extends ClosureParameterInfo> parameters,
                                 GrClosableBlock block,
                                 PsiSubstitutor substitutor,
                                 PsiMethod method, final Project project,
                                 final Editor editor) {
    if (method instanceof ClsMethodImpl) method = ((ClsMethodImpl)method).getSourceMirrorMethod();

    assert block.getArrow() == null;
    if (parameters.isEmpty()) return;

    StringBuilder buffer = new StringBuilder();
    buffer.append("{");

    List<PsiType> paramTypes = new ArrayList<>();
    for (ClosureParameterInfo parameter : parameters) {
      final String type = parameter.getType();
      final String name = parameter.getName();
      if (type != null) {
        final PsiType fromText = JavaPsiFacade.getElementFactory(project).createTypeFromText(type, method);
        final PsiType substituted = substitutor.substitute(fromText);
        paramTypes.add(substituted);
        buffer.append(substituted.getCanonicalText()).append(" ");
      }
      else {
        buffer.append("def ");
      }
      buffer.append(name);
      buffer.append(", ");
    }
    buffer.replace(buffer.length() - 2, buffer.length(), " ->}");

    final Document document = editor.getDocument();
    final PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
    assert file != null;

    final GrClosableBlock closure = GroovyPsiElementFactory.getInstance(project).createClosureFromText(buffer.toString());
    final GrClosableBlock templateClosure = (GrClosableBlock)block.replaceWithExpression(closure, false);

    final TemplateBuilderImpl builder = new TemplateBuilderImpl(templateClosure);

    int i = 0;
    for (GrParameter p : templateClosure.getParameters()) {
      final GrTypeElement typeElement = p.getTypeElementGroovy();
      final PsiElement nameIdentifier = p.getNameIdentifierGroovy();

      if (typeElement != null) {
        final TypeConstraint[] typeConstraints = {SupertypeConstraint.create(paramTypes.get(i++))};
        final ChooseTypeExpression expression = new ChooseTypeExpression(typeConstraints, PsiManager.getInstance(project), nameIdentifier.getResolveScope());
        builder.replaceElement(typeElement, expression);
      }
      else {
        final ChooseTypeExpression expression =
          new ChooseTypeExpression(TypeConstraint.EMPTY_ARRAY, PsiManager.getInstance(project), nameIdentifier.getResolveScope());
        builder.replaceElement(p.getModifierList(), expression);
      }

      builder.replaceElement(nameIdentifier, new StringParameterNameExpression(nameIdentifier.getText()));
    }

    final GrClosableBlock afterPostprocess = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(templateClosure);
    final Template template = builder.buildTemplate();
    TextRange range = afterPostprocess.getTextRange();
    document.deleteString(range.getStartOffset(), range.getEndOffset());

    TemplateEditingListener templateListener = new TemplateEditingAdapter() {
      @Override
      public void templateFinished(@NotNull Template template, boolean brokenOff) {
        ApplicationManager.getApplication().runWriteAction(() -> {
          PsiDocumentManager.getInstance(project).commitDocument(document);
          final CaretModel caretModel = editor.getCaretModel();
          final int offset = caretModel.getOffset();
          GrClosableBlock block1 = PsiTreeUtil.findElementOfClassAtOffset(file, offset - 1, GrClosableBlock.class, false);
          if (block1 != null) {
            final PsiElement arrow = block1.getArrow();
            if (arrow != null) {
              caretModel.moveToOffset(arrow.getTextRange().getEndOffset());
            }

            // fix space before closure lbrace
            final TextRange range1 = block1.getTextRange();
            CodeStyleManager.getInstance(project).reformatRange(block1.getParent(), range1.getStartOffset() - 1, range1.getEndOffset(), true);
          }
        });
      }
    };

    TemplateManager manager = TemplateManager.getInstance(project);
    manager.startTemplate(editor, template, templateListener);
  }
public static void runTemplate(List<? extends ClosureParameterInfo> parameters,
                                 GrClosableBlock block,
                                 PsiSubstitutor substitutor,
                                 PsiMethod method, final Project project,
                                 final Editor editor)