public CandidateEventNotification recordNotification(
      final CandidateEvent candidateEvent, final Notification notification) {
    final CandidateEventNotification record = new CandidateEventNotification();
    record.setCandidateEvent(candidateEvent);

    record.setMessage(notification.getMessage());
    record.setNotificationLevel(notification.getNotificationLevel());
    record.setNotificationType(notification.getNotificationType());

    final QtiNode qtiNode = notification.getQtiNode();
    if (qtiNode != null) {
      record.setNodeQtiClassName(qtiNode.getQtiClassName());
      final XmlSourceLocationInformation sourceLocation = qtiNode.getSourceLocation();
      if (sourceLocation != null) {
        record.setSystemId(sourceLocation.getSystemId());
        record.setLineNumber(sourceLocation.getLineNumber());
        record.setColumnNumber(sourceLocation.getColumnNumber());
      }
    }
    final Attribute<?> attribute = notification.getAttribute();
    if (attribute != null) {
      record.setAttributeLocalName(attribute.getLocalName());
      record.setAttributeNamespaceUri(attribute.getNamespaceUri());
    }

    candidateEvent.getNotifications().add(record);
    candidateEventNotificationDao.persist(record);
    return record;
  }
  /**
   * Gets attribute with given local name and namespace URI or null (if attribute is not found).
   * Silent parameter is useful for support of unknown attributes.
   *
   * @param localName name of requested attribute
   * @param silent if exception should be thrown in case attribute is not found
   * @return attribute with given name
   * @throws QtiAttributeException if silent is false and if attribute is not found
   */
  private Attribute<?> get(
      final String localName, final String namespaceUri, final boolean silent) {
    Assert.notNull(localName, "localName");
    Assert.notNull(namespaceUri, "namespaceUri");
    for (final Attribute<?> attribute : attributes) {
      if (attribute.getLocalName().equals(localName)
          && attribute.getNamespaceUri().equals(namespaceUri)) {
        return attribute;
      }
    }

    if (silent) {
      return null;
    }
    throw new QtiAttributeException(
        "Cannot find attribute with namespace '"
            + namespaceUri
            + "' and local name '"
            + localName
            + "' in Node with XPath "
            + owner.computeXPath());
  }