/**
  * Loads group's children from given source DOM {@link Element}.
  *
  * <ul>
  *   <li>Unsupported (unknown) children are skipped.
  *   <li>Wrong order of children is ignored (children are loaded in correct order).
  * </ul>
  *
  * @param element source DOM {@link Element}
  * @param context current {@link LoadingContext} callback
  */
 public void load(final Element element, final LoadingContext context) {
   for (final NodeGroup<?, ?> group : groups) {
     group.getChildren().clear();
   }
   final NodeList childNodes = element.getChildNodes();
   for (int i = 0; i < childNodes.getLength(); i++) {
     final Node childNode = childNodes.item(i);
     boolean childLoaded = false;
     for (final NodeGroup<?, ?> group : groups) {
       if (group.loadChildIfSupported(childNode, context)) {
         childLoaded = true;
         break;
       }
     }
     if (!childLoaded) {
       /* No NodeGroup supports this child */
       if (childNode.getNodeType() == Node.TEXT_NODE
           && childNode.getNodeValue().trim().isEmpty()) {
         /* Whitespace node, so we'll ignore this */
       } else {
         /* Register error */
         final String childName =
             childNode.getNodeType() == Node.ELEMENT_NODE ? childNode.getLocalName() : "(text)";
         context.modelBuildingError(new QtiIllegalChildException(parent, childName), childNode);
       }
     }
   }
 }
 private static final <V> void loadAttribute(
     final Attribute<V> attribute,
     final Element element,
     final String stringValue,
     final LoadingContext context) {
   Assert.notNull(stringValue, "stringValue");
   V value = null;
   try {
     value = attribute.parseDomAttributeValue(stringValue);
   } catch (final QtiParseException ex) {
     context.modelBuildingError(ex, element);
   }
   attribute.setValue(value);
 }