class LocationService {

    public synchronized void removeLocation(long id) {
        Optional<Location> optionalLocation = repository.find(id);
        if (!optionalLocation.isPresent()) {
            eventPublisher.publishEvent(
                    new ErrorEvent(this, "Location [" + id + "] cannot be removed because it doesn't exist."));
            return;
        }
        Location removedLocation = optionalLocation.get();
        List<Location> locations = repository.locations();
        if (locations.size() > 1) {
            Location depot = locations.stream()
                    .min(comparingLong(Location::id))
                    .orElseThrow(() -> new IllegalStateException(
                            "Impossible. Locations have size (" + locations.size() + ") but the stream is empty."));
            if (removedLocation.equals(depot)) {
                eventPublisher.publishEvent(
                        new ErrorEvent(this, "You can only remove depot if there are no visits."));
                return;
            }
        }

        optimizer.removeLocation(removedLocation);
        repository.removeLocation(id);
        distanceMatrix.removeLocation(removedLocation);
    }

    @Autowired  LocationService(
            LocationRepository repository,
            RouteOptimizer optimizer,
            DistanceMatrix distanceMatrix,
            ApplicationEventPublisher eventPublisher);

}