/**
   * @param text
   * @param validate
   * @return
   * @throws org.purl.sword.base.UnmarshallException
   */
  public SwordValidationInfo unmarshall(Element text, Properties validationProperties)
      throws UnmarshallException {
    if (!isInstanceOf(text, xmlName)) {
      return handleIncorrectElement(text, validationProperties);
    }

    ArrayList<SwordValidationInfo> validationItems = new ArrayList<SwordValidationInfo>();
    ArrayList<SwordValidationInfo> attributeItems = new ArrayList<SwordValidationInfo>();

    try {
      initialise();

      // get the attributes
      int attributeCount = text.getAttributeCount();
      Attribute attribute = null;
      for (int i = 0; i < attributeCount; i++) {
        attribute = text.getAttribute(i);
        if (ATTRIBUTE_TYPE.equals(attribute.getQualifiedName())) {
          boolean success = true;
          String value = attribute.getValue();
          if (ContentType.TEXT.toString().equals(value)) {
            type = ContentType.TEXT;
          } else if (ContentType.HTML.toString().equals(value)) {
            type = ContentType.HTML;
          } else if (ContentType.XHTML.toString().equals(value)) {
            type = ContentType.XHTML;
          } else {
            log.error("Unable to parse extract type in " + getQualifiedName());
            SwordValidationInfo info =
                new SwordValidationInfo(
                    xmlName,
                    new XmlName(attribute),
                    "Invalid content type has been specified",
                    SwordValidationInfoType.ERROR);
            info.setContentDescription(value);
            attributeItems.add(info);
            success = false;
          }

          if (success) {
            SwordValidationInfo info = new SwordValidationInfo(xmlName, new XmlName(attribute));
            info.setContentDescription(type.toString());
            attributeItems.add(info);
          }
        } else {
          SwordValidationInfo info =
              new SwordValidationInfo(
                  xmlName,
                  new XmlName(attribute),
                  SwordValidationInfo.UNKNOWN_ATTRIBUTE,
                  SwordValidationInfoType.INFO);
          info.setContentDescription(attribute.getValue());
          attributeItems.add(info);
        }
      }

      // retrieve all of the sub-elements
      int length = text.getChildCount();
      if (length > 0) {
        content = unmarshallString(text);
      }

    } catch (Exception ex) {
      log.error("Unable to parse an element in " + getQualifiedName() + ": " + ex.getMessage());
      throw new UnmarshallException("Unable to parse an element in " + getQualifiedName(), ex);
    }

    SwordValidationInfo result = null;
    if (validationProperties != null) {
      result = validate(validationItems, attributeItems, validationProperties);
    }
    return result;
  }