Improves config system + bug fixes

Change-Id: I83b9d9174ab41776bd0061912240de824d7dfde0
diff --git a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainConfigService.java b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainConfigService.java
new file mode 100644
index 0000000..81057a4
--- /dev/null
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainConfigService.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.icona.domainmgr.api;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Link;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *  Domain configuration interface.
+ *  Currently, the whole configuration is passed to ICONA through
+ *  the network configuration subsystem. Cli commands with related
+ *  setter methods will be added in the near future.
+ */
+public interface DomainConfigService {
+
+    /**
+     * Returns the local domain ID.
+     * @return domain ID
+     */
+    DomainId localDomainId();
+
+    /**
+     * Returns the set of configured domain IDs.
+     * @return set of domain IDs
+     */
+    Set<DomainId> remoteDomainIds();
+
+    /**
+     * Returns the map between an interlink ID and a description
+     * of type and physical connect point where the link is attached to.
+     *
+     * @return a map between interlink ID and a pair of type and port of the link
+     */
+    Map<LinkId, Pair<Link.Type, ConnectPoint>> interlinkConnectPointMap();
+}
+
diff --git a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainService.java b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainService.java
index 4ccaf6a..6f3597a 100644
--- a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainService.java
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainService.java
@@ -17,12 +17,15 @@
 package org.onosproject.icona.domainmgr.api;
 
 import org.apache.commons.lang3.tuple.Pair;
-import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
+import org.onosproject.net.Device;
 import org.onosproject.net.HostId;
+import org.onosproject.net.Host;
 import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.ConnectPoint;
 
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -90,4 +93,19 @@
      * @return set of intra-domain link
      */
     Set<Link> getIntraLinks(DomainId domainId);
+
+    /**
+     * Gets from the distributed store the mapping between the port numbers
+     * of the specified device exposed to a peer domain and the local connect points.
+     * @param deviceId device identifier
+     * @return map between virtual ports and physical hosts
+     */
+    Map<PortNumber, ConnectPoint> getVirtualPortToPortMapping(DeviceId deviceId);
+
+    /**
+     * Adds a new mapping between virtual ports and local connect point for
+     * a specified domain device.
+     * @param deviceId identifier of the domain device
+     */
+    void setVirtualPortToPortMapping(DeviceId deviceId, Map<PortNumber, ConnectPoint> map);
 }
diff --git a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainStore.java b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainStore.java
index 4501731..6374430 100644
--- a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainStore.java
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainStore.java
@@ -20,8 +20,11 @@
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.HostId;
 import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.ConnectPoint;
 import org.onosproject.store.Store;
 
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -111,4 +114,19 @@
      * @param link link object
      */
     void removeInterLink(Pair<DomainId, DomainId> endDomains, Link link);
+
+    /**
+     * Returns the mapping between the port numbers
+     * of the specified device exposed to a peer and the physical ports.
+     * @param deviceId device identifier of the local virtual device exposed to a peer
+     * @return the mapping between the ports seen by the other domain and a local host
+     */
+    Map<PortNumber, ConnectPoint> getVirtualPortToPortMapping(DeviceId deviceId);
+
+    /**
+     * Adds a new mapping between virtual and physical ports
+     * exposed to other domains.
+     * @param deviceId identifier of the domain device
+     */
+    void setVirtualPortToPortMapping(DeviceId deviceId, Map<PortNumber, ConnectPoint> virtualPortToPortMap);
 }
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/LinkId.java b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/LinkId.java
similarity index 93%
rename from icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/LinkId.java
rename to icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/LinkId.java
index 575d50d..37dc510 100644
--- a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/LinkId.java
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/LinkId.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.icona.domainprovider.api.link;
+package org.onosproject.icona.domainmgr.api;
 
 import org.onlab.util.Identifier;
 
diff --git a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/package-info.java b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/package-info.java
index 32e1199..16c0b74 100644
--- a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/package-info.java
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/package-info.java
@@ -15,6 +15,6 @@
  */
 
 /**
- * Icona manager APIs.
+ * ICONA store and service manager APIs.
  */
 package org.onosproject.icona.domainmgr.api;
\ No newline at end of file
diff --git a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/DistributedDomainStore.java b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/DistributedDomainStore.java
index 4c28802..4ff3557 100644
--- a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/DistributedDomainStore.java
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/DistributedDomainStore.java
@@ -16,13 +16,16 @@
 
 package org.onosproject.icona.domainmgr.impl;
 
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
+import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Reference;
 import org.onlab.util.Identifier;
 import org.onlab.util.KryoNamespace;
 import org.onosproject.icona.domainmgr.api.DomainId;
@@ -31,7 +34,9 @@
 import org.onosproject.icona.domainmgr.api.DomainStoreDelegate;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.HostId;
+import org.onosproject.net.PortNumber;
 import org.onosproject.net.Link;
+import org.onosproject.net.ConnectPoint;
 import org.onosproject.store.AbstractStore;
 import org.onosproject.store.serializers.KryoNamespaces;
 import org.onosproject.store.service.StorageService;
@@ -58,6 +63,8 @@
 /**
  * Distributed domain store implementation.
  */
+@Component(immediate = true)
+@Service
 public class DistributedDomainStore extends AbstractStore<DomainEvent, DomainStoreDelegate>
         implements DomainStore {
 
@@ -78,10 +85,14 @@
     private ConsistentMap<Pair<DomainId, DomainId>, Set<Link>> domainIdLinkSetConsistentMap;
     private Map<Pair<DomainId, DomainId>, Set<Link>> domainIdLinkSetMap;
 
+    private ConsistentMap<DeviceId, Map<PortNumber, ConnectPoint>> virtualPortToLocalHostConsistentMap;
+    private Map<DeviceId, Map<PortNumber, ConnectPoint>> virtualPortToLocalHostMap;
+
     private static final Serializer SERIALIZER = Serializer
             .using(new KryoNamespace.Builder().register(KryoNamespaces.API)
                     .register(Identifier.class)
                     .register(DomainId.class)
+                    .register(ImmutablePair.class)
                     .build());
 
     @Activate
@@ -117,6 +128,14 @@
                 .build();
         domainIdLinkSetMap = domainIdLinkSetConsistentMap.asJavaMap();
 
+        virtualPortToLocalHostConsistentMap = storageService
+                .<DeviceId, Map<PortNumber, ConnectPoint>>consistentMapBuilder()
+                .withSerializer(SERIALIZER)
+                .withName("onos-virtual-port-host-mapping")
+                .withRelaxedReadConsistency()
+                .build();
+        virtualPortToLocalHostMap = virtualPortToLocalHostConsistentMap.asJavaMap();
+
         log.info("Started");
 
     }
@@ -155,7 +174,7 @@
         checkState(domainExists(domainId), "Domain id unknown");
         domainIdDeviceIdsMap.compute(domainId, (k, set) -> {
             if (set == null) {
-               set = Sets.newConcurrentHashSet();
+               set = new HashSet<>();
             }
             set.add(deviceId);
             return set;
@@ -186,7 +205,7 @@
         checkState(domainExists(domainId), "Domain id unknown");
         domainIdHostIdsMap.compute(domainId, (k, set) -> {
             if (set == null) {
-                set = Sets.newConcurrentHashSet();
+                set = new HashSet<>();
             }
             set.add(hostId);
             return set;
@@ -219,7 +238,7 @@
         checkState(domainExists(endDomains.getRight()), "Domain id unknown");
         domainIdLinkSetMap.compute(endDomains, (k, set) -> {
            if (set == null) {
-               set = Sets.newConcurrentHashSet();
+               set = new HashSet<>();
            }
            set.add(link);
             return set;
@@ -240,6 +259,16 @@
         });
     }
 
+    @Override
+    public void setVirtualPortToPortMapping(DeviceId deviceId, Map<PortNumber, ConnectPoint> map) {
+        virtualPortToLocalHostMap.put(deviceId, map);
+    }
+
+    @Override
+    public Map<PortNumber, ConnectPoint> getVirtualPortToPortMapping(DeviceId deviceId) {
+        return ImmutableMap.copyOf(virtualPortToLocalHostMap.get(deviceId));
+    }
+
     private void clear(DomainId domainId) {
         Set<Pair<DomainId, DomainId>> domainPairs = new HashSet<>();
         // find all domains connected with the one to be removed and remove related links
diff --git a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/DomainConfigManager.java b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/DomainConfigManager.java
new file mode 100644
index 0000000..a114960
--- /dev/null
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/DomainConfigManager.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.icona.domainmgr.impl;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Reference;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.icona.domainmgr.api.DomainConfigService;
+import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.icona.domainmgr.api.DomainService;
+import org.onosproject.icona.domainmgr.api.LinkId;
+import org.onosproject.icona.domainmgr.impl.config.DomainConfig;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.basics.SubjectFactories;
+import org.slf4j.Logger;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static org.onosproject.net.Link.Type;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation class of {@link org.onosproject.icona.domainmgr.api.DomainConfigService}.
+ */
+@Component(immediate = true)
+@Service
+public class DomainConfigManager implements DomainConfigService {
+
+    private static final String APP_NAME = "org.onosproject.icona.domainmgr";
+    private static DomainId localDomainId;
+    private final Logger log = getLogger(getClass());
+    private ApplicationId appId;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry configRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService configService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DomainService domainService;
+
+    private ExecutorService eventExecutor = Executors.newSingleThreadExecutor();
+
+    private final NetworkConfigListener configListener = new InternalConfigListener();
+
+    private final ConfigFactory configFactory =
+            new ConfigFactory(SubjectFactories.APP_SUBJECT_FACTORY, DomainConfig.class, "domains") {
+                @Override
+                public DomainConfig createConfig() {
+                    return new DomainConfig();
+                }
+            };
+
+    private Set<DomainId> remoteDomainIds = Sets.newConcurrentHashSet();
+
+    private Map<LinkId, Pair<Type, ConnectPoint>> interlinkConnectPointMap;
+
+    @Activate
+    public void activate() {
+        appId = coreService.getAppId(APP_NAME);
+        configRegistry.registerConfigFactory(configFactory);
+        configService.addListener(configListener);
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        configService.removeListener(configListener);
+        configRegistry.unregisterConfigFactory(configFactory);
+        log.info("Stopped");
+    }
+
+    @Override
+    public DomainId localDomainId() {
+        return localDomainId;
+    }
+
+    @Override
+    public Set<DomainId> remoteDomainIds() {
+        return ImmutableSet.copyOf(remoteDomainIds);
+    }
+
+    @Override
+    public Map<LinkId, Pair<Type, ConnectPoint>> interlinkConnectPointMap() {
+        return ImmutableMap.copyOf(interlinkConnectPointMap);
+    }
+
+
+
+    private void readConfig() {
+        log.debug("Config received");
+        DomainConfig config = configRegistry.getConfig(appId, DomainConfig.class);
+        localDomainId = config.getLocalId();
+        domainService.registerDomainId(localDomainId);
+        remoteDomainIds.addAll(config.remoteDomainIds());
+        interlinkConnectPointMap = config.interlinkMap();
+        remoteDomainIds.forEach(domainId -> domainService.registerDomainId(domainId));
+    }
+
+    private class InternalConfigListener implements NetworkConfigListener {
+        @Override
+        public void event(NetworkConfigEvent event) {
+            if (!event.configClass().equals(DomainConfig.class)) {
+                return;
+            }
+            log.debug("Listener called: {}", event.type());
+            switch (event.type()) {
+                case CONFIG_ADDED:
+                    log.info("Network configuration added");
+                    eventExecutor.execute(DomainConfigManager.this::readConfig);
+                    break;
+                case CONFIG_UPDATED:
+                    log.info("Network configuration updated");
+                    eventExecutor.execute(DomainConfigManager.this::readConfig);
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+}
diff --git a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/DomainManager.java b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/DomainManager.java
index e554f59..4b6682b 100644
--- a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/DomainManager.java
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/DomainManager.java
@@ -31,11 +31,13 @@
 import org.onosproject.icona.domainmgr.api.DomainStore;
 import org.onosproject.icona.domainmgr.api.DomainStoreDelegate;
 import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Device;
 import org.onosproject.net.HostId;
 import org.onosproject.net.Host;
-import org.onosproject.net.DeviceId;
 import org.onosproject.net.Link;
-import org.onosproject.net.Device;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.device.DeviceEvent;
 import org.onosproject.net.device.DeviceListener;
 import org.onosproject.net.device.DeviceService;
@@ -49,6 +51,7 @@
 import org.slf4j.LoggerFactory;
 
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 
 import static com.google.common.base.Preconditions.checkNotNull;
@@ -173,6 +176,16 @@
         return ImmutableSet.copyOf(intralinks);
     }
 
+    @Override
+    public Map<PortNumber, ConnectPoint> getVirtualPortToPortMapping(DeviceId deviceId) {
+        return domainStore.getVirtualPortToPortMapping(deviceId);
+    }
+
+    @Override
+    public void setVirtualPortToPortMapping(DeviceId deviceId, Map<PortNumber, ConnectPoint> map) {
+        domainStore.setVirtualPortToPortMapping(deviceId, map);
+    }
+
     private class InternalDeviceListener implements DeviceListener {
         @Override
         public void event(DeviceEvent event) {
diff --git a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/config/DomainConfig.java b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/config/DomainConfig.java
new file mode 100644
index 0000000..4364ec0
--- /dev/null
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/config/DomainConfig.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.icona.domainmgr.impl.config;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.apache.commons.lang3.tuple.Pair;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.icona.domainmgr.api.LinkId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.Config;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import static org.onosproject.net.Link.Type.*;
+import static org.onosproject.net.Link.Type.INDIRECT;
+
+/**
+ * Configuration class for domain identifiers.
+ * Look at tools/sample_configs/icona-config.json
+ * for a sample configuration
+ */
+public class DomainConfig extends Config<ApplicationId> {
+
+    private static final String DOMAIN_ID = "domainId";
+    private static final String LOCAL_DOMAIN = "localDomain";
+    private static final String REMOTE_DOMAINS = "remoteDomains";
+    private static final String INTER_LINK_PORTS = "interlinkPorts";
+    private static final String DEVICE_ID = "deviceId";
+    private static final String PORT_NUMBER = "portNumber";
+    private static final String LINK_ID = "id";
+    private static final String LINK_TYPE = "type";
+
+    /**
+     * Gets local domain identifier from configuration.
+     * @return string identifier
+     */
+    public DomainId getLocalId() {
+        return DomainId.domainId(object.get(LOCAL_DOMAIN).asText());
+    }
+
+    /**
+     * Gets the remote domain identifiers.
+     * @return set of domain IDs
+     */
+    public Set<DomainId> remoteDomainIds() {
+        Set<DomainId> remoteDomainIds = Sets.newConcurrentHashSet();
+        object.path(REMOTE_DOMAINS).forEach(domainElem -> remoteDomainIds.add(
+                new DomainId(domainElem.path(DOMAIN_ID).asText())
+        ));
+        return ImmutableSet.copyOf(remoteDomainIds);
+    }
+
+    public Map<LinkId, Pair<Link.Type, ConnectPoint>> interlinkMap() {
+        Map<LinkId, Pair<Link.Type, ConnectPoint>> map = new HashMap<>();
+
+        JsonNode domainElems = object.path(REMOTE_DOMAINS);
+        // for each domain
+        domainElems.forEach(domainElem -> {
+            JsonNode interlinksJson = domainElem.path(INTER_LINK_PORTS);
+
+            // for each interlink of a single domain
+            interlinksJson.forEach(interlinkJson -> {
+                LinkId linkId = LinkId.linkId(interlinkJson.path(LINK_ID).asText());
+                DeviceId deviceId = DeviceId.deviceId(interlinkJson.path(DEVICE_ID).asText());
+                PortNumber portNumber = PortNumber.fromString(interlinkJson.path(PORT_NUMBER).asText());
+                String type = interlinkJson.path(LINK_TYPE).asText();
+                Link.Type ilType;
+                switch (type) {
+                    case "virtual":
+                        ilType = VIRTUAL;
+                        break;
+                    case "optical":
+                        ilType = OPTICAL;
+                        break;
+                    case "tunnel":
+                        ilType = TUNNEL;
+                        break;
+                    case "direct":
+                        ilType = DIRECT;
+                        break;
+                    default:
+                        ilType = INDIRECT;
+
+                }
+                map.put(linkId, Pair.of(ilType, new ConnectPoint(deviceId, portNumber)));
+            });
+        });
+
+        return map;
+    }
+}
+
diff --git a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/config/package-info.java b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/config/package-info.java
new file mode 100644
index 0000000..0d81b76
--- /dev/null
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/config/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Domain system configuration package.
+ */
+package org.onosproject.icona.domainmgr.impl.config;
\ No newline at end of file
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/PeerState.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/flow/package-info.java
similarity index 80%
rename from icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/PeerState.java
rename to icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/flow/package-info.java
index 75f1bdf..6ffc368 100644
--- a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/PeerState.java
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/flow/package-info.java
@@ -14,14 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.icona.domainprovider.api;
-
 /**
- * State of a session with a remote domain.
+ * Flow rule provisioning APIs.
  */
-public enum PeerState {
-
-    UP,
-    DOWN,
-    UNKNOWN
-}
+package org.onosproject.icona.domainprovider.api.flow;
\ No newline at end of file
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/DefaultInterLinkDescription.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/DefaultInterLinkDescription.java
index 8eac6f5..3f5456f 100644
--- a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/DefaultInterLinkDescription.java
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/DefaultInterLinkDescription.java
@@ -18,6 +18,7 @@
 
 import org.apache.commons.lang3.tuple.Pair;
 import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.icona.domainmgr.api.LinkId;
 import org.onosproject.net.SparseAnnotations;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.link.DefaultLinkDescription;
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/IconaSBLinkListener.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/IconaSBLinkListener.java
index 61b56ad..f51daed 100644
--- a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/IconaSBLinkListener.java
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/IconaSBLinkListener.java
@@ -17,6 +17,7 @@
 package org.onosproject.icona.domainprovider.api.link;
 
 import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.icona.domainmgr.api.LinkId;
 
 import static org.onosproject.net.Link.State;
 
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/IconaSBLinkService.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/IconaSBLinkService.java
index 68470c0..3191413 100644
--- a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/IconaSBLinkService.java
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/IconaSBLinkService.java
@@ -17,6 +17,7 @@
 package org.onosproject.icona.domainprovider.api.link;
 
 import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.icona.domainmgr.api.LinkId;
 
 import static org.onosproject.net.Link.State;
 
@@ -35,10 +36,9 @@
     /**
      * Signals the domain provider to add an interlink between this and a remote domain.
      *
-     * @param domainId remote domain identifier
      * @param link link to be added
      */
-    void addInterLink(DomainId domainId, InterLinkDescription link);
+    void addInterLink(InterLinkDescription link);
 
     /**
      * Signals the domain provider to change a remote link state.
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/InterLinkDescription.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/InterLinkDescription.java
index 4d620a5..21de42d 100644
--- a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/InterLinkDescription.java
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/InterLinkDescription.java
@@ -18,6 +18,7 @@
 
 import org.apache.commons.lang3.tuple.Pair;
 import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.icona.domainmgr.api.LinkId;
 import org.onosproject.net.link.LinkDescription;
 
 
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/config/IconaConfig.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/config/IconaConfig.java
index e9ee7f6..59a503e 100644
--- a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/config/IconaConfig.java
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/config/IconaConfig.java
@@ -17,64 +17,42 @@
 package org.onosproject.icona.domainprovider.impl.config;
 
 import com.fasterxml.jackson.databind.JsonNode;
-import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
-import org.apache.commons.lang3.tuple.Pair;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.icona.domainmgr.api.DomainId;
-import org.onosproject.icona.domainprovider.api.link.LinkId;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Link;
-import org.onosproject.net.PortNumber;
 import org.onosproject.net.config.Config;
 import org.slf4j.Logger;
 
 import java.util.ArrayList;
-import java.util.Map;
 import java.util.Set;
 
 import static org.onosproject.icona.domainprovider.impl.config.TopologyConfig.Type.BIG_SWITCH;
 import static org.onosproject.icona.domainprovider.impl.config.TopologyConfig.Type.FULL_MESH;
-import static org.onosproject.net.Link.Type.*;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
- *  Provider configuration class.
- *  Refer to tools/sample_configs/multidomain-config.json, under
- *  "org.onosproject.icona.domainprovider" for a sample configuration
+ *  Icona provider configuration class.
+ *  Look at tools/sample_configs/icona-provider-config.json
+ *  for a sample configuration
  */
 public class IconaConfig extends Config<ApplicationId> {
 
     private final Logger log = getLogger(getClass());
 
-    private static final String LOCAL_DOMAIN_ID = "localDomainId";
     private static final String BIG_SWITCH_PREFIX_ID = "bigSwitchPrefixId";
-    private static final String PEERS = "peers";
+    private static final String DRIVER = "driver";
+    private static final String MANUFACTURER = "manufacturer";
+    private static final String SW_VERSION = "swVersion";
+    private static final String HW_VERSION = "hwVersion";
+    private static final String DOMAINS = "domains";
     private static final String DOMAIN_ID = "domainId";
-
-    private static final String DOMAIN_INTER_LINKS = "interlinks";
-    private static final String INTER_LINK_DEVICE_ID = "deviceId";
-    private static final String INTER_LINK_DEVICE_PORTNUM = "portNumber";
-    private static final String INTER_LINK_ID = "interlinkId";
-    private static final String INTER_LINK_TYPE = "interlinkType";
-
-    private static final String TOPOLOGY = "topology";
+    private static final String TOPOLOGY_TYPE = "topologyType";
     private static final String END_POINTS = "endPointIds";
+    private static final String PORT_SPEED = "portSpeed";
 
     /**
-     * Gets local domain identifier from configuration.
-     *
-     * @return string identifier
-     */
-    public DomainId getLocalId() {
-        return DomainId.domainId(object.get(LOCAL_DOMAIN_ID).asText());
-    }
-
-    /**
-     * Gets the ID of the local big switch abstraction.
-     *
+     * Gets the id of the local big switch abstraction.
      * @return big switch identifier
      */
     public String getBigSwitchPrefixId() {
@@ -82,6 +60,27 @@
     }
 
     /**
+     * Gets port speed from configuration.
+     * @return port speed in mbps
+     */
+    // TODO: think a better way to handle this
+    public int portSpeed() {
+        return object.get(PORT_SPEED).asInt();
+    }
+
+    /**
+     * Returns the domain device driver config parameters.
+     * @return driver configuration object
+     */
+    public DriverConfig getDriverConfig() {
+        JsonNode driverJson = object.get(DRIVER);
+        String manufacturer = driverJson.get(MANUFACTURER).asText();
+        String swVersion = driverJson.get(SW_VERSION).asText();
+        String hwVersion = driverJson.get(HW_VERSION).asText();
+        return new DriverConfig(manufacturer, swVersion, hwVersion);
+    }
+
+    /**
      * Parses the list of peers from the configuration json object.
      *
      * @return set of domain configuration objects
@@ -90,53 +89,16 @@
 
         Set<DomainConfig> peers = Sets.newHashSet();
 
-        JsonNode peerNodes = object.get(PEERS);
+        JsonNode abstractionsNode = object.get(DOMAINS);
 
-        peerNodes.forEach(peerNode -> {
+        abstractionsNode.forEach(peerNode -> {
 
             String id = peerNode.path(DOMAIN_ID).asText();
 
             DomainId domainId = new DomainId(id);
 
-            JsonNode cpsNode = peerNode.path(DOMAIN_INTER_LINKS);
-
-            Map<LinkId, Pair<Link.Type, ConnectPoint>> interLinkConnectPointMap = Maps.newHashMap();
-
-            cpsNode.forEach(il -> {
-                // real internal deviceId where the inter-link is attached
-                DeviceId deviceId = DeviceId.deviceId(il.path(INTER_LINK_DEVICE_ID).asText());
-                // TODO: LinkDiscovery must be disabled for this port
-                PortNumber portNumber = PortNumber.portNumber(il.path(INTER_LINK_DEVICE_PORTNUM).asText());
-                String ilid = il.path(INTER_LINK_ID).asText();
-                String type = il.path(INTER_LINK_TYPE).asText();
-                Link.Type ilType;
-                switch (type) {
-                    case "indirect":
-                        ilType = INDIRECT;
-                        break;
-                    case "virtual":
-                        ilType = VIRTUAL;
-                        break;
-                    case "optical":
-                        ilType = OPTICAL;
-                        break;
-                    case "tunnel":
-                        ilType = TUNNEL;
-                        break;
-                    case "direct":
-                        ilType = DIRECT;
-                        break;
-                    default:
-                        ilType = INDIRECT;
-                }
-                interLinkConnectPointMap.put(LinkId.linkId(ilid),
-                        Pair.of(ilType, new ConnectPoint(deviceId, portNumber)));
-
-            });
-
-            JsonNode topologyNode = peerNode.path(TOPOLOGY);
             TopologyConfig.Type type;
-            switch (topologyNode.path("type")
+            switch (peerNode.path(TOPOLOGY_TYPE)
                     .asText()) {
                 case "bigSwitch":
                     type = BIG_SWITCH;
@@ -145,17 +107,16 @@
                     type = FULL_MESH;
                     break;
                 default:
-                    type = TopologyConfig.Type.BIG_SWITCH;
+                    type = BIG_SWITCH;
             }
             ArrayList<String> endPointIds = new ArrayList<>();
-            topologyNode.path(END_POINTS).forEach(
+            peerNode.path(END_POINTS).forEach(
                     endPointId -> endPointIds.add(endPointId.asText())
             );
             TopologyConfig topologyConfig = new TopologyConfig(type, endPointIds);
 
-            peers.add(new DomainConfig(domainId, interLinkConnectPointMap, topologyConfig));
+            peers.add(new DomainConfig(domainId, topologyConfig));
         });
-
         return peers;
     }
 
@@ -165,27 +126,46 @@
     public static class DomainConfig {
 
         private final DomainId domainId;
-        private final Map<LinkId, Pair<Link.Type, ConnectPoint>> interLinkConnectPointMap;
         private final TopologyConfig topologyConfig;
 
-        public DomainConfig(DomainId domainId, Map<LinkId, Pair<Link.Type, ConnectPoint>> interLinkConnectPointMap,
-                            TopologyConfig topologyConfig) {
+        public DomainConfig(DomainId domainId, TopologyConfig topologyConfig) {
             this.domainId = checkNotNull(domainId);
-            this.interLinkConnectPointMap = interLinkConnectPointMap;
             this.topologyConfig = topologyConfig;
         }
 
-        public DomainId peerId() {
+        public DomainId domainId() {
             return domainId;
         }
 
-        public Map<LinkId, Pair<Link.Type, ConnectPoint>> interLinkConnectPointMap() {
-            return interLinkConnectPointMap;
-        }
-
         public TopologyConfig topologyConfig() {
             return topologyConfig;
         }
+    }
 
+    /**
+     * Domain device driver configuration class.
+     */
+    public static class DriverConfig {
+        private final String manufacturer;
+        private final String swVersion;
+        private final String hwVersion;
+
+        public DriverConfig(String manufacturer, String swVersion, String hwVersion) {
+            this.manufacturer = manufacturer;
+            this.swVersion = swVersion;
+            this.hwVersion = hwVersion;
+        }
+
+        public String manufacturer() {
+            return manufacturer;
+        }
+
+        public String swVersion() {
+            return swVersion;
+        }
+
+        public String hwVersion() {
+            return hwVersion;
+        }
     }
 }
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/PeerState.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/flow/package-info.java
similarity index 80%
copy from icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/PeerState.java
copy to icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/flow/package-info.java
index 75f1bdf..006919d 100644
--- a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/PeerState.java
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/flow/package-info.java
@@ -14,14 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.icona.domainprovider.api;
-
 /**
- * State of a session with a remote domain.
+ * ICONA flow rule provider.
  */
-public enum PeerState {
-
-    UP,
-    DOWN,
-    UNKNOWN
-}
+package org.onosproject.icona.domainprovider.impl.flow;
\ No newline at end of file
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/IconaRemoteDeviceProvider.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/topology/IconaRemoteDeviceProvider.java
similarity index 77%
rename from icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/IconaRemoteDeviceProvider.java
rename to icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/topology/IconaRemoteDeviceProvider.java
index ec11959..5a2a60d 100644
--- a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/IconaRemoteDeviceProvider.java
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/topology/IconaRemoteDeviceProvider.java
@@ -14,9 +14,8 @@
  * limitations under the License.
  */
 
-package org.onosproject.icona.domainprovider.impl;
+package org.onosproject.icona.domainprovider.impl.topology;
 
-import com.google.common.collect.Sets;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Service;
@@ -25,16 +24,19 @@
 import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.onlab.packet.ChassisId;
+import org.onosproject.cluster.ClusterService;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
+import org.onosproject.icona.domainmgr.api.DomainConfigService;
 import org.onosproject.icona.domainmgr.api.DomainId;
 import org.onosproject.icona.domainprovider.api.device.DomainDevice;
 import org.onosproject.icona.domainprovider.api.device.IconaSBDeviceService;
 import org.onosproject.icona.domainprovider.api.link.DefaultInterLinkDescription;
 import org.onosproject.icona.domainprovider.api.link.IconaSBLinkService;
 import org.onosproject.icona.domainprovider.api.link.InterLinkDescription;
-import org.onosproject.icona.domainprovider.api.link.LinkId;
+import org.onosproject.icona.domainmgr.api.LinkId;
 import org.onosproject.icona.domainprovider.impl.config.IconaConfig;
+import org.onosproject.mastership.MastershipAdminService;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultAnnotations;
 import org.onosproject.net.SparseAnnotations;
@@ -43,8 +45,8 @@
 import org.onosproject.net.MastershipRole;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.Link;
-import org.onosproject.net.config.ConfigFactory;
 import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.ConfigFactory;
 import org.onosproject.net.config.NetworkConfigRegistry;
 import org.onosproject.net.config.NetworkConfigService;
 import org.onosproject.net.config.NetworkConfigEvent;
@@ -57,15 +59,15 @@
 import org.onosproject.net.provider.ProviderId;
 import org.slf4j.Logger;
 
-import java.util.Optional;
 import java.util.List;
-import java.util.Set;
 import java.util.concurrent.ExecutorService;
 
-import static org.onosproject.icona.domainprovider.impl.IconaTopologyManager.INTER_LINK_ID;
-import static org.onosproject.icona.domainprovider.impl.config.IconaConfig.DomainConfig;
+import static org.onosproject.icona.domainprovider.impl.config.IconaConfig.DriverConfig;
+import static org.onosproject.icona.domainprovider.impl.topology.IconaTopologyManager.DOMAIN_ID;
+import static org.onosproject.icona.domainprovider.impl.topology.IconaTopologyManager.INTER_LINK_ID;
 import static java.util.concurrent.Executors.newFixedThreadPool;
 import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.AnnotationKeys.DRIVER;
 import static org.slf4j.LoggerFactory.getLogger;
 import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
 
@@ -73,16 +75,16 @@
  * Exposes remote domain devices to the core.
  */
 @Component(immediate = true)
-@Service(IconaSBDeviceService.class)
+@Service(value = IconaSBDeviceService.class)
 public class IconaRemoteDeviceProvider implements DeviceProvider, IconaSBDeviceService {
 
     private final Logger log = getLogger(getClass());
-    protected static final String PROVIDER_NAME = "org.onosproject.icona.domainprovider";
-    protected static final ProviderId PROVIDER_ID = new ProviderId("domain", PROVIDER_NAME);
+    public static final String PROVIDER_NAME = "org.onosproject.icona.domainprovider";
+    public static final ProviderId PROVIDER_ID = new ProviderId("domain", PROVIDER_NAME);
     private static final String UNKNOWN = "unknown";
+    private static final String NO_LLDP = "no-lldp";
 
     private ApplicationId appId;
-    private DomainId localDomainId;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected NetworkConfigRegistry configRegistry;
@@ -99,9 +101,18 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected IconaSBLinkService iconaSBLinkService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DomainConfigService domainConfigService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipAdminService mastershipAdminService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ClusterService clusterService;
+
     protected DeviceProviderService deviceProviderService;
 
-    private Set<DomainConfig> domainConfigs = Sets.newConcurrentHashSet();
+    private DriverConfig driverConfig;
 
     private final NetworkConfigListener configListener = new InternalConfigListener();
     private final ConfigFactory configFactory =
@@ -111,106 +122,104 @@
                     return new IconaConfig();
                 }
             };
+
     private final ExecutorService eventExecutor =
             newFixedThreadPool(3, groupedThreads("onos/icona-sb-manager", "event-handler-%d"));
 
-    @Override
-    public ProviderId id() {
-        return PROVIDER_ID;
-    }
-
     @Activate
     public void activate() {
         appId = coreService.registerApplication(PROVIDER_NAME);
         configRegistry.registerConfigFactory(configFactory);
         configService.addListener(configListener);
         deviceProviderService = deviceProviderRegistry.register(this);
+        log.info("Started");
     }
 
     @Deactivate
     public void deactivate() {
-        //TODO: disconnect devices
         configService.removeListener(configListener);
         configRegistry.unregisterConfigFactory(configFactory);
         deviceProviderRegistry.unregister(this);
+        log.info("Stopped");
     }
 
     /**
      * Notify the core system that a new domain device is on.
-     *
      * @param deviceId remote device identifier
      */
     private void advertiseDevice(DeviceId deviceId, DomainId domainId) {
         ChassisId chassisId = new ChassisId();
+        log.info("advertiseDevice");
 
-        // disable lldp for this virtual device
+        // disable lldp for this virtual device and annotate it with the proper driver
+        String driverKey = driverConfig.manufacturer() + "-" + driverConfig.hwVersion() + "-" +
+                driverConfig.swVersion();
         SparseAnnotations annotations = DefaultAnnotations.builder()
-                .set("no-lldp", "lldp is disabled for a domain device")
-                .set("domainId", domainId.toString())
+                .set(NO_LLDP, "any")
+                .set(DOMAIN_ID, domainId.id())
+                .set(DRIVER, driverKey)
                 .build();
 
-        // TODO: give meaningful device info from the remote cluster
         DeviceDescription deviceDescription = new DefaultDeviceDescription(
                 deviceId.uri(),
                 Device.Type.SWITCH,
-                UNKNOWN, UNKNOWN,
-                UNKNOWN, UNKNOWN,
+                driverConfig.manufacturer(), driverConfig.hwVersion(),
+                driverConfig.swVersion(), UNKNOWN,
                 chassisId,
                 annotations);
         deviceProviderService.deviceConnected(deviceId, deviceDescription);
+        mastershipAdminService.setRole(clusterService.getLocalNode().id(), deviceId,
+                MastershipRole.MASTER);
     }
 
     /**
-     * Notifies the core system of all ports of a device.
-     *
+     * Notify the core system of all ports of a device.
      * @param deviceId device identifier
      * @param portDescriptions description of ports
      */
     private void advertiseDevicePorts(DeviceId deviceId, List<PortDescription> portDescriptions) {
-        // ports are properly annotated in the southbound bundles
         deviceProviderService.updatePorts(deviceId, portDescriptions);
     }
 
     /**
      * Creates two directed links for each inter-link port found among the list
      * of all the domain device ports, assuming all interlinks are bidirectional.
-     * One connect-point is taken from configuration, the other from the port description.
-     *
+     * One connect-point is taken from configuration, the other from the port description
      * @param domainId domain identifier
      * @param deviceId port identifier
      * @param port interlink port description
      */
     private void advertiseInterlinks(DomainId domainId, DeviceId deviceId, PortDescription port) {
         LinkId interLinkId = LinkId.linkId(port.annotations().value(INTER_LINK_ID));
-        Optional<DomainConfig> optional = domainConfigs.stream()
-                .filter(config -> !config.peerId().equals(domainId))
-                .findFirst();
-        if (optional.isPresent()) {
-            Pair<Link.Type, ConnectPoint> interlinkConf =
-                    optional.get()
-                            .interLinkConnectPointMap()
-                            .get(interLinkId);
+        Pair<Link.Type, ConnectPoint> interlinkConf =
+                domainConfigService.interlinkConnectPointMap()
+                        .get(interLinkId);
+        if (interlinkConf != null) {
+
             ConnectPoint localCp = interlinkConf.getRight();
             ConnectPoint remoteCp = new ConnectPoint(deviceId, port.portNumber());
             Link.Type linkType = interlinkConf.getLeft();
+            DomainId localDomainId = domainConfigService.localDomainId();
             // currently we handle interlinks as being bidirectional...
-            SparseAnnotations annotations = annotateInterLink(localDomainId.id(), domainId.id());
             InterLinkDescription interLinkDescription1 = new DefaultInterLinkDescription(localCp,
-                    remoteCp, linkType, Pair.of(localDomainId, domainId), interLinkId, annotations);
-            SparseAnnotations annotations1 = annotateInterLink(domainId.id(), localDomainId.id());
+                    remoteCp, linkType, Pair.of(localDomainId, domainId), interLinkId);
             InterLinkDescription interLinkDescription2 = new DefaultInterLinkDescription(remoteCp,
-                    localCp, linkType, Pair.of(domainId, localDomainId), interLinkId, annotations1);
-            iconaSBLinkService.addInterLink(domainId, interLinkDescription1);
-            iconaSBLinkService.addInterLink(domainId, interLinkDescription2);
+                    localCp, linkType, Pair.of(domainId, localDomainId), interLinkId);
+            iconaSBLinkService.addInterLink(interLinkDescription1);
+            iconaSBLinkService.addInterLink(interLinkDescription2);
+            log.info("Interlink {} detected", interLinkId.id());
         } else {
             log.info("No local connect point for interlink: " + interLinkId);
         }
     }
-    private SparseAnnotations annotateInterLink(String srcDomain, String dstDomain) {
-        return DefaultAnnotations.builder()
-                .set("srcDomain", srcDomain)
-                .set("dstDomain", dstDomain)
-                .build();
+
+    private void disconnectDevice(DeviceId deviceId) {
+        deviceProviderService.deviceDisconnected(deviceId);
+    }
+
+    @Override
+    public ProviderId id() {
+        return PROVIDER_ID;
     }
 
     // DeviceProvider
@@ -251,8 +260,8 @@
     }
 
     @Override
-    public void addRemotePort(DomainId domainId, DeviceId deviceId, PortDescription portDescription) {
-        // TODO
+    public void addRemotePort(DomainId domainId, DeviceId deviceId, PortDescription newPort) {
+
     }
 
     @Override
@@ -262,7 +271,7 @@
 
     @Override
     public void disconnectRemoteDevice(DomainId domainId, DeviceId deviceId) {
-        // TODO
+        disconnectDevice(deviceId);
     }
 
     @Override
@@ -273,13 +282,10 @@
     private void readConfig() {
         IconaConfig iconaConfig =
                 configRegistry.getConfig(appId, IconaConfig.class);
-        localDomainId = iconaConfig.getLocalId();
-        domainConfigs.addAll(
-                iconaConfig.getPeersConfig());
+        driverConfig = iconaConfig.getDriverConfig();
     }
 
     private class InternalConfigListener implements NetworkConfigListener {
-
         @Override
         public void event(NetworkConfigEvent event) {
             if (!event.configClass().equals(IconaConfig.class)) {
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/IconaRemoteHostProvider.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/topology/IconaRemoteHostProvider.java
similarity index 91%
rename from icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/IconaRemoteHostProvider.java
rename to icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/topology/IconaRemoteHostProvider.java
index 2e54b8d..dc55a38 100644
--- a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/IconaRemoteHostProvider.java
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/topology/IconaRemoteHostProvider.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.icona.domainprovider.impl;
+package org.onosproject.icona.domainprovider.impl.topology;
 
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Service;
@@ -37,8 +37,8 @@
 import java.util.Set;
 
 import static org.slf4j.LoggerFactory.getLogger;
-import static org.onosproject.icona.domainprovider.impl.IconaRemoteDeviceProvider.PROVIDER_ID;
-import static org.onosproject.icona.domainprovider.impl.IconaRemoteDeviceProvider.PROVIDER_NAME;
+import static org.onosproject.icona.domainprovider.impl.topology.IconaRemoteDeviceProvider.PROVIDER_ID;
+import static org.onosproject.icona.domainprovider.impl.topology.IconaRemoteDeviceProvider.PROVIDER_NAME;
 
 /**
  * Exposes remote domain hosts to the core.
@@ -98,8 +98,8 @@
 
     // IconaSBHostService interface
     @Override
-    public void addRemoteHosts(DomainId domainId, Set<DomainHostDescription> domainHostDescriptions) {
-        // TODO
+    public void addRemoteHosts(DomainId domainId, Set<DomainHostDescription> newHosts) {
+        newHosts.forEach(this::advertiseHost);
     }
 
     @Override
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/IconaRemoteLinkProvider.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/topology/IconaRemoteLinkProvider.java
similarity index 66%
rename from icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/IconaRemoteLinkProvider.java
rename to icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/topology/IconaRemoteLinkProvider.java
index 35485ac..e1cb7ba 100644
--- a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/IconaRemoteLinkProvider.java
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/topology/IconaRemoteLinkProvider.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.icona.domainprovider.impl;
+package org.onosproject.icona.domainprovider.impl.topology;
 
 import com.google.common.annotations.Beta;
 import org.apache.felix.scr.annotations.Component;
@@ -28,17 +28,22 @@
 import org.onosproject.icona.domainprovider.api.link.InterLinkDescription;
 import org.onosproject.icona.domainprovider.api.link.IntraLinkDescription;
 import org.onosproject.icona.domainprovider.api.link.IconaSBLinkService;
-import org.onosproject.icona.domainprovider.api.link.LinkId;
+import org.onosproject.icona.domainmgr.api.LinkId;
+import org.onosproject.net.DefaultAnnotations;
 import org.onosproject.net.Link;
+import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.link.LinkDescription;
 import org.onosproject.net.link.LinkProvider;
+import org.onosproject.net.link.DefaultLinkDescription;
 import org.onosproject.net.link.LinkProviderRegistry;
 import org.onosproject.net.link.LinkProviderService;
 import org.onosproject.net.provider.ProviderId;
 import org.slf4j.Logger;
 
+import static org.onosproject.icona.domainprovider.impl.topology.IconaTopologyManager.DOMAIN_ID;
 import static org.slf4j.LoggerFactory.getLogger;
-import static org.onosproject.icona.domainprovider.impl.IconaRemoteDeviceProvider.PROVIDER_ID;
-import static org.onosproject.icona.domainprovider.impl.IconaRemoteDeviceProvider.PROVIDER_NAME;
+import static org.onosproject.icona.domainprovider.impl.topology.IconaRemoteDeviceProvider.PROVIDER_ID;
+import static org.onosproject.icona.domainprovider.impl.topology.IconaRemoteDeviceProvider.PROVIDER_NAME;
 
 /**
  * Exposes remote domain links to the core.
@@ -46,6 +51,8 @@
 @Component(immediate = true)
 @Service(IconaSBLinkService.class)
 public class IconaRemoteLinkProvider implements LinkProvider, IconaSBLinkService {
+    private static final String SRC_DOMAIN_ID = "srcDomainId";
+    private static final String DST_DOMAIN_ID = "dstDomainId";
 
     private final Logger log = getLogger(getClass());
 
@@ -73,14 +80,25 @@
         linkProviderRegistry.unregister(this);
     }
 
-    // IconaSBLinkService
     @Override
     public void addRemoteLink(IntraLinkDescription link) {
-        // TODO
+        SparseAnnotations annotations = DefaultAnnotations.builder()
+                .set(DOMAIN_ID, link.domainId().id())
+                .build();
+        LinkDescription linkDescription = new DefaultLinkDescription(link.src(), link.dst(),
+                link.type(), true, annotations);
+        linkProviderService.linkDetected(link);
     }
 
     @Override
-    public void addInterLink(DomainId domainId, InterLinkDescription link) {
+    public void addInterLink(InterLinkDescription link) {
+        SparseAnnotations annotations = DefaultAnnotations.builder()
+                .set(SRC_DOMAIN_ID, link.endDomains().getLeft().id())
+                .set(DST_DOMAIN_ID, link.endDomains().getLeft().id())
+                .build();
+        LinkDescription linkDescription = new DefaultLinkDescription(link.src(), link.dst(),
+                link.type(), true, annotations);
+        linkProviderService.linkDetected(linkDescription);
     }
 
     @Override
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/IconaTopologyManager.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/topology/IconaTopologyManager.java
similarity index 74%
rename from icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/IconaTopologyManager.java
rename to icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/topology/IconaTopologyManager.java
index 4050a2e..1e0ba5a 100644
--- a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/IconaTopologyManager.java
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/topology/IconaTopologyManager.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.icona.domainprovider.impl;
+package org.onosproject.icona.domainprovider.impl.topology;
 
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
@@ -29,7 +29,9 @@
 import org.onlab.packet.VlanId;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
+import org.onosproject.icona.domainmgr.api.DomainConfigService;
 import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.icona.domainmgr.api.DomainService;
 import org.onosproject.icona.domainprovider.api.DomainTopology;
 import org.onosproject.icona.domainprovider.api.DefaultDomainTopology;
 import org.onosproject.icona.domainprovider.api.IconaSBListener;
@@ -41,15 +43,17 @@
 import org.onosproject.icona.domainprovider.api.link.IntraLinkDescription;
 import org.onosproject.icona.domainprovider.impl.config.IconaConfig;
 import org.onosproject.net.DeviceId;
-import org.onosproject.net.HostLocation;
-import org.onosproject.net.SparseAnnotations;
-import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.Host;
 import org.onosproject.net.PortNumber;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.config.NetworkConfigListener;
 import org.onosproject.net.config.ConfigFactory;
 import org.onosproject.net.config.NetworkConfigRegistry;
 import org.onosproject.net.config.NetworkConfigService;
 import org.onosproject.net.config.NetworkConfigEvent;
-import org.onosproject.net.config.NetworkConfigListener;
 import org.onosproject.net.device.DefaultPortDescription;
 import org.onosproject.net.device.PortDescription;
 import org.onosproject.net.device.DeviceService;
@@ -63,38 +67,37 @@
 import org.onosproject.net.link.LinkService;
 import org.slf4j.Logger;
 
-import java.util.Map;
 import java.util.Set;
-import java.util.List;
+import java.util.Map;
 import java.util.ArrayList;
+import java.util.List;
 import java.util.HashSet;
+import java.util.HashMap;
 import java.util.concurrent.CopyOnWriteArraySet;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.atomic.AtomicLong;
 
 import static java.util.concurrent.Executors.newFixedThreadPool;
-import static org.onosproject.icona.domainprovider.impl.IconaRemoteDeviceProvider.PROVIDER_NAME;
+import static org.onosproject.icona.domainprovider.impl.topology.IconaRemoteDeviceProvider.PROVIDER_NAME;
+import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
 import static org.onosproject.icona.domainprovider.impl.config.IconaConfig.DomainConfig;
 import static org.onlab.util.Tools.groupedThreads;
 import static org.onosproject.net.Port.Type.VIRTUAL;
 import static org.slf4j.LoggerFactory.getLogger;
-import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
 
 /**
- * Component in charge of sending the local topology abstraction to the remote clusters
- * through the southbound listeners. It also listens for relevant local topology events.
+ * Component in charge of handling local topology events and applying
+ *
+ * the mapping between internal changes and the exposed topologies.
  */
 @Component(immediate = true)
 @Service
 public class IconaTopologyManager implements IconaSBListenerService {
-    private static final String DEVICE_ID = "deviceId";
-    private static final String DOMAIN_ID = "domainId";
+    protected static final String DEVICE_ID = "deviceId";
+    protected static final String DOMAIN_ID = "domainId";
     protected static final String INTER_LINK_ID = "interlinkId";
 
-    private static DomainId localDomainId;
-
-    private final Logger log = getLogger(IconaTopologyManager.class);
-
+    private final Logger log = getLogger(getClass());
     private ApplicationId appId;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -115,6 +118,13 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected LinkService linkService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DomainService domainService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DomainConfigService domainConfigService;
+
+
     private final ConfigFactory configFactory =
             new ConfigFactory(APP_SUBJECT_FACTORY, IconaConfig.class, "icona") {
                 @Override
@@ -143,21 +153,25 @@
         deviceService.addListener(deviceListener);
         linkService.addListener(linkListener);
         hostService.addListener(hostListener);
+        log.info("Started");
     }
 
     @Deactivate
     public void deactivate() {
         eventExecutor.shutdown();
+
         deviceService.removeListener(deviceListener);
         linkService.removeListener(linkListener);
         hostService.removeListener(hostListener);
 
         configService.removeListener(configListener);
         configRegistry.unregisterConfigFactory(configFactory);
+        log.info("Stopped");
     }
 
     @Override
     public void addListener(IconaSBListener sbListener) {
+        log.debug("listener added");
         sbListeners.add(sbListener);
     }
 
@@ -166,6 +180,86 @@
         sbListeners.remove(sbListener);
     }
 
+    private void buildBigSwitch(String bigSwitchPrefixId, int portSpeed) {
+        Map<DomainId, DomainTopology> topologyMap = Maps.newHashMap();
+
+        domainConfigs.forEach(domainConfig -> {
+            log.info("Building big switch topology for domain {}", domainConfig.domainId().id());
+            DomainId localDomainId = domainConfigService.localDomainId();
+            DeviceId bigSwitchId = DeviceId.deviceId(bigSwitchPrefixId + localDomainId + "-" +
+                    domainConfig.domainId().id());
+            AtomicLong portCounter = new AtomicLong(0);
+            List<PortDescription> allPorts = new ArrayList<>();
+            Map<PortNumber, ConnectPoint> virtualPortToPortMapping = new HashMap<>();
+
+            domainConfigService.interlinkConnectPointMap().forEach((interlinkId, pair) -> {
+                SparseAnnotations annotations = DefaultAnnotations.builder()
+                        .set(DEVICE_ID, bigSwitchId.toString())
+                        .set(DOMAIN_ID, localDomainId.id())
+                        .set(INTER_LINK_ID, interlinkId.id())
+                        .build();
+
+                allPorts.add(new DefaultPortDescription(
+                        PortNumber.portNumber(portCounter.get()),
+                        true,
+                        VIRTUAL,
+                        portSpeed,    // port speed is to be configured
+                        annotations));
+
+                virtualPortToPortMapping.put(PortNumber.portNumber(portCounter.get()),
+                        pair.getRight());
+
+                portCounter.getAndIncrement();
+            });
+
+            final Set<DomainHostDescription> domainHostDescriptions = new HashSet<>();
+            hostService.getHosts().forEach(host ->
+                    domainConfig.topologyConfig().endPointIds().forEach(mac -> {
+
+                        if (host.mac().equals(MacAddress.valueOf(mac))) {
+
+                            PortNumber virtualPort = PortNumber.portNumber(portCounter.get());
+
+                            DefaultDomainHostDescription domainHost = new DefaultDomainHostDescription(
+                                    localDomainId,
+                                    MacAddress.valueOf(mac),
+                                    VlanId.NONE,
+                                    new HostLocation(bigSwitchId,
+                                            virtualPort, 0),
+                                    host.ipAddresses(),
+                                    new HashSet<Ip4Prefix>()); // TODO: ip4/6prefixes from config
+
+                            virtualPortToPortMapping.put(virtualPort,
+                                    new ConnectPoint(host.location().deviceId(), host.location().port()));
+
+                            domainHostDescriptions.add(domainHost);
+
+                            portCounter.getAndIncrement();
+
+                            log.info("host {} added", host.id());
+                        }
+                    })
+            );
+            domainService.setVirtualPortToPortMapping(bigSwitchId, virtualPortToPortMapping);
+
+            domainHostDescriptions.forEach(domainHost ->
+                    allPorts.add(new DefaultPortDescription(domainHost.location().port(),
+                            true, VIRTUAL, portSpeed)));
+            final DomainDevice bigSwitch =
+                    new DefaultDomainDevice(bigSwitchId, localDomainId, allPorts);
+            final Set<DomainDevice> domainDevices = Sets.newHashSet();
+            domainDevices.add(bigSwitch);
+            final Set<IntraLinkDescription> interLinks = Sets.newHashSet();
+            final DomainTopology domainTopology = new DefaultDomainTopology(localDomainId, domainDevices,
+                    interLinks, domainHostDescriptions);
+            topologyMap.put(domainConfig.domainId(), domainTopology);
+        });
+
+        log.debug("Calling southbound listeners to expose the local topology");
+        sbListeners.forEach(listener ->
+                listener.configTopology(topologyMap));
+    }
+
     private class LocalDeviceListener implements DeviceListener {
 
         @Override
@@ -194,9 +288,10 @@
     private class LocalHostListener implements HostListener {
         @Override
         public void event(HostEvent event) {
+            Host host = event.subject();
             switch (event.type()) {
                 case HOST_ADDED:
-                    // TODO: check config policy and the impact on the local topology exposed to the peers
+                    /// TODO: check config policy and the impact on the local topology exposed to the peers
                     break;
                 case HOST_REMOVED:
                     // TODO: check config policy and the impact on the local topology exposed to the peers
@@ -225,95 +320,18 @@
         }
     }
 
-    private void buildFullMesh(DomainConfig domainConfig) {
-
-    }
-    // We will add a parameter to this method to process only the subsets of domains
-    // whose TopologyConfig.Type is equal to BIG_SWITCH
-    private void buildBigSwitch(String bigSwitchPrefixId) {
-        Map<DomainId, DomainTopology> topologyMap = Maps.newHashMap();
-        domainConfigs.forEach(domainConfig -> {
-            log.info("Building big switch topology for domain {}", domainConfig.peerId().id());
-            DeviceId bigSwitchId = DeviceId.deviceId(bigSwitchPrefixId + localDomainId);
-            AtomicLong portCounter = new AtomicLong(0);
-
-            List<PortDescription> allPorts = new ArrayList<>();
-
-            domainConfig.interLinkConnectPointMap()
-                    .forEach((interLinkId, pair) -> {
-                        SparseAnnotations annotations = DefaultAnnotations.builder()
-                                .set(DEVICE_ID, bigSwitchId.toString())
-                                .set(DOMAIN_ID, localDomainId.id())
-                                .set(INTER_LINK_ID, interLinkId.id())
-                                .build();
-                        allPorts.add(
-                                new DefaultPortDescription(
-                                        PortNumber.portNumber(portCounter.get()),
-                                        true,
-                                        VIRTUAL,
-                                        100,    // port speed is to be configured
-                                        annotations));
-
-                        portCounter.getAndIncrement();
-                    });
-
-            Set<DomainHostDescription> domainHostDescriptions = new HashSet<>();
-            hostService.getHosts().forEach(host ->
-                    domainConfig.topologyConfig()
-                            .endPointIds().forEach(mac -> {
-                        if (host.mac().equals(MacAddress.valueOf(mac))) {
-                            DefaultDomainHostDescription domainHost = new DefaultDomainHostDescription(
-                                    localDomainId,
-                                    MacAddress.valueOf(mac),
-                                    VlanId.NONE,
-                                    new HostLocation(bigSwitchId,
-                                            PortNumber.portNumber(portCounter.get()), 0),
-                                    host.ipAddresses(),
-                                    new HashSet<Ip4Prefix>()); // TODO: ip4/6prefixes from config
-                            domainHostDescriptions.add(domainHost);
-                            log.info("host {} added as domainHost for domain {}", host.id(), domainConfig.peerId());
-                            portCounter.getAndIncrement();
-                        }
-                    })
-            );
-
-            domainHostDescriptions.forEach(domainHost ->
-                    allPorts.add(new DefaultPortDescription(domainHost.location().port(),
-                            true, VIRTUAL, 100)));
-            DomainDevice bigSwitch =
-                    new DefaultDomainDevice(bigSwitchId, localDomainId, allPorts);
-            Set<DomainDevice> domainDevices = Sets.newHashSet();
-            domainDevices.add(bigSwitch);
-            Set<IntraLinkDescription> interLinks = Sets.newHashSet();
-            DomainTopology domainTopology = new DefaultDomainTopology(localDomainId, domainDevices,
-                    interLinks, domainHostDescriptions);
-            topologyMap.put(domainConfig.peerId(), domainTopology);
-        });
-
-        log.info("Calling southbound listeners to expose the local topology...");
-        // listeners will executes network tasks,
-        // load balancing is handled via the leadership service
-        sbListeners.forEach(listener ->
-                listener.configTopology(topologyMap));
-    }
-
     private void readConfig() {
-        log.info("List of domains and inter-link connect points received");
+        log.info("Config received");
 
-        IconaConfig iconaConfig =
-                configRegistry.getConfig(appId, IconaConfig.class);
-
-        localDomainId = iconaConfig.getLocalId();
-
+        IconaConfig iconaConfig = configRegistry.getConfig(appId, IconaConfig.class);
         domainConfigs.addAll(
                 iconaConfig.getPeersConfig());
 
         // TODO: different topology for different TopologyConfig.Type values
-        buildBigSwitch(iconaConfig.getBigSwitchPrefixId());
+        buildBigSwitch(iconaConfig.getBigSwitchPrefixId(), iconaConfig.portSpeed());
     }
 
     private class InternalConfigListener implements NetworkConfigListener {
-
         @Override
         public void event(NetworkConfigEvent event) {
             if (!event.configClass().equals(IconaConfig.class)) {
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/PeerState.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/topology/package-info.java
similarity index 80%
copy from icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/PeerState.java
copy to icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/topology/package-info.java
index 75f1bdf..61127ce 100644
--- a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/PeerState.java
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/topology/package-info.java
@@ -14,14 +14,7 @@
  * limitations under the License.
  */
 
-package org.onosproject.icona.domainprovider.api;
-
 /**
- * State of a session with a remote domain.
+ * ICONA topology provider implementation.
  */
-public enum PeerState {
-
-    UP,
-    DOWN,
-    UNKNOWN
-}
+package org.onosproject.icona.domainprovider.impl.topology;
\ No newline at end of file
diff --git a/icona/tools/sample_configs/icona-config.json b/icona/tools/sample_configs/icona-config.json
new file mode 100644
index 0000000..f445de5
--- /dev/null
+++ b/icona/tools/sample_configs/icona-config.json
@@ -0,0 +1,56 @@
+{
+  "ports" : {
+    "of:0000000000000001/3" : {
+      "linkDiscovery" : {
+        "enabled" : "false"
+      }
+    }
+  },
+
+  "apps" : {
+    "org.onosproject.icona.domainmgr" : {
+      "domains" : {
+        "localDomain" : "domA",
+        "remoteDomains" : [
+          {
+            "domainId" : "domB",
+            "interlinkPorts" : [
+              {
+                "id" : "il:00000001",
+                "deviceId"  : "of:0000000000000001",
+                "portNumber"  : "3",
+                "type" : "INDIRECT"
+              }
+            ]
+          }
+        ]
+      }
+    },
+
+    "org.onosproject.icona.southbound.p2p" : {
+      "endPoints" : {
+        "localDomain" : "domA",
+        "listenPort" : "8181",
+        "topics" : [
+          "icona-domains-topic-one"
+        ],
+        "peers" :
+        [
+          {
+            "domainId" : "domB",
+            "clusterIps" : [
+              "192.168.102.10",
+              "192.168.102.11",
+              "192.168.102.12"
+            ],
+            "listenPort" : "8181",
+            "uername" : "fraluc",
+            "password" : "rocks",
+            "topic" : "icona-domains-topic-one"
+          }
+
+        ]
+      }
+    }
+  }
+}
diff --git a/icona/tools/sample_configs/icona-provider-config.json b/icona/tools/sample_configs/icona-provider-config.json
new file mode 100644
index 0000000..60f3c61
--- /dev/null
+++ b/icona/tools/sample_configs/icona-provider-config.json
@@ -0,0 +1,24 @@
+{
+  "apps" : {
+    "org.onosproject.icona.domainprovider" : {
+      "icona" : {
+        "bigSwitchPrefixId" : "domain:dev0001",
+        "driver" : {
+          "manufacturer" : "create-net",
+          "hwVersion" : "1.0.0",
+          "swVersion" : "1.0.0"
+        },
+        "domains" : [
+          {
+            "domainId"    : "domB",
+            "topologyType" : "bigSwitch",
+            "endPointIds" : [
+              "00:00:00:00:00:02",
+              "00:00:00:00:00:03"
+            ]
+          }
+        ]
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/icona/tools/sample_configs/multidomain-config.json b/icona/tools/sample_configs/multidomain-config.json
deleted file mode 100644
index 537abb8..0000000
--- a/icona/tools/sample_configs/multidomain-config.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-     "apps" : {
-        "org.onosproject.icona.domainprovider" : {
-            "icona" : {
-                "localDomainId" : "polito-sdn",
-                "bigSwitchPrefixId" : "domain:dev0000",
-                 "peers" : [
-                    {
-                        "domainId"    : "polito-turin",
-                        "interlinks" : [
-                                   {
-                                        "deviceId"      : "of:0000000000000001",
-                                        "portNumber"    : "2",
-                                        "interlinkId" : "il:00000001",
-                                         "interlinkType" : "tunnel"
-                                    }
-                            ],
-                        "topology" :
-                            {
-                                "type" : "bigSwitch",
-                                "endpointIds" : [
-                                    "aa:ee:bb:cc:dd:ff",
-                                    "aa:ee:bb:cc:dd:fe"
-                              ]
-                            }
-                    }
-                ]
-            }
-        }
-    }
-}