ARIES-1941 Addressed synchronization inconsistency in (using) MultiMap (#31)

* ARIES-1941 Addressed synchronization inconsistency in (using) MultiMap

Changed the approach to MultiMap to have all public method thread-safe: using synchronized keyword *and* returning read-only *copies* when a Set is to be returned
Changed the one case where a defensive copy was made. Note that this old approach was not thread-safe, as the copy-constructors' iterator could be 'tripped' by a concurrent modification.

* With the change to regular HashMap, a defensive copy of keySet is needed.
diff --git a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/MultiMap.java b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/MultiMap.java
index eac5f40..b0f8dbe 100644
--- a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/MultiMap.java
+++ b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/MultiMap.java
@@ -19,10 +19,10 @@
 package org.apache.aries.rsa.topologymanager.importer;
 
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Map;
+import java.util.Map;;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Minimal implementation of a synchronized map
@@ -32,7 +32,7 @@
     private Map<String, Set<T>> map;
     
     public MultiMap() {
-        map = new ConcurrentHashMap<>();
+        map = new HashMap<>();
     }
     
     public synchronized void put(String key, T value) {
@@ -45,7 +45,11 @@
     }
     
     public synchronized Set<T> get(String key) {
-        return map.getOrDefault(key, Collections.<T>emptySet());
+        if (map.containsKey(key)) {
+            return Collections.unmodifiableSet(new HashSet<>(map.get(key)));
+        } else {
+            return Collections.<T>emptySet();
+        }
     }
 
     public synchronized void remove(String key, T value) {
@@ -57,12 +61,11 @@
     }
 
     public synchronized Set<String> keySet() {
-        return map.keySet();
+        return Collections.unmodifiableSet(new HashSet<>(map.keySet()));
     }
 
-    public void remove(T toRemove) {
-        Set<String> keys = new HashSet<>(map.keySet());
-        for (String key : keys) {
+    public synchronized void remove(T toRemove) {
+        for (String key : map.keySet()) {
             remove(key, toRemove);
         }
     }
diff --git a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/TopologyManagerImport.java b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/TopologyManagerImport.java
index cbe8d5e..43c0bd5 100644
--- a/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/TopologyManagerImport.java
+++ b/topology-manager/src/main/java/org/apache/aries/rsa/topologymanager/importer/TopologyManagerImport.java
@@ -176,7 +176,7 @@
     }
 
     private void unImportForGoneEndpoints(String filter) {
-        Set<ImportRegistration> importRegistrations = new HashSet<>(importedServices.get(filter));
+        Set<ImportRegistration> importRegistrations = importedServices.get(filter);
         Set<EndpointDescription> endpoints = importPossibilities.get(filter);
         for (ImportRegistration ir : importRegistrations) {
             EndpointDescription endpoint = ir.getImportReference().getImportedEndpoint();