/**
  * Updates, creates or deletes UDI events using a given list of UDI Event DTOs.
  *
  * @param period {@link LocalDate} period for which UDI Events will be created/updated/deleted.
  * @param updatedUdiEvents {@link List} of {@link UdiEventDto}.
  */
 public void updateUdiEvents(LocalDate period, List<UdiEventDto> updatedUdiEvents) {
   LOGGER.debug("Updating udi events for period [{}]", period);
   // fetch existing udi events
   Map<String, UdiEvent> udiEventsPerId =
       udiEventRepository
           .findUdiEventsForPeriod(period)
           .stream()
           .collect(Collectors.toMap(UdiEvent::getId, Function.identity()));
   // 1. Update or create UdiEvents
   for (UdiEventDto udiEventDto : updatedUdiEvents) {
     if (!udiEventsPerId.containsKey(udiEventDto.getId())) {
       createUdiEventFromDto(udiEventDto, period);
     } else {
       updateUdiEventFromDto(udiEventsPerId.get(udiEventDto.getId()), udiEventDto);
     }
   }
   // 2. Delete udi events not present in the list anymore
   Set<String> updatedIds =
       updatedUdiEvents.stream().map(UdiEventDto::getId).collect(Collectors.toSet());
   udiEventsPerId
       .entrySet()
       .stream()
       .filter(udiEventPerId -> !updatedIds.contains(udiEventPerId.getKey()))
       .forEach(
           udiEventPerId -> {
             LOGGER.debug("Deleted udi event with id [{}]", udiEventPerId.getKey());
             udiEventRepository.delete(udiEventPerId.getValue());
           });
 }
 private void createUdiEventFromDto(UdiEventDto udiEventDto, LocalDate period) {
   Udi udi = udiRepository.findByEndpoint(udiEventDto.getUdiEndpoint(), period);
   UdiEvent udiEvent = UdiEventTransformer.transformToModel(udiEventDto, udi);
   udiEventRepository.persist(udiEvent);
   LOGGER.debug("Created new udi event with id [{}]", udiEvent.getId());
   udiEventDto
       .getDeviceCapabilities()
       .forEach(deviceCapabilityDto -> createDeviceCapability(deviceCapabilityDto, udiEvent));
 }
 private void updateUdiEventFromDto(UdiEvent originalUdiEvent, UdiEventDto udiEventDto) {
   // should not change but you never know, let's allow it for now
   originalUdiEvent.setPeriod(udiEventDto.getPeriod());
   originalUdiEvent.setUdiEventType(
       UdiEventTransformer.transformToModel(udiEventDto.getUdiEventType()));
   // may change
   originalUdiEvent.setStartDtu(udiEventDto.getStartDtu());
   originalUdiEvent.setEndDtu(udiEventDto.getEndDtu());
   originalUdiEvent.setStartAfterDtu(udiEventDto.getStartAfterDtu());
   originalUdiEvent.setFinishBeforeDtu(udiEventDto.getFinishBeforeDtu());
   originalUdiEvent.setDeviceSelector(udiEventDto.getDeviceSelector());
   Map<String, DeviceCapability> dbCapabilitiesPerId =
       originalUdiEvent
           .getDeviceCapabilities()
           .stream()
           .collect(Collectors.toMap(DeviceCapability::getId, Function.identity()));
   LOGGER.debug("Updated udi event with id [{}]", originalUdiEvent.getId());
   // update of create
   udiEventDto
       .getDeviceCapabilities()
       .stream()
       .forEach(
           deviceCapabilityDto -> {
             if (!dbCapabilitiesPerId.containsKey(deviceCapabilityDto.getId())) {
               createDeviceCapability(deviceCapabilityDto, originalUdiEvent);
             } else {
               updateDeviceCapability(
                   dbCapabilitiesPerId.get(deviceCapabilityDto.getId()), deviceCapabilityDto);
             }
           });
   // remove capabilities that are not given back in the updated id list
   Set<String> updatedCapabilitiesId =
       udiEventDto
           .getDeviceCapabilities()
           .stream()
           .map(DeviceCapabilityDto::getId)
           .collect(Collectors.toSet());
   dbCapabilitiesPerId
       .values()
       .stream()
       .filter(deviceCapability -> !updatedCapabilitiesId.contains(deviceCapability.getId()))
       .forEach(
           deviceCapability -> {
             LOGGER.debug(
                 "Deleted device capability with id [{}] for udi event with id [{}]",
                 deviceCapability.getId(),
                 deviceCapability.getUdiEvent().getId());
             originalUdiEvent.getDeviceCapabilities().remove(deviceCapability);
           });
 }