@Override
 public void endDataField(Field designator) {
   try {
     if (!datafieldOpen) {
       return;
     }
     if (listener != null) {
       listener.endDataField(designator);
     }
     if (designator != null) {
       String value = designator.data();
       if (value != null && !value.isEmpty()) {
         value = normalizeValue(value);
         // write data field per default into a subfield with code 'a'
         AttributesImpl attrs = new AttributesImpl();
         attrs.addAttribute(nsUri, CODE, CODE, "CDATA", "a");
         if (contentHandler != null) {
           contentHandler.startElement(nsUri, SUBFIELD, SUBFIELD, attrs);
           contentHandler.characters(value.toCharArray(), 0, value.length());
           contentHandler.endElement(nsUri, SUBFIELD, SUBFIELD);
         }
       }
     }
     if (contentHandler != null) {
       contentHandler.endElement(NS_URI, DATAFIELD, DATAFIELD);
     }
     datafieldOpen = false;
   } catch (Exception ex) {
     if (fatalerrors) {
       throw new RuntimeException(ex);
     } else if (!silenterrors) {
       logger.warn(designator + ": " + ex.getMessage(), ex);
     }
   }
 }
 @Override
 public void endSubField(Field designator) {
   if (designator == null) {
     return;
   }
   try {
     if (listener != null) {
       listener.endSubField(designator);
     }
     if (designator != null) {
       if (contentHandler != null) {
         String value = designator.data();
         if (!value.isEmpty()) {
           value = normalizeValue(value);
           contentHandler.characters(value.toCharArray(), 0, value.length());
         }
       }
     }
     if (contentHandler != null) {
       contentHandler.endElement(NS_URI, SUBFIELD, SUBFIELD);
     }
   } catch (Exception ex) {
     if (fatalerrors) {
       throw new RuntimeException(ex);
     } else if (!silenterrors) {
       logger.warn(designator + ": " + ex.getMessage(), ex);
     }
   }
 }
 @Override
 public void endControlField(Field designator) {
   try {
     if (listener != null) {
       listener.endControlField(designator);
     }
     if (designator != null) {
       String value = designator.data();
       if (!value.isEmpty()) {
         switch (designator.tag()) {
           case "001":
             this.id = value;
             break;
           case "006":
           case "007":
           case "008":
             // fix fill characters here
             value = value.replace('^', '|');
             break;
         }
         if (contentHandler != null) {
           contentHandler.characters(value.toCharArray(), 0, value.length());
         }
       }
     }
     if (contentHandler != null) {
       contentHandler.endElement(nsUri, CONTROLFIELD, CONTROLFIELD);
     }
   } catch (Exception ex) {
     if (fatalerrors) {
       throw new RuntimeException(ex);
     } else if (!silenterrors) {
       logger.warn(designator + ": " + ex.getMessage(), ex);
     }
   }
 }