protected <T extends Tag> T getChildTag(Map<String, Tag> items, String key, Class<T> expected) {
   if (!items.containsKey(key)) {
     return null;
   }
   Tag tag = items.get(key);
   if (!expected.isInstance(tag)) {
     throw new IllegalArgumentException(
         tag.getName()
             + " tag is not of tag type "
             + expected.getName()
             + System.lineSeparator()
             + "tag is: "
             + tag);
   }
   return expected.cast(tag);
 }
  protected <T> T convert(Object obj, Class<T> expected) {
    if (!(obj instanceof Tag)) {
      return null;
    } else {

      Tag tag = (Tag) obj;

      if (!expected.isInstance(tag.getValue())) {
        throw new IllegalArgumentException(
            tag.getName()
                + " tag is not of tag type "
                + expected.getName()
                + System.lineSeparator()
                + "tag is: "
                + tag);
      }

      return expected.cast(tag.getValue());
    }
  }