/**
  * Parses the capabilities, processing and removing special insertion metadata
  *
  * @param abstractProcess The AbstractProcess to which capabilities and insertion metadata are
  *     added
  * @param capabilitiesArray XML capabilities
  * @throws OwsExceptionReport * if an error occurs
  */
 private void parseCapabilities(
     final AbstractProcess abstractProcess, final Capabilities[] capabilitiesArray)
     throws OwsExceptionReport {
   for (final Capabilities xbcaps : capabilitiesArray) {
     final Object o = CodingHelper.decodeXmlElement(xbcaps.getAbstractDataRecord());
     if (o instanceof DataRecord) {
       final DataRecord record = (DataRecord) o;
       final SmlCapabilities caps = new SmlCapabilities();
       caps.setDataRecord(record).setName(xbcaps.getName());
       abstractProcess.addCapabilities(caps);
       // check if this capabilities is insertion metadata
       if (SensorMLConstants.ELEMENT_NAME_OFFERINGS.equals(caps.getName())) {
         abstractProcess.addOfferings(
             SosOffering.fromSet(
                 caps.getDataRecord().getSweAbstractSimpleTypeFromFields(SweText.class)));
       } else if (SensorMLConstants.ELEMENT_NAME_PARENT_PROCEDURES.equals(caps.getName())) {
         abstractProcess.addParentProcedures(parseCapabilitiesMetadata(caps, xbcaps).keySet());
       } else if (SensorMLConstants.ELEMENT_NAME_FEATURES_OF_INTEREST.equals(caps.getName())) {
         abstractProcess.addFeaturesOfInterest(parseCapabilitiesMetadata(caps, xbcaps).keySet());
       }
     } else {
       throw new InvalidParameterValueException()
           .at(XmlHelper.getLocalName(xbcaps))
           .withMessage(
               "Error while parsing the capabilities of "
                   + "the SensorML (the capabilities data record "
                   + "is not of type DataRecordPropertyType)!");
     }
   }
 }
 /**
  * Process standard formatted capabilities insertion metadata into a map (key=identifier,
  * value=name)
  *
  * @param dataRecord The DataRecord to examine
  * @param xbCapabilities The original capabilites xml object, used for exception throwing
  * @return Map of insertion metadata (key=identifier, value=name)
  * @throws CodedException thrown if the DataRecord fields are in an incorrect format
  */
 private Map<String, String> parseCapabilitiesMetadata(
     final SmlCapabilities caps, final Capabilities xbCapabilities) throws OwsExceptionReport {
   final Map<String, String> map =
       Maps.newHashMapWithExpectedSize(caps.getDataRecord().getFields().size());
   for (final SweField sosSweField : caps.getDataRecord().getFields()) {
     if (sosSweField.getElement() instanceof SweText) {
       final SweText sosSweText = (SweText) sosSweField.getElement();
       if (sosSweText.isSetValue()) {
         map.put(sosSweText.getValue(), sosSweField.getName().getValue());
       } else {
         throw new UnsupportedDecoderInputException(this, xbCapabilities)
             .withMessage(
                 "Removable capabilities element %s contains a field with no value",
                 xbCapabilities.getName());
       }
     } else {
       throw new UnsupportedDecoderInputException(this, xbCapabilities)
           .withMessage(
               "Removable capabilities element %s contains a non-Text field",
               xbCapabilities.getName());
     }
   }
   return map;
 }