public CompiledST defineTemplate(
      String templateName,
      Token nameT,
      List<FormalArgument> args,
      String template,
      Token templateToken) {
    if (templateName == null || templateName.length() == 0) {
      throw new IllegalArgumentException("empty template name");
    }
    if (templateName.indexOf('.') >= 0) {
      throw new IllegalArgumentException("cannot have '.' in template names");
    }
    template = Misc.trimOneStartingNewline(template);
    template = Misc.trimOneTrailingNewline(template);
    // compile, passing in templateName as enclosing name for any embedded regions
    CompiledST code = compile(getFileName(), templateName, args, template, templateToken);
    code.name = templateName;
    rawDefineTemplate(templateName, code, nameT);
    code.defineArgDefaultValueTemplates(this);
    code.defineImplicitlyDefinedTemplates(this); // define any anonymous subtemplates

    return code;
  }
  public CompiledST defineRegion(
      String enclosingTemplateName, Token regionT, String template, Token templateToken) {
    String name = regionT.getText();
    template = Misc.trimOneStartingNewline(template);
    template = Misc.trimOneTrailingNewline(template);
    CompiledST code = compile(getFileName(), enclosingTemplateName, null, template, templateToken);
    String mangled = getMangledRegionName(enclosingTemplateName, name);

    if (lookupTemplate(mangled) == null) {
      errMgr.compileTimeError(
          ErrorType.NO_SUCH_REGION, templateToken, regionT, enclosingTemplateName, name);
      return new CompiledST();
    }
    code.name = mangled;
    code.isRegion = true;
    code.regionDefType = ST.RegionType.EXPLICIT;
    code.templateDefStartToken = regionT;

    rawDefineTemplate(mangled, code, regionT);
    code.defineArgDefaultValueTemplates(this);
    code.defineImplicitlyDefinedTemplates(this);

    return code;
  }