@Override
  public void tag(Tag tag) {
    String tagName = tag.getName().toString();

    if (tagName.startsWith("decora:")) {
      onDecoraTag(tag);
      return;
    }
    if (tag.getType().isStartingTag()) {
      CharSequence id = tag.getId();

      if (id != null && id.toString().startsWith("decora-")) {
        onIdAttrStart(tag);
      }
    } else {
      // close tag
      if (tagName.equals(closingTagName) && closingTagDeepLevel == tag.getDeepLevel()) {
        onIdAttrEnd(tag);
      }
    }
  }
  /** Handle Decora tags. */
  protected void onDecoraTag(Tag tag) {
    String tagName = tag.getName().toString();

    if (tag.getType() == TagType.SELF_CLOSING) {
      checkNestedDecoraTags();
      decoraTagName = tagName.substring(7);
      decoraTagStart = tag.getTagPosition();
      decoraTagEnd = tag.getTagPosition() + tag.getTagLength();
      defineDecoraTag();
      return;
    }

    if (tag.getType() == TagType.START) {
      checkNestedDecoraTags();
      decoraTagName = tagName.substring(7);
      decoraTagStart = tag.getTagPosition();
      decoraTagDefaultValueStart = tag.getTagPosition() + tag.getTagLength();
      return;
    }

    // closed tag type
    decoraTagEnd = tag.getTagPosition() + tag.getTagLength();
    decoraTagDefaultValueEnd = tag.getTagPosition();
    defineDecoraTag();
  }
 protected void onIdAttrEnd(Tag tag) {
   decoraTagEnd = tag.getTagPosition() + tag.getTagLength();
   decoraTagDefaultValueEnd = tag.getTagPosition();
   defineDecoraTag();
 }
  /** Handle open and empty ID attribute tags. */
  protected void onIdAttrStart(Tag tag) {
    String id = tag.getId().toString().substring(7);
    String tagName;
    String idName;

    int dashIndex = id.indexOf('-');
    if (dashIndex == -1) {
      tagName = id;
      idName = null;
    } else {
      tagName = id.substring(0, dashIndex);
      idName = id.substring(dashIndex + 1);
    }

    if (tag.getType() == TagType.SELF_CLOSING) {
      checkNestedDecoraTags();
      decoraTagName = tagName;
      decoraIdName = idName;
      decoraTagStart = tag.getTagPosition();
      decoraTagEnd = tag.getTagPosition() + tag.getTagLength();
      defineDecoraTag();
      return;
    }

    if (tag.getType() == TagType.START) {
      checkNestedDecoraTags();
      decoraTagName = tagName;
      decoraIdName = idName;
      decoraTagStart = tag.getTagPosition();
      decoraTagDefaultValueStart = tag.getTagPosition() + tag.getTagLength();

      closingTagName = tag.getName().toString();
      closingTagDeepLevel = tag.getDeepLevel();
    }
  }