@Override
  public TemplateBuilder buildTemplate(@NotNull PsiFile psiFile) {
    TemplateBuilder builder = TemplateBuilderFactory.getInstance().createTemplateBuilder(psiFile);
    PlaceholderCount classCount = new PlaceholderCount("Class");
    PlaceholderCount varCount = new PlaceholderCount("Var");
    PlaceholderCount funCount = new PlaceholderCount("Fun");

    IntRef shift = new IntRef();
    JavaRecursiveElementVisitor visitor = new JavaRecursiveElementVisitor() {

      @Override
      public void visitIdentifier(@NotNull PsiIdentifier identifier) {
        PsiElement parent = identifier.getParent();
        if (parent instanceof PsiClass) {
          replaceElement(identifier, classCount, true, builder, shift.get());
        }
        else if (parent instanceof PsiReferenceExpression) {
          if (parent.getParent() instanceof PsiMethodCallExpression)
            replaceElement(identifier, funCount, true, builder, shift.get());
          else
            replaceElement(identifier, varCount, false, builder, shift.get());
        }
        else if (parent instanceof PsiJavaCodeReferenceElement) {
          replaceElement(identifier, classCount, false, builder, shift.get());
        }
      }

      @Override
      public void visitReferenceList(@NotNull PsiReferenceList list) {
        PsiJavaCodeReferenceElement[] elements = list.getReferenceElements();
        for (PsiJavaCodeReferenceElement element : elements) {
          replaceElement(element.getReferenceNameElement(), classCount, false, builder, shift.get());
        }
      }
    };

    String text = psiFile.getText();
    int textOffset = 0;
    while (textOffset < text.length() && StringUtil.isWhiteSpace(text.charAt(textOffset))) {
      textOffset++;
    }
    shift.set(shift.get() - textOffset);
    PsiElement[] elements =
      MatcherImplUtil.createTreeFromText(text, PatternTreeContext.Block, (LanguageFileType)psiFile.getFileType(), psiFile.getProject());
    if (elements.length > 0) {
      PsiElement element = elements[0];
      shift.set(shift.get() + element.getTextRange().getStartOffset());
      element.accept(visitor);
    }
    return builder;
  }
@Override
  public TemplateBuilder buildTemplate(@NotNull PsiFile psiFile)