@Override
  protected @Nullable ZenCodingNode parseTemplate() {
    ZenCodingToken token = getToken();
    String templateKey = getDefaultTemplateKey();
    boolean mustHaveSelector = true;

    if (token instanceof IdentifierToken) {
      templateKey = ((IdentifierToken)token).getText();
      advance();
      if (StringUtil.startsWithIgnoreCase(templateKey, LOREM_KEYWORD) || StringUtil.startsWithIgnoreCase(templateKey, LIPSUM_KEYWORD)) {
        return parseLorem(templateKey);
      }
      mustHaveSelector = false;
    }

    if (templateKey == null) {
      return null;
    }

    boolean forceSingleTag = false;
    TemplateImpl template = myCallback.findApplicableTemplate(templateKey);
    if (template == null && StringUtil.endsWithChar(templateKey, '/')) {
      forceSingleTag = true;
      templateKey = StringUtil.trimEnd(templateKey, '/');
    }
    if (template == null && !ZenCodingUtil.isXML11ValidQName(templateKey) && !StringUtil.containsChar(templateKey, '$')) {
      return null;
    }

    Map<String, String> attributes = parseSelectors();
    if (mustHaveSelector && attributes.isEmpty()) {
      return null;
    }

    ZenCodingToken currentToken = getToken();
    if (currentToken instanceof IdentifierToken && "/".equals(((IdentifierToken)currentToken).getText())) {
      advance();
      forceSingleTag = true;
    }

    TemplateToken templateToken = new TemplateToken(templateKey, attributes, forceSingleTag);
    if (!setTemplate(templateToken, template)) {
      return null;
    }
    return new TemplateNode(templateToken, myGenerator);
  }
@Override
  protected @Nullable ZenCodingNode parseTemplate()