private void fillMaps() {
        Map<HostName, ApplicationInstance> applicationInstances = new HashMap<>();
        Map<HostName, List<ServiceInstance>> serviceInstances = new HashMap<>();

        for (ApplicationInstance application : applicationsByReference.values()) {
            for (ServiceCluster cluster : application.serviceClusters()) {
                for (ServiceInstance instance : cluster.serviceInstances()) {

                    ApplicationInstance previous = applicationInstances.put(instance.hostName(), application);
                    if (previous != null && !previous.equals(application)) {
                        throw new IllegalStateException("Major assumption broken: Multiple application instances contain host " +
                                instance.hostName().s() + ": " + List.of(previous, application));
                    }

                    serviceInstances
                            .computeIfAbsent(instance.hostName(), key -> new ArrayList<>())
                            .add(instance);
                }
            }
        }

        applicationsByHostName = Collections.unmodifiableMap(applicationInstances);
        servicesByHostName = Collections.unmodifiableMap(serviceInstances);
    }
The service model is the union of the duper model and the service monitor, and presented
as classes from the {@code application-model} module.

<p>The duper model contains the latest {@link ApplicationInfo} of both tenant and infrastructure
applications. The service monitor provides Slobrok or {@code /state/v1/health} information
on (most) services. The application model presents an application as a set of clusters, and
each cluster a set of services, and each service is associated with a particular host
and has a health status.</p>

@author hakonhall
service-monitor/src/main/java/com/yahoo/vespa/service/monitor/ServiceModel.java