// Path: microservices-dashboard-server-core/src/main/java/be/ordina/msdashboard/catalog/Catalog.java
// public class Catalog {
// 
// 	private Set<String> applications = new HashSet<>();
// 	private Map<String, List<String>> applicationInstances = new HashMap<>();
// 
// 	Catalog() {
// 	}
// 
// 	public List<String> getApplications() {
// 		return new ArrayList<>(this.applications);
// 	}
// 
// 	void addApplication(String application) {
// 		this.applications.add(application);
// 	}
// 
// 	void removeApplication(String application) {
// 		this.applications.remove(application);
// 	}
// 
// 	void addApplicationInstance(ApplicationInstance applicationInstance) {
// 		this.addApplication(applicationInstance.getApplication());
// 		List<String> instances = this.applicationInstances.getOrDefault(applicationInstance.getApplication(), new ArrayList<>());
// 		instances.add(applicationInstance.getId());
// 		this.applicationInstances.put(applicationInstance.getApplication(), instances);
// 	}
// 
// 	void removeApplicationInstance(ApplicationInstance applicationInstance) {
// 		List<String> instances = this.applicationInstances.getOrDefault(applicationInstance.getApplication(), new ArrayList<>());
// 		instances.remove(applicationInstance.getId());
// 		this.applicationInstances.put(applicationInstance.getApplication(), instances);
// 	}
// 
// 	List<String> getApplicationInstances() {
// 		return this.applicationInstances.values().stream()
// 				.flatMap(List::stream)
// 				.collect(toList());
// 	}
// 
// 	public List<String> getApplicationInstancesForApplication(String application) {
// 		return this.applicationInstances.getOrDefault(application, new ArrayList<>());
// 	}
// }
// 
// Path: microservices-dashboard-server-core/src/main/java/be/ordina/msdashboard/catalog/CatalogService.java
// public class CatalogService {
// 
// 	private final Catalog catalog;
// 
// 	public CatalogService() {
// 		this.catalog = new Catalog();
// 	}
// 
// 	public Catalog getCatalog() {
// 		return this.catalog;
// 	}
// 
// 	public void addApplicationToCatalog(String application) {
// 		this.catalog.addApplication(application);
// 	}
// 
// 	public void removeApplicationFromCatalog(String application) {
// 		this.catalog.removeApplication(application);
// 	}
// 
// 	public void addApplicationInstanceToCatalog(ApplicationInstance applicationInstance) {
// 		this.catalog.addApplicationInstance(applicationInstance);
// 	}
// 	public void removeApplicationInstanceFromCatalog(ApplicationInstance applicationInstance) {
// 		this.catalog.removeApplicationInstance(applicationInstance);
// 	}
// }
// 
// Path: microservices-dashboard-server-core/src/main/java/be/ordina/msdashboard/discovery/events/ServiceDisappeared.java
// public class ServiceDisappeared extends ApplicationEvent {
// 
// 	public ServiceDisappeared(String service) {
// 		super(service);
// 	}
// 
// 	public String getService() {
// 		return (String) this.source;
// 	}
// 
// }
// 
// Path: microservices-dashboard-server-core/src/main/java/be/ordina/msdashboard/discovery/events/ServiceDiscovered.java
// public class ServiceDiscovered extends ApplicationEvent {
// 
// 	public ServiceDiscovered(String application) {
// 		super(application);
// 	}
// 
// 	public String getService() {
// 		return (String) this.source;
// 	}
// 
// }
// 
// Path: microservices-dashboard-server-core/src/main/java/be/ordina/msdashboard/discovery/events/ServiceInstanceDisappeared.java
// public class ServiceInstanceDisappeared extends ApplicationEvent {
// 
// 	public ServiceInstanceDisappeared(String serviceInstanceId) {
// 		super(serviceInstanceId);
// 	}
// 
// 	public String getServiceInstanceId() {
// 		return (String) this.source;
// 	}
// 
// }
// 
// Path: microservices-dashboard-server-core/src/main/java/be/ordina/msdashboard/discovery/events/ServiceInstanceDiscovered.java
// public class ServiceInstanceDiscovered extends ApplicationEvent {
// 
// 	public ServiceInstanceDiscovered(ServiceInstance serviceInstance) {
// 		super(serviceInstance);
// 	}
// 
// 	public ServiceInstance getServiceInstance() {
// 		return (ServiceInstance) this.source;
// 	}
// 
// }


import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.event.EventListener;
import static org.apache.commons.collections4.CollectionUtils.subtract;
import java.util.List;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import be.ordina.msdashboard.catalog.Catalog;
import be.ordina.msdashboard.catalog.CatalogService;
import be.ordina.msdashboard.discovery.events.ServiceDisappeared;
import be.ordina.msdashboard.discovery.events.ServiceDiscovered;
import be.ordina.msdashboard.discovery.events.ServiceInstanceDisappeared;
import be.ordina.msdashboard.discovery.events.ServiceInstanceDiscovered;
import org.springframework.cloud.client.ServiceInstance;
	public void discoverLandscape() {
		logger.debug("Discovering landscape");

		List<String> applications = this.discoveryClient.getServices()
				.stream()
				.filter(this.applicationFilters)
				.collect(Collectors.toList());

		Catalog catalog = this.catalogService.getCatalog();
		dispatchEventForDiscoveredApplications(applications, catalog);
		dispatchEventForDisappearedApplications(applications, catalog);

		applications.forEach(this::processApplication);
	}

	private void dispatchEventForDiscoveredApplications(List<String> applications, Catalog catalog) {
		subtract(applications, catalog.getApplications())
				.stream()
				.map(ServiceDiscovered::new)
				.forEach(this.publisher::publishEvent);
	}

	private void dispatchEventForDisappearedApplications(List<String> applications, Catalog catalog) {
		subtract(catalog.getApplications(), applications)
				.stream()
				.map(ServiceDisappeared::new)
				.forEach(this.publisher::publishEvent);
	}

	private void processApplication(String application) {
// Path: microservices-dashboard-server-core/src/main/java/be/ordina/msdashboard/catalog/Catalog.java
// public class Catalog {
// 
// 	private Set<String> applications = new HashSet<>();
// 	private Map<String, List<String>> applicationInstances = new HashMap<>();
// 
// 	Catalog() {
// 	}
// 
// 	public List<String> getApplications() {
// 		return new ArrayList<>(this.applications);
// 	}
// 
// 	void addApplication(String application) {
// 		this.applications.add(application);
// 	}
// 
// 	void removeApplication(String application) {
// 		this.applications.remove(application);
// 	}
// 
// 	void addApplicationInstance(ApplicationInstance applicationInstance) {
// 		this.addApplication(applicationInstance.getApplication());
// 		List<String> instances = this.applicationInstances.getOrDefault(applicationInstance.getApplication(), new ArrayList<>());
// 		instances.add(applicationInstance.getId());
// 		this.applicationInstances.put(applicationInstance.getApplication(), instances);
// 	}
// 
// 	void removeApplicationInstance(ApplicationInstance applicationInstance) {
// 		List<String> instances = this.applicationInstances.getOrDefault(applicationInstance.getApplication(), new ArrayList<>());
// 		instances.remove(applicationInstance.getId());
// 		this.applicationInstances.put(applicationInstance.getApplication(), instances);
// 	}
// 
// 	List<String> getApplicationInstances() {
// 		return this.applicationInstances.values().stream()
// 				.flatMap(List::stream)
// 				.collect(toList());
// 	}
// 
// 	public List<String> getApplicationInstancesForApplication(String application) {
// 		return this.applicationInstances.getOrDefault(application, new ArrayList<>());
// 	}
// }
// 
// Path: microservices-dashboard-server-core/src/main/java/be/ordina/msdashboard/catalog/CatalogService.java
// public class CatalogService {
// 
// 	private final Catalog catalog;
// 
// 	public CatalogService() {
// 		this.catalog = new Catalog();
// 	}
// 
// 	public Catalog getCatalog() {
// 		return this.catalog;
// 	}
// 
// 	public void addApplicationToCatalog(String application) {
// 		this.catalog.addApplication(application);
// 	}
// 
// 	public void removeApplicationFromCatalog(String application) {
// 		this.catalog.removeApplication(application);
// 	}
// 
// 	public void addApplicationInstanceToCatalog(ApplicationInstance applicationInstance) {
// 		this.catalog.addApplicationInstance(applicationInstance);
// 	}
// 	public void removeApplicationInstanceFromCatalog(ApplicationInstance applicationInstance) {
// 		this.catalog.removeApplicationInstance(applicationInstance);
// 	}
// }
// 
// Path: microservices-dashboard-server-core/src/main/java/be/ordina/msdashboard/discovery/events/ServiceDisappeared.java
// public class ServiceDisappeared extends ApplicationEvent {
// 
// 	public ServiceDisappeared(String service) {
// 		super(service);
// 	}
// 
// 	public String getService() {
// 		return (String) this.source;
// 	}
// 
// }
// 
// Path: microservices-dashboard-server-core/src/main/java/be/ordina/msdashboard/discovery/events/ServiceDiscovered.java
// public class ServiceDiscovered extends ApplicationEvent {
// 
// 	public ServiceDiscovered(String application) {
// 		super(application);
// 	}
// 
// 	public String getService() {
// 		return (String) this.source;
// 	}
// 
// }
// 
// Path: microservices-dashboard-server-core/src/main/java/be/ordina/msdashboard/discovery/events/ServiceInstanceDisappeared.java
// public class ServiceInstanceDisappeared extends ApplicationEvent {
// 
// 	public ServiceInstanceDisappeared(String serviceInstanceId) {
// 		super(serviceInstanceId);
// 	}
// 
// 	public String getServiceInstanceId() {
// 		return (String) this.source;
// 	}
// 
// }
// 
// Path: microservices-dashboard-server-core/src/main/java/be/ordina/msdashboard/discovery/events/ServiceInstanceDiscovered.java
// public class ServiceInstanceDiscovered extends ApplicationEvent {
// 
// 	public ServiceInstanceDiscovered(ServiceInstance serviceInstance) {
// 		super(serviceInstance);
// 	}
// 
// 	public ServiceInstance getServiceInstance() {
// 		return (ServiceInstance) this.source;
// 	}
// 
// }


// Path: microservices-dashboard-server-core/src/main/java/be/ordina/msdashboard/discovery/LandscapeWatcher.java
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.event.EventListener;
import static org.apache.commons.collections4.CollectionUtils.subtract;
import java.util.List;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import be.ordina.msdashboard.catalog.Catalog;
import be.ordina.msdashboard.catalog.CatalogService;
import be.ordina.msdashboard.discovery.events.ServiceDisappeared;
import be.ordina.msdashboard.discovery.events.ServiceDiscovered;
import be.ordina.msdashboard.discovery.events.ServiceInstanceDisappeared;
import be.ordina.msdashboard.discovery.events.ServiceInstanceDiscovered;
import org.springframework.cloud.client.ServiceInstance;

	public void discoverLandscape() {
		logger.debug("Discovering landscape");

		List<String> applications = this.discoveryClient.getServices()
				.stream()
				.filter(this.applicationFilters)
				.collect(Collectors.toList());

		Catalog catalog = this.catalogService.getCatalog();
		dispatchEventForDiscoveredApplications(applications, catalog);
		dispatchEventForDisappearedApplications(applications, catalog);

		applications.forEach(this::processApplication);
	}

	private void dispatchEventForDiscoveredApplications(List<String> applications, Catalog catalog) {
		subtract(applications, catalog.getApplications())
				.stream()
				.map(ServiceDiscovered::new)
				.forEach(this.publisher::publishEvent);
	}

	private void dispatchEventForDisappearedApplications(List<String> applications, Catalog catalog) {
		subtract(catalog.getApplications(), applications)
				.stream()
				.map(ServiceDisappeared::new)
				.forEach(this.publisher::publishEvent);
	}

	private void processApplication(String application) {
		logger.debug("Processing application {}", application);