@Override
 public void saveWsdl(SubsystemId subsystemId, ServiceId serviceId, String wsdlString) {
   Assert.notNull(subsystemId);
   Assert.notNull(serviceId);
   Service oldService;
   // bit ugly this one, would be a little cleaner if
   // https://jira.spring.io/browse/DATAJPA-209 was resolved
   if (serviceId.getServiceVersion() == null) {
     oldService =
         serviceRepository.findActiveNullVersionByNaturalKey(
             subsystemId.getXRoadInstance(),
             subsystemId.getMemberClass(),
             subsystemId.getMemberCode(),
             subsystemId.getSubsystemCode(),
             serviceId.getServiceCode());
   } else {
     oldService =
         serviceRepository.findActiveByNaturalKey(
             subsystemId.getXRoadInstance(),
             subsystemId.getMemberClass(),
             subsystemId.getMemberCode(),
             subsystemId.getSubsystemCode(),
             serviceId.getServiceCode(),
             serviceId.getServiceVersion());
   }
   if (oldService == null) {
     throw new IllegalStateException("service " + serviceId + " not found!");
   }
   LocalDateTime now = LocalDateTime.now();
   Wsdl wsdl = new Wsdl();
   wsdl.setData(wsdlString);
   Wsdl oldWsdl = oldService.getWsdl();
   if (oldWsdl == null) {
     wsdl.initializeExternalId();
     wsdl.getStatusInfo().setTimestampsForNew(now);
     oldService.setWsdl(wsdl);
     wsdl.setService(oldService);
     wsdlRepository.save(wsdl);
   } else {
     if (oldWsdl.getStatusInfo().isRemoved()) {
       // resurrect
       oldWsdl.setData(wsdl.getData());
       oldWsdl.getStatusInfo().setChanged(now);
       oldWsdl.getStatusInfo().setRemoved(null);
       oldWsdl.getStatusInfo().setFetched(now);
     } else {
       // update existing
       boolean wsdlChanged = !oldWsdl.getData().equals(wsdl.getData());
       if (wsdlChanged) {
         oldWsdl.getStatusInfo().setChanged(now);
         oldWsdl.setData(wsdl.getData());
       }
       oldWsdl.getStatusInfo().setFetched(now);
     }
   }
 }
  @Override
  public void saveServices(SubsystemId subsystemId, Collection<Service> services) {
    assert subsystemId != null;
    Subsystem oldSubsystem =
        subsystemRepository.findActiveByNaturalKey(
            subsystemId.getXRoadInstance(),
            subsystemId.getMemberClass(),
            subsystemId.getMemberCode(),
            subsystemId.getSubsystemCode());
    if (oldSubsystem == null) {
      throw new IllegalStateException("subsystem " + subsystemId + " not found!");
    }

    LocalDateTime now = LocalDateTime.now();

    Map<ServiceId, Service> unprocessedOldServices = new HashMap<>();
    oldSubsystem
        .getAllServices()
        .stream()
        .forEach(s -> unprocessedOldServices.put(s.createKey(), s));

    for (Service service : services) {
      Service oldService = unprocessedOldServices.get(service.createKey());
      if (oldService == null) {
        // brand new item, add it
        service.getStatusInfo().setTimestampsForNew(now);
        service.setSubsystem(oldSubsystem);
        oldSubsystem.getAllServices().add(service);
      } else {
        oldService.getStatusInfo().setTimestampsForFetched(now);
      }
      unprocessedOldServices.remove(service.createKey());
    }

    // now unprocessedOldServices should all be removed (either already removed, or will be now)
    for (Service oldToRemove : unprocessedOldServices.values()) {
      StatusInfo status = oldToRemove.getStatusInfo();
      if (!status.isRemoved()) {
        status.setTimestampsForRemoved(now);
      }
    }
  }