ONOS-4489 - Initial ICONA provider development

- Southbound APIs definition
- Stubs of implementation classes

Change-Id: I5a9b76510ea8d6b43fa615c94db191439555ddc2
diff --git a/icona/app/app.xml b/icona/app/app.xml
new file mode 100644
index 0000000..8fb0322
--- /dev/null
+++ b/icona/app/app.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ 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.
+  -->
+<app name="org.onosproject.icona" origin="ON.Lab" version="${project.version}"
+     category="Utility" url="http://onosproject.org" title="Inter-Cluster ONOS Application"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/onos-app-icona-domain-manager/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/onos-app-icona-domain-provider/${project.version}</artifact>
+</app>
diff --git a/icona/app/features.xml b/icona/app/features.xml
new file mode 100644
index 0000000..74fa9c8
--- /dev/null
+++ b/icona/app/features.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+
+<!--
+  ~ 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.
+  -->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
+    <feature name="${project.artifactId}" version="${project.version}"
+             description="${project.description}">
+        <feature>onos-api</feature>
+        <bundle>mvn:${project.groupId}/onos-app-icona-domain-manager/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-app-icona-domain-provider/${project.version}</bundle>
+    </feature>
+</features>
\ No newline at end of file
diff --git a/icona/app/pom.xml b/icona/app/pom.xml
new file mode 100644
index 0000000..63611ed
--- /dev/null
+++ b/icona/app/pom.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-icona</artifactId>
+        <version>1.7.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>onos-app-icona</artifactId>
+    <packaging>pom</packaging>
+
+    <description>Inter-Cluster ONOS App</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-icona-domain-manager</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-icona-domain-provider</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/icona/domainmgr/pom.xml b/icona/domainmgr/pom.xml
new file mode 100644
index 0000000..29e3f3c
--- /dev/null
+++ b/icona/domainmgr/pom.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-icona</artifactId>
+        <version>1.7.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>onos-app-icona-domain-manager</artifactId>
+    <packaging>bundle</packaging>
+
+
+    <description>Inter Cluster Onos Network App</description>
+
+    <properties>
+        <onos.app.name>org.onosproject.icona.domainmgr</onos.app.name>
+    </properties>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-core-serializers</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-osgi</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-misc</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+
+    </dependencies>
+</project>
diff --git a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainEvent.java b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainEvent.java
new file mode 100644
index 0000000..0ac8358
--- /dev/null
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainEvent.java
@@ -0,0 +1,48 @@
+/*
+ * 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.onosproject.event.AbstractEvent;
+
+/**
+ * Domain event class. The event notifies the presence of a new domain or its disappearance.
+ * Apps can listen for such events and then retrieve the domain topologies through {@link DomainService}
+ */
+public class DomainEvent extends AbstractEvent<DomainEvent.Type, DomainId> {
+
+    /**
+     * Domain event type.
+     */
+    public enum Type {
+
+        /**
+         * Indicates that a new domain ID has been added to the distributed store.
+         */
+        DOMAIN_ADDED,
+
+        /**
+         * Indicates that a domain ID has been removed from the store.
+         */
+        DOMAIN_REMOVED
+
+        // TODO: other state-related event types
+    }
+
+    public DomainEvent(DomainEvent.Type type, DomainId domainId) {
+        super(type, domainId);
+    }
+}
diff --git a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainId.java b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainId.java
new file mode 100644
index 0000000..e031952
--- /dev/null
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainId.java
@@ -0,0 +1,44 @@
+/*
+ * 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.onlab.util.Identifier;
+
+/**
+ * Representation of a peer domain.
+ */
+public class DomainId extends Identifier<String> {
+
+    /**
+     * Constructor of the peer id.
+     *
+     * @param identifier of the peer
+     */
+    public DomainId(String identifier) {
+        super(identifier);
+    }
+
+    /**
+     * Creates a peer id from the string identifier.
+     *
+     * @param identifier string identifier
+     * @return instance of the class DomainId
+     */
+    public static DomainId domainId(String identifier) {
+        return new DomainId(identifier);
+    }
+}
\ No newline at end of file
diff --git a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainListener.java b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainListener.java
new file mode 100644
index 0000000..6094ff8
--- /dev/null
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainListener.java
@@ -0,0 +1,26 @@
+/*
+ * 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.onosproject.event.EventListener;
+
+/**
+ * Listeners for domain events. Currently we handle the addition and remotion of a domain.
+ * Domain topology elements events can be sensed through existing Device, Host, Link listener
+ */
+public interface DomainListener extends EventListener<DomainEvent> {
+}
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
new file mode 100644
index 0000000..4ccaf6a
--- /dev/null
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainService.java
@@ -0,0 +1,93 @@
+/*
+ * 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.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.Link;
+
+import java.util.Set;
+
+/**
+ * Service to access domain topology elements.
+ */
+public interface DomainService {
+
+    /**
+     * Adds a new domain id to the store.
+     * @param domainId domain identifier
+     */
+    void registerDomainId(DomainId domainId);
+
+    /**
+     * Removes the specified domain id from the store.
+     * @param domainId domain identifier
+     */
+    void unregisterDomainId(DomainId domainId);
+
+    /**
+     * Returns the set of domains that have an associated topology.
+     *
+     * @return set of domain identifiers
+     */
+    Set<DomainId> getDomainIds();
+
+    /**
+     * Returns the set of the devices of the specified domain.
+     *
+     * @param domainId domain identifier
+     * @return set of device objects
+     */
+    Set<DeviceId> getDeviceIds(DomainId domainId);
+
+    /**
+     * Gets all the devices of the specified domain.
+     * @param domainId domain identifier.
+     * @return set of devices
+     */
+    Set<Device> getDevices(DomainId domainId);
+
+    /**
+     * Returns the set of hosts of the specified domain.
+     * @param domainId domain id
+     * @return set of host objects
+     */
+    Set<HostId> getHostIds(DomainId domainId);
+
+    /**
+     * Gets the hosts of the specified domain.
+     * @param domainId domain id
+     * @return set of host objects
+     */
+    Set<Host> getHosts(DomainId domainId);
+
+    /**
+     * Gets the list of interlinks between the specified domains.
+     * @return set of interlinks
+     */
+    Set<Link> getInterLinks(Pair<DomainId, DomainId> endDomains);
+
+    /**
+     * Gets the list of links within a domain.
+     * @param domainId domain id
+     * @return set of intra-domain link
+     */
+    Set<Link> getIntraLinks(DomainId domainId);
+}
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
new file mode 100644
index 0000000..4501731
--- /dev/null
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainStore.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.api;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.Link;
+import org.onosproject.store.Store;
+
+import java.util.Set;
+
+/**
+ * Domain store interface.
+ */
+public interface DomainStore extends Store<DomainEvent, DomainStoreDelegate> {
+
+    /**
+     * Returns the set of domains that have an associated topology.
+     * @return set of domain identifiers
+     */
+    Set<DomainId> getDomainIds();
+
+    /**
+     * Returns the set of the devices of the specified domain.
+     * @param domainId domain identifier
+     * @return set of device objects
+     */
+    Set<DeviceId> getDeviceIds(DomainId domainId);
+
+    //TODO: get the topology of the topologies of all domain
+
+    /**
+     * Adds a new domain ID to the store.
+     * @param domainId domain id
+     */
+    void addDomain(DomainId domainId);
+
+    /**
+     * Removes the specified domain ID from the store.
+     * @param domainId domain identifier
+     */
+    void removeDomain(DomainId domainId);
+
+    /**
+     * Adds a new device to the store.
+     * @param domainId domain ientifier
+     * @param deviceId device identifier
+     */
+    void addDevice(DomainId domainId, DeviceId deviceId);
+
+    /**
+     * Removes a device from the store.
+     * @param domainId domain identifier
+     * @param deviceId device identifier
+     */
+    void removeDevice(DomainId domainId, DeviceId deviceId);
+
+    /**
+     * Gets the set of host identifiers of the specified domain.
+     * @param domainId domain identifier
+     * @return set of host identifiers
+     */
+    Set<HostId> getHostIds(DomainId domainId);
+
+    /**
+     * Adds a host to the domain store.
+     * @param domainId domain identifier
+     * @param hostId host identifier
+     */
+    void addHost(DomainId domainId, HostId hostId);
+
+    /**
+     * Removes a host from a domain.
+     * @param domainId domain identifier
+     * @param hostId host identifier
+     */
+    void removeHost(DomainId domainId, HostId hostId);
+
+    /**
+     * Gets the set of interlinks having source port within the specified domains.
+     * @param endDomains end domains identifier
+     * @return set of links
+     */
+    Set<Link> getInterLinks(Pair<DomainId, DomainId> endDomains);
+
+    /**
+     * Adds an interlink to the store. Link source port is within the specified domain.
+     * @param endDomains end domains identifier
+     * @param link link object
+     */
+    void addOrUpdateInterLink(Pair<DomainId, DomainId> endDomains, Link link);
+
+    /**
+     * Removes an interlink from the store.
+     * @param endDomains end domain identifiers
+     * @param link link object
+     */
+    void removeInterLink(Pair<DomainId, DomainId> endDomains, Link link);
+}
diff --git a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainStoreDelegate.java b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainStoreDelegate.java
new file mode 100644
index 0000000..edb7d9a
--- /dev/null
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/DomainStoreDelegate.java
@@ -0,0 +1,27 @@
+/*
+ * 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.onosproject.store.StoreDelegate;
+
+/**
+ * Domain store delegate.
+ */
+public interface DomainStoreDelegate extends StoreDelegate<DomainEvent> {
+
+}
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
new file mode 100644
index 0000000..32e1199
--- /dev/null
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/api/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Icona 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
new file mode 100644
index 0000000..4c28802
--- /dev/null
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/DistributedDomainStore.java
@@ -0,0 +1,280 @@
+/*
+ * 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.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.apache.commons.lang3.tuple.Pair;
+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.onlab.util.Identifier;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.icona.domainmgr.api.DomainEvent;
+import org.onosproject.icona.domainmgr.api.DomainStore;
+import org.onosproject.icona.domainmgr.api.DomainStoreDelegate;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.Link;
+import org.onosproject.store.AbstractStore;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.DistributedSet;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.SetEventListener;
+import org.onosproject.store.service.SetEvent;
+import org.onosproject.store.service.Serializer;
+
+import org.slf4j.Logger;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import static org.onosproject.icona.domainmgr.api.DomainEvent.Type;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import static org.onosproject.icona.domainmgr.api.DomainEvent.Type.DOMAIN_ADDED;
+import static org.onosproject.icona.domainmgr.api.DomainEvent.Type.DOMAIN_REMOVED;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Distributed domain store implementation.
+ */
+public class DistributedDomainStore extends AbstractStore<DomainEvent, DomainStoreDelegate>
+        implements DomainStore {
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    private final Logger log = getLogger(getClass());
+
+    private DistributedSet<DomainId> domainIds;
+    private final SetEventListener<DomainId> domainIdSetEventListener = new InternalMapListener();
+
+    private ConsistentMap<DomainId, Set<DeviceId>> domainIdDeviceIdsConsistentMap;
+    private Map<DomainId, Set<DeviceId>> domainIdDeviceIdsMap;
+
+    private ConsistentMap<DomainId, Set<HostId>> domainIdHostsIdsConsistentMap;
+    private Map<DomainId, Set<HostId>> domainIdHostIdsMap;
+
+    private ConsistentMap<Pair<DomainId, DomainId>, Set<Link>> domainIdLinkSetConsistentMap;
+    private Map<Pair<DomainId, DomainId>, Set<Link>> domainIdLinkSetMap;
+
+    private static final Serializer SERIALIZER = Serializer
+            .using(new KryoNamespace.Builder().register(KryoNamespaces.API)
+                    .register(Identifier.class)
+                    .register(DomainId.class)
+                    .build());
+
+    @Activate
+    public void activate() {
+
+        domainIds = storageService.<DomainId>setBuilder()
+                .withSerializer(SERIALIZER)
+                .withName("onos-domainId")
+                .withRelaxedReadConsistency()
+                .build()
+                .asDistributedSet();
+        domainIds.addListener(domainIdSetEventListener);
+
+        domainIdDeviceIdsConsistentMap = storageService.<DomainId, Set<DeviceId>>consistentMapBuilder()
+                .withSerializer(SERIALIZER)
+                .withName("onos-domain-device-ids")
+                .withRelaxedReadConsistency()
+                .build();
+        domainIdDeviceIdsMap = domainIdDeviceIdsConsistentMap.asJavaMap();
+
+        domainIdHostsIdsConsistentMap = storageService.<DomainId, Set<HostId>>consistentMapBuilder()
+                .withSerializer(SERIALIZER)
+                .withName("onos-domain-host-ids")
+                .withRelaxedReadConsistency()
+                .build();
+        domainIdHostIdsMap = domainIdHostsIdsConsistentMap.asJavaMap();
+
+        domainIdLinkSetConsistentMap = storageService.<Pair<DomainId, DomainId>, Set<Link>>
+                consistentMapBuilder()
+                .withSerializer(SERIALIZER)
+                .withName("onos-domain-links")
+                .withRelaxedReadConsistency()
+                .build();
+        domainIdLinkSetMap = domainIdLinkSetConsistentMap.asJavaMap();
+
+        log.info("Started");
+
+    }
+
+    @Deactivate
+    public void deactivate() {
+        domainIds.removeListener(domainIdSetEventListener);
+        log.info("Stopped");
+
+    }
+
+    @Override
+    public Set<DomainId> getDomainIds() {
+        return ImmutableSet.copyOf(domainIds);
+    }
+
+    @Override
+    public Set<DeviceId> getDeviceIds(DomainId domainId) {
+        checkState(domainExists(domainId), "Domain id unknown");
+        return ImmutableSet.copyOf(domainIdDeviceIdsMap.get(domainId));
+    }
+
+    @Override
+    public void addDomain(DomainId domainId) {
+        domainIds.add(domainId);
+    }
+
+    @Override
+    public void removeDomain(DomainId domainId) {
+        domainIds.remove(domainId);
+        clear(domainId);
+    }
+
+    @Override
+    public void addDevice(DomainId domainId, DeviceId deviceId) {
+        checkState(domainExists(domainId), "Domain id unknown");
+        domainIdDeviceIdsMap.compute(domainId, (k, set) -> {
+            if (set == null) {
+               set = Sets.newConcurrentHashSet();
+            }
+            set.add(deviceId);
+            return set;
+        });
+    }
+
+    @Override
+    public void removeDevice(DomainId domainId, DeviceId deviceId) {
+        checkState(domainExists(domainId), "Domain id unknown");
+        domainIdDeviceIdsMap.computeIfPresent(domainId, (k, existingSet) -> {
+            if (existingSet.contains(deviceId)) {
+                existingSet.remove(deviceId);
+                return existingSet;
+            } else {
+                return existingSet;
+            }
+        });
+    }
+
+    @Override
+    public Set<HostId> getHostIds(DomainId domainId) {
+        checkState(domainExists(domainId), "Domain id unknown");
+        return ImmutableSet.copyOf(domainIdHostIdsMap.get(domainId));
+    }
+
+    @Override
+    public void addHost(DomainId domainId, HostId hostId) {
+        checkState(domainExists(domainId), "Domain id unknown");
+        domainIdHostIdsMap.compute(domainId, (k, set) -> {
+            if (set == null) {
+                set = Sets.newConcurrentHashSet();
+            }
+            set.add(hostId);
+            return set;
+        });
+    }
+
+    @Override
+    public void removeHost(DomainId domainId, HostId hostId) {
+        checkState(domainExists(domainId), "Domain id unknown");
+        domainIdHostIdsMap.computeIfPresent(domainId, (k, existingSet) -> {
+            if (existingSet.contains(hostId)) {
+                existingSet.remove(hostId);
+                return existingSet;
+            } else {
+                return existingSet;
+            }
+        });
+    }
+
+    @Override
+    public Set<Link> getInterLinks(Pair<DomainId, DomainId> endDomains) {
+        checkState(domainExists(endDomains.getLeft()), "Domain id unknown");
+        checkState(domainExists(endDomains.getRight()), "Domain id unknown");
+        return ImmutableSet.copyOf(domainIdLinkSetMap.get(endDomains));
+    }
+
+    @Override
+    public void addOrUpdateInterLink(Pair<DomainId, DomainId> endDomains, Link link) {
+        checkState(domainExists(endDomains.getLeft()), "Domain id unknown");
+        checkState(domainExists(endDomains.getRight()), "Domain id unknown");
+        domainIdLinkSetMap.compute(endDomains, (k, set) -> {
+           if (set == null) {
+               set = Sets.newConcurrentHashSet();
+           }
+           set.add(link);
+            return set;
+        });
+    }
+
+    @Override
+    public void removeInterLink(Pair<DomainId, DomainId> endDomains, Link link) {
+        checkState(domainExists(endDomains.getLeft()), "Domain id unknown");
+        checkState(domainExists(endDomains.getRight()), "Domain id unknown");
+        domainIdLinkSetMap.computeIfPresent(endDomains, (k, existingSet) -> {
+            if (existingSet.contains(link)) {
+                existingSet.remove(link);
+                return existingSet;
+            } else {
+                return existingSet;
+            }
+        });
+    }
+
+    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
+        domainIdLinkSetMap.keySet().forEach(endDomains -> {
+            if (endDomains.getLeft().equals(domainId) ||
+                    endDomains.getRight().equals(domainId)) {
+                domainPairs.add(endDomains);
+            }
+        });
+        domainPairs.forEach(pair -> domainIdLinkSetMap.remove(pair));
+        domainIdDeviceIdsMap.remove(domainId);
+        domainIdHostIdsMap.remove(domainId);
+    }
+
+    private class InternalMapListener implements SetEventListener<DomainId> {
+        @Override
+        public void event(SetEvent<DomainId> event) {
+            Type type;
+            switch (event.type()) {
+                case ADD:
+                    type = DOMAIN_ADDED;
+                    break;
+                case REMOVE:
+                    type = DOMAIN_REMOVED;
+                    break;
+                default:
+                    log.error("Unsupported event type: " + event.type());
+                    return;
+            }
+            notifyDelegate(new DomainEvent(type, event.entry()));
+        }
+    }
+
+    private boolean domainExists(DomainId domainId) {
+        checkNotNull(domainId, "domain identifier is null");
+        return domainIds.contains(domainId);
+    }
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..e554f59
--- /dev/null
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/DomainManager.java
@@ -0,0 +1,246 @@
+/*
+ * 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.ImmutableSet;
+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.event.AbstractListenerManager;
+import org.onosproject.icona.domainmgr.api.DomainEvent;
+import org.onosproject.icona.domainmgr.api.DomainListener;
+import org.onosproject.icona.domainmgr.api.DomainService;
+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.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.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.link.LinkEvent;
+import org.onosproject.net.link.LinkListener;
+import org.onosproject.net.link.LinkService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Exposes domain topology elements and listen for updates of such elements.
+ */
+@Component(immediate = true)
+@Service
+public class DomainManager extends AbstractListenerManager<DomainEvent, DomainListener>
+        implements DomainService {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private static final String DOMAIN_ID = "domainId";
+    private static final String SRC_DOMAIN_ID = "srcDomainId";
+    private static final String DST_DOMAIN_ID = "dstDomainId";
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DomainStore domainStore;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkService linkService;
+
+    protected DomainStoreDelegate delegate = this::post;
+
+    private final DeviceListener deviceListener = new InternalDeviceListener();
+    private final HostListener hostListener = new InternalHostListener();
+    private final LinkListener linkListener = new InternalLinkListener();
+
+    @Activate
+    public void activate() {
+        deviceService.addListener(deviceListener);
+        hostService.addListener(hostListener);
+        linkService.addListener(linkListener);
+        domainStore.setDelegate(delegate);
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        deviceService.removeListener(deviceListener);
+        hostService.removeListener(hostListener);
+        linkService.removeListener(linkListener);
+        domainStore.unsetDelegate(delegate);
+        log.info("Stopped");
+    }
+
+    @Override
+    public void registerDomainId(DomainId domainId) {
+        checkNotNull(domainId);
+        domainStore.addDomain(domainId);
+    }
+
+    @Override
+    public void unregisterDomainId(DomainId domainId) {
+        checkNotNull(domainId);
+        domainStore.removeDomain(domainId);
+    }
+
+    @Override
+    public Set<DomainId> getDomainIds() {
+        return domainStore.getDomainIds();
+    }
+
+    @Override
+    public Set<DeviceId> getDeviceIds(DomainId domainId) {
+        return domainStore.getDeviceIds(domainId);
+    }
+
+    @Override
+    public Set<Device> getDevices(DomainId domainId) {
+        Set<DeviceId> deviceIds = domainStore.getDeviceIds(domainId);
+        Set<Device> devices = new HashSet<>();
+        deviceService.getDevices().forEach(device -> {
+            if (deviceIds.contains(device.id())) {
+                devices.add(device);
+            }
+        });
+        return ImmutableSet.copyOf(devices);
+    }
+
+    @Override
+    public Set<HostId> getHostIds(DomainId domainId) {
+        return domainStore.getHostIds(domainId);
+    }
+
+    @Override
+    public Set<Host> getHosts(DomainId domainId) {
+        Set<HostId> hostIds = domainStore.getHostIds(domainId);
+        Set<Host> hosts = new HashSet<>();
+        hostService.getHosts().forEach(host -> {
+            if (hostIds.contains(host.id())) {
+                hosts.add(host);
+            }
+        });
+        return ImmutableSet.copyOf(hosts);
+    }
+
+    @Override
+    public Set<Link> getInterLinks(Pair<DomainId, DomainId> endDomains) {
+        return domainStore.getInterLinks(endDomains);
+    }
+
+    @Override
+    public Set<Link> getIntraLinks(DomainId domainId) {
+        Set<Device> domDevices = getDevices(domainId);
+        Set<Link> intralinks = new HashSet<>();
+        domDevices.forEach(device -> {
+            Set<Link> devLinks = linkService.getDeviceLinks(device.id());
+            devLinks.forEach(link -> {
+                if (!link.annotations().keys().contains(SRC_DOMAIN_ID)) {
+                    intralinks.add(link);
+                }
+            });
+        });
+        return ImmutableSet.copyOf(intralinks);
+    }
+
+    private class InternalDeviceListener implements DeviceListener {
+        @Override
+        public void event(DeviceEvent event) {
+            Device device = event.subject();
+            if (!device.annotations().keys().contains(DOMAIN_ID)) {
+                return;
+            }
+            DomainId domainId = DomainId.domainId(
+                    device.annotations().value(DOMAIN_ID));
+            switch (event.type()) {
+                case DEVICE_ADDED:
+                    domainStore.addDevice(domainId, device.id());
+                    break;
+                case DEVICE_REMOVED:
+                    domainStore.removeDevice(domainId, device.id());
+                    break;
+                default:
+                    log.error("Unsupported event type: " + event.type());
+            }
+        }
+    }
+
+    private class InternalHostListener implements HostListener {
+        @Override
+        public void event(HostEvent event) {
+            Host host = event.subject();
+            if (!host.annotations().keys().contains(DOMAIN_ID)) {
+                return;
+            }
+            DomainId domainId = DomainId.domainId(
+                    host.annotations().value(DOMAIN_ID));
+            switch (event.type()) {
+                case HOST_ADDED:
+                    domainStore.addHost(domainId, host.id());
+                    break;
+                case HOST_REMOVED:
+                    domainStore.removeHost(domainId, host.id());
+                    break;
+                default:
+                    log.error("Unsupported event type: " + event.type());
+            }
+        }
+    }
+
+    private class InternalLinkListener implements LinkListener {
+        @Override
+        public void event(LinkEvent event) {
+            Link link = event.subject();
+            if (!link.annotations().keys().contains(SRC_DOMAIN_ID) ||
+                    !link.annotations().keys().contains(DST_DOMAIN_ID)) {
+                return;
+            }
+            DomainId srcDomainId = DomainId.domainId(
+                    link.annotations().value(SRC_DOMAIN_ID));
+            DomainId dstDomainId = DomainId.domainId(
+                    link.annotations().value(DST_DOMAIN_ID));
+            Pair<DomainId, DomainId> endDomains = Pair.of(srcDomainId, dstDomainId);
+            switch (event.type()) {
+                case LINK_ADDED:
+                case LINK_UPDATED:
+                    domainStore.addOrUpdateInterLink(endDomains, link);
+                    break;
+                case LINK_REMOVED:
+                    domainStore.removeInterLink(endDomains, link);
+                    break;
+                default:
+                    log.error("Unsupported event type: " + event.type());
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/package-info.java b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/package-info.java
new file mode 100644
index 0000000..5f9144e
--- /dev/null
+++ b/icona/domainmgr/src/main/java/org/onosproject/icona/domainmgr/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Icona manager implementation.
+ */
+package org.onosproject.icona.domainmgr.impl;
\ No newline at end of file
diff --git a/icona/domainprovider/pom.xml b/icona/domainprovider/pom.xml
new file mode 100644
index 0000000..2c25234
--- /dev/null
+++ b/icona/domainprovider/pom.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-icona</artifactId>
+         <version>1.7.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+  </parent>
+
+    <artifactId>onos-app-icona-domain-provider</artifactId>
+    <packaging>bundle</packaging>
+
+
+    <description>Inter Cluster Onos Network App/provider</description>
+
+    <properties>
+        <onos.app.name>org.onosproject.icona.domainprovider</onos.app.name>
+    </properties>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-api</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-core-serializers</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-osgi</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onlab-misc</artifactId>
+            <version>${onos.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.core</groupId>
+            <artifactId>jersey-client</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-app-icona-domain-manager</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+    </dependencies>
+</project>
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/DefaultDomainTopology.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/DefaultDomainTopology.java
new file mode 100644
index 0000000..511928d
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/DefaultDomainTopology.java
@@ -0,0 +1,73 @@
+/*
+ * 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.domainprovider.api;
+
+import com.google.common.collect.ImmutableSet;
+import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.icona.domainprovider.api.device.DomainDevice;
+import org.onosproject.icona.domainprovider.api.host.DomainHostDescription;
+import org.onosproject.icona.domainprovider.api.link.IntraLinkDescription;
+
+import java.util.Set;
+
+/**
+ * Default implementation of {@link DomainTopology}.
+ */
+public class DefaultDomainTopology implements DomainTopology {
+
+    private final DomainId domainId;
+    private final Set<DomainDevice> devices;
+    private final Set<IntraLinkDescription> intraLinkDescriptions;
+    private final Set<DomainHostDescription> domainHostDescriptions;
+
+    /**
+     * Creates a domain topology object with the supplied elements.
+     *
+     * @param domainId domain identifier
+     * @param devices set of devices
+     * @param intraLinkDescriptions set of links inside the domain
+     * @param domainHostDescriptions set of hosts
+     */
+    public DefaultDomainTopology(DomainId domainId, Set<DomainDevice> devices,
+                                 Set<IntraLinkDescription> intraLinkDescriptions,
+                                 Set<DomainHostDescription> domainHostDescriptions) {
+        this.domainId = domainId;
+        this.devices = devices;
+        this.intraLinkDescriptions = intraLinkDescriptions;
+        this.domainHostDescriptions = domainHostDescriptions;
+    }
+
+    @Override
+    public DomainId domainId() {
+        return domainId;
+    }
+
+    @Override
+    public Set<DomainDevice> domainDevices() {
+        return ImmutableSet.copyOf(devices);
+    }
+
+    @Override
+    public Set<IntraLinkDescription> domainLinks() {
+        return ImmutableSet.copyOf(intraLinkDescriptions);
+    }
+
+    @Override
+    public Set<DomainHostDescription> domainHosts() {
+       return ImmutableSet.copyOf(domainHostDescriptions);
+    }
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/DomainElement.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/DomainElement.java
new file mode 100644
index 0000000..4ef9c67
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/DomainElement.java
@@ -0,0 +1,32 @@
+/*
+ * 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.domainprovider.api;
+
+import org.onosproject.icona.domainmgr.api.DomainId;
+
+/**
+ * Interface implemented by the domain topology elements.
+ */
+public interface DomainElement {
+
+    /**
+     * Returns the domain id the element belongs to.
+     *
+     * @return domain id
+     */
+    DomainId domainId();
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/DomainTopology.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/DomainTopology.java
new file mode 100644
index 0000000..1d9f98b
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/DomainTopology.java
@@ -0,0 +1,46 @@
+/*
+ * 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.domainprovider.api;
+
+import org.onosproject.icona.domainprovider.api.device.DomainDevice;
+import org.onosproject.icona.domainprovider.api.host.DomainHostDescription;
+import org.onosproject.icona.domainprovider.api.link.IntraLinkDescription;
+
+import java.util.Set;
+/**
+ * Methods for describing a topology exposed by a domain.
+ */
+public interface DomainTopology extends DomainElement {
+
+    /**
+     * Returns the set of "virtual" devices of the domain.
+     * @return set of devices
+     */
+    Set<DomainDevice> domainDevices();
+
+    /**
+     * @return set of intra-links
+     */
+    Set<IntraLinkDescription> domainLinks();
+
+    /**
+     * Returns set of hosts exposed by the domain.
+     *
+     * @return set of domain hosts
+     */
+    Set<DomainHostDescription> domainHosts();
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/IconaSBListener.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/IconaSBListener.java
new file mode 100644
index 0000000..079642d
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/IconaSBListener.java
@@ -0,0 +1,30 @@
+/*
+ * 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.domainprovider.api;
+
+
+import org.onosproject.icona.domainprovider.api.device.IconaSBDeviceListener;
+import org.onosproject.icona.domainprovider.api.host.IconaSBHostListener;
+import org.onosproject.icona.domainprovider.api.link.IconaSBLinkListener;
+
+/**
+ * This interface enables a single component that implements IconaSBListenerService
+ * to orchestrate multiple southbound components implementing all the element-specific listeners.
+ */
+public interface IconaSBListener extends IconaSBDeviceListener,
+        IconaSBHostListener, IconaSBLinkListener, IconaSBTopologyListener {
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/IconaSBListenerService.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/IconaSBListenerService.java
new file mode 100644
index 0000000..fc06fea
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/IconaSBListenerService.java
@@ -0,0 +1,37 @@
+/*
+ * 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.domainprovider.api;
+
+/**
+ * Service used by the southbound components to listen for local domain events.
+ */
+public interface IconaSBListenerService {
+
+    /**
+     * Adds southbound listener to the provider.
+     *
+     * @param listener listener
+     */
+    void addListener(IconaSBListener listener);
+
+    /**
+     * Removes a southbound listener from the provider.
+     *
+     * @param listener listener
+     */
+    void removeListener(IconaSBListener listener);
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/IconaSBTopologyListener.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/IconaSBTopologyListener.java
new file mode 100644
index 0000000..58267cf
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/IconaSBTopologyListener.java
@@ -0,0 +1,44 @@
+/*
+ * 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.domainprovider.api;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.icona.domainmgr.api.DomainId;
+
+import java.util.Map;
+
+/**
+ * Methods implemented by the southbound components to send the complete local topology to another domain.
+ */
+public interface IconaSBTopologyListener {
+
+    /**
+     * Configures the local topology exposed to a domain, based on configuration policies.
+     *
+     * @param topologyMap a map with the domain id as the key and the topology object as the value
+     */
+    void configTopology(Map<DomainId, DomainTopology> topologyMap);
+
+
+    /**
+     * Remove a complete topology configuration exposed to a domain.
+     *
+     * @param domainId domain identifier
+     */
+    @Beta
+    void removeConfigTopology(DomainId domainId);
+}
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/PeerState.java
new file mode 100644
index 0000000..75f1bdf
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/PeerState.java
@@ -0,0 +1,27 @@
+/*
+ * 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.domainprovider.api;
+
+/**
+ * State of a session with a remote domain.
+ */
+public enum PeerState {
+
+    UP,
+    DOWN,
+    UNKNOWN
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/device/DefaultDomainDevice.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/device/DefaultDomainDevice.java
new file mode 100644
index 0000000..88ff89b
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/device/DefaultDomainDevice.java
@@ -0,0 +1,86 @@
+/*
+ * 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.domainprovider.api.device;
+
+import com.google.common.collect.ImmutableList;
+import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.PortDescription;
+
+import java.util.List;
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Default implementation of a domain device.
+ */
+public class DefaultDomainDevice implements DomainDevice {
+
+    private final DeviceId deviceId;
+    private final DomainId domainId;
+    private final List<PortDescription> ports;
+
+    public DefaultDomainDevice(DeviceId deviceId, DomainId domainId, List<PortDescription> ports) {
+        this.deviceId = deviceId;
+        this.domainId = domainId;
+        this.ports = ports;
+    }
+
+    @Override
+    public DeviceId deviceId() {
+        return deviceId;
+    }
+
+    @Override
+    public DomainId domainId() {
+        return domainId;
+    }
+
+    @Override
+    public List<PortDescription> ports() {
+        return ImmutableList.copyOf(ports);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), deviceId, domainId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultDomainDevice) {
+            final DefaultDomainDevice other = (DefaultDomainDevice) obj;
+            return  Objects.equals(this.deviceId, other.deviceId()) &&
+                    Objects.equals(this.domainId, other.domainId());
+
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("deviceId", deviceId.toString())
+                .add("domainId", domainId)
+                .add("ports", ports.toString())
+                .toString();
+    }
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/device/DomainDevice.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/device/DomainDevice.java
new file mode 100644
index 0000000..b5dc0df
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/device/DomainDevice.java
@@ -0,0 +1,45 @@
+/*
+ * 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.domainprovider.api.device;
+
+import org.onosproject.icona.domainprovider.api.DomainElement;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.PortDescription;
+
+import java.util.List;
+
+/**
+ * Peer domain device.
+ */
+public interface DomainDevice extends DomainElement {
+
+    /**
+     * Returns the device ID.
+     *
+     * @return device identifier
+     */
+    DeviceId deviceId();
+
+    /**
+     * Returns a list of port descriptions.
+     * These ports differ in ports where end-points (hosts) are attached to, intra-link ports
+     * and inter-link ports.
+     *
+     * @return list of port descriptions
+     */
+    List<PortDescription> ports();
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/device/IconaSBDeviceListener.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/device/IconaSBDeviceListener.java
new file mode 100644
index 0000000..9b7b4d0
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/device/IconaSBDeviceListener.java
@@ -0,0 +1,76 @@
+/*
+ * 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.domainprovider.api.device;
+
+import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.PortDescription;
+
+/**
+ * Methods implemented by the southbound components for (local topology) device events.
+ */
+public interface IconaSBDeviceListener {
+
+    /**
+     * Connects a new domain device with its list of ports to a remote domain.
+     * The first parameter is the domain ID of the receiving domain, while the domain
+     * ID inside the device parameter is the local domain identifier which is
+     * the "owner" of the device.
+     *
+     * @param domainId domain interested to this device
+     * @param device to be added
+     */
+    void connectDevice(DomainId domainId, DomainDevice device);
+
+    /**
+     * Adds a port to an existing domain device.
+     *
+     * @param domainId domain interested to this addition
+     * @param deviceId device identifier
+     * @param portDescription description of the port
+     */
+    void addPort(DomainId domainId, DeviceId deviceId, PortDescription portDescription);
+
+    /**
+     * Enables or disables a port on a domain device.
+     * No distinction between administrative and operational state currently.
+     *
+     * @param domainId domain interested to this change
+     * @param deviceId device identifier
+     * @param portNumber port identifier
+     * @param enable true if port is to be enabled, false to disable
+     */
+    void updatePortState(DomainId domainId, DeviceId deviceId, PortNumber portNumber, boolean enable);
+
+    /**
+     * Disconnects the device with the specified identifier.
+     *
+     * @param  domainId domain interested to this update
+     * @param deviceId device identifier
+     */
+    void disconnectDevice(DomainId domainId, DeviceId deviceId);
+
+    /**
+     * Removes the port with the specified identifier.
+     *
+     * @param domainId domain interested to this update
+     * @param deviceId device identifier
+     * @param portNumber port number
+     */
+    void removePort(DomainId domainId, DeviceId deviceId, PortNumber portNumber);
+}
\ No newline at end of file
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/device/IconaSBDeviceService.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/device/IconaSBDeviceService.java
new file mode 100644
index 0000000..664331a
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/device/IconaSBDeviceService.java
@@ -0,0 +1,72 @@
+/*
+ * 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.domainprovider.api.device;
+
+import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.PortDescription;
+
+/**
+ * Service used by the southbound components to advertise remote device events.
+ */
+public interface IconaSBDeviceService {
+
+    /**
+     * Signals the domain provider to connect a domain device.
+     *
+     * @param domainDevice device object
+     */
+    void connectRemoteDevice(DomainDevice domainDevice);
+
+    /**
+     * Signals the domain provider to add a new port to a domain device.
+     *
+     * @param domainId domain identifier
+     * @param deviceId device identifier
+     * @param portDescription description of the port
+     */
+    void addRemotePort(DomainId domainId, DeviceId deviceId, PortDescription portDescription);
+
+    /**
+     * Signals a remote port update.
+     *
+     * @param domainId domain identifier
+     * @param deviceId device identifier
+     * @param portDescription port description
+     */
+    void updateRemotePortState(DomainId domainId, DeviceId deviceId, PortDescription portDescription);
+
+
+    /**
+     * Signals the disconnection of a remote domain device.
+     *
+     * @param domainId domain identifier
+     * @param deviceId device identifier
+     */
+    void disconnectRemoteDevice(DomainId domainId, DeviceId deviceId);
+
+    /**
+     * Signals the deletion of a remote domain device port.
+     *
+     * @param domainId domain identifier
+     * @param deviceId device identifier
+     * @param portNumber port identifier
+     */
+    void removeRemotePort(DomainId domainId, DeviceId deviceId, PortNumber portNumber);
+
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/device/package-info.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/device/package-info.java
new file mode 100644
index 0000000..b04b14c
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/device/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Multi domain device apis.
+ */
+
+package org.onosproject.icona.domainprovider.api.device;
\ No newline at end of file
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/host/DefaultDomainHostDescription.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/host/DefaultDomainHostDescription.java
new file mode 100644
index 0000000..f8f2d22
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/host/DefaultDomainHostDescription.java
@@ -0,0 +1,155 @@
+/*
+ * 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.domainprovider.api.host;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.onlab.packet.Ip6Prefix;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onlab.packet.IpAddress;
+import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.Host;
+import org.onosproject.net.host.DefaultHostDescription;
+
+import java.util.Objects;
+import java.util.Set;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Default implementation of {@link DomainHostDescription}.
+ */
+public class DefaultDomainHostDescription extends DefaultHostDescription
+        implements DomainHostDescription {
+
+    private final DomainId domainId;
+    private final Set<Ip4Prefix> ip4Subnets;
+    private final Set<Ip6Prefix> ip6Subnets;
+
+    /**
+     * Creates an end-station host using the supplied information.
+     *
+     * @param domainId    domain identifier
+     * @param mac         host MAC address
+     * @param vlan        host VLAN identifier
+     * @param location    host location
+     * @param ips         host IP addresses
+     * @param ip4Subnets  ipv4 subnets
+     * @param annotations optional key/value annotations
+     */
+    public DefaultDomainHostDescription(DomainId domainId,
+                                        MacAddress mac,
+                                        VlanId vlan,
+                                        HostLocation location,
+                                        Set<IpAddress> ips,
+                                        Set<Ip4Prefix> ip4Subnets,
+                                        SparseAnnotations... annotations) {
+        super(mac, vlan, location, ips, annotations);
+
+        this.domainId = domainId;
+        this.ip4Subnets = ip4Subnets;
+        this.ip6Subnets = Sets.newHashSet();
+    }
+
+    /**
+     * Creates an end-station host using the supplied information.
+     *
+     * @param domainId    domain identifier
+     * @param mac         host MAC address
+     * @param vlan        host VLAN identifier
+     * @param location    host location
+     * @param ips         host IP addresses
+     * @param ip4Subnets  ipv4 subnets
+     * @param ip6Subnets  ip6 subnets
+     * @param annotations optional key/value annotations
+     */
+    public DefaultDomainHostDescription(DomainId domainId,
+                                        MacAddress mac,
+                                        VlanId vlan,
+                                        HostLocation location,
+                                        Set<IpAddress> ips,
+                                        Set<Ip4Prefix> ip4Subnets,
+                                        Set<Ip6Prefix> ip6Subnets,
+                                        SparseAnnotations... annotations) {
+        super(mac, vlan, location, ips, annotations);
+
+        this.domainId = domainId;
+        this.ip4Subnets = ip4Subnets;
+        this.ip6Subnets = ip6Subnets;
+    }
+
+    @Override
+    public DomainId domainId() {
+        return domainId;
+    }
+
+    @Override
+    public Set<Ip4Prefix> ip4Subnets() {
+        return ImmutableSet.copyOf(ip4Subnets);
+    }
+
+    @Override
+    public Set<Ip6Prefix> ip6Subnets() {
+        return ImmutableSet.copyOf(ip6Subnets);
+
+    }
+
+    @Override
+    public boolean isHost(Host host) {
+        return Objects.equals(this.hwAddress(), host.mac());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), domainId, ip4Subnets, ip6Subnets);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultDomainHostDescription) {
+            final DefaultDomainHostDescription other = (DefaultDomainHostDescription) obj;
+            return  Objects.equals(this.hwAddress(), other.hwAddress()) &&
+                    Objects.equals(this.ipAddress(), other.ipAddress()) &&
+                    Objects.equals(this.location(), other.location()) &&
+                    Objects.equals(this.domainId, other.domainId) &&
+                    Objects.equals(this.ip4Subnets, other.ip4Subnets()) &&
+                    Objects.equals(this.ip6Subnets, other.ip6Subnets());
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("mac", hwAddress())
+                .add("vlan", vlan())
+                .add("location", location())
+                .add("ipAdresses", ipAddress())
+                .add("ip4Subnets", ip4Subnets)
+                .add("ip6Subnets", ip6Subnets)
+                .add("domain", domainId)
+                .add("annotations", annotations())
+                .toString();
+    }
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/host/DomainHostDescription.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/host/DomainHostDescription.java
new file mode 100644
index 0000000..658d4ee
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/host/DomainHostDescription.java
@@ -0,0 +1,55 @@
+/*
+ * 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.domainprovider.api.host;
+
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.Ip6Prefix;
+import org.onosproject.icona.domainprovider.api.DomainElement;
+import org.onosproject.net.Host;
+import org.onosproject.net.host.HostDescription;
+
+import java.util.Set;
+
+/**
+ * Description of a host that belongs to another domain.
+ */
+public interface DomainHostDescription extends HostDescription, DomainElement {
+
+    /**
+     * Verify if the domain host corresponds to the specified host in the local domain.
+     * The domainHost will have a host location pointing to a (virtual) domain device
+     * exposed to the other domains.
+     *
+     * @param host to compare with
+     * @return true if they correspond
+     */
+    boolean isHost(Host host);
+
+    /**
+     * Returns the ipv4 subnets.
+     *
+     * @return set of ipv4 subnets
+     */
+    Set<Ip4Prefix> ip4Subnets();
+
+    /**
+     * Returns the ipv6 subnets.
+     *
+     * @return set of ipv6 subnets
+     */
+    Set<Ip6Prefix> ip6Subnets();
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/host/IconaSBHostListener.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/host/IconaSBHostListener.java
new file mode 100644
index 0000000..a4b4292
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/host/IconaSBHostListener.java
@@ -0,0 +1,52 @@
+/*
+ * 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.domainprovider.api.host;
+
+import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.net.HostId;
+
+import java.util.Set;
+
+/**
+ * Methods implemented by the southbound components to react to the (local topology) host events.
+ */
+public interface IconaSBHostListener {
+
+    /**
+     * Advertises a set of new domain hosts to a domain.
+     *
+     * @param domainId domain interested to this addition
+     * @param hosts set of hosts to add
+     */
+    void addHosts(DomainId domainId, Set<DomainHostDescription> hosts);
+
+    /**
+     * Replaces the information about an existing set of domain hosts.
+     *
+     * @param domainId domain interested to this update
+     * @param hosts set of hosts to update
+     */
+    void replaceHosts(DomainId domainId, Set<DomainHostDescription> hosts);
+
+    /**
+     * Removes a set of domain hosts exposed to a domain.
+     *
+     * @param domainId domain interested to this deletion
+     * @param hostIds set of host identifiers
+     */
+    void removeHosts(DomainId domainId, Set<HostId> hostIds);
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/host/IconaSBHostService.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/host/IconaSBHostService.java
new file mode 100644
index 0000000..fc34af4
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/host/IconaSBHostService.java
@@ -0,0 +1,53 @@
+/*
+ * 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.domainprovider.api.host;
+
+import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.net.HostId;
+
+import java.util.Set;
+
+/**
+ * Service consumed by the southbound components to advertise
+ * remote host events to the provider.
+ */
+public interface IconaSBHostService {
+
+    /**
+     * Signals the domain provider to add a set of remote domain hosts.
+     *
+     * @param domainId remote domain identifier
+     * @param domainHostDescriptions hosts to be added
+     */
+    void addRemoteHosts(DomainId domainId, Set<DomainHostDescription> domainHostDescriptions);
+
+    /**
+     * Signals the domain provider to replace the set of domain hosts.
+     *
+     * @param domainId remote domain identifier
+     * @param domainHostDescriptions hosts to be updated
+     */
+    void replaceRemoteHosts(DomainId domainId, Set<DomainHostDescription> domainHostDescriptions);
+
+    /**
+     * Signals the domain provider to remove the given remote hosts.
+     *
+     * @param domainId domain identifier
+     * @param hostIds host identifiers
+     */
+    void removeRemoteHosts(DomainId domainId, Set<HostId> hostIds);
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/host/package-info.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/host/package-info.java
new file mode 100644
index 0000000..50e88a1
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/host/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Multi domain host APIs.
+ */
+package org.onosproject.icona.domainprovider.api.host;
\ 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
new file mode 100644
index 0000000..8eac6f5
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/DefaultInterLinkDescription.java
@@ -0,0 +1,95 @@
+/*
+ * 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.domainprovider.api.link;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.link.DefaultLinkDescription;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static org.onosproject.net.Link.Type;
+
+/**
+ * Default implementation of {@link InterLinkDescription}.
+ */
+public class DefaultInterLinkDescription extends DefaultLinkDescription
+        implements InterLinkDescription {
+
+    private final Pair<DomainId, DomainId> endDomains;
+    private final LinkId id;
+
+    /**
+     * Creates an interlink using the supplied information.
+     *
+     * @param src source connect point
+     * @param dst destination connect point
+     * @param type link type
+     * @param endDomains pair of domains: source left, destination right
+     * @param id link identifier
+     * @param annotations more information
+     */
+    public DefaultInterLinkDescription(ConnectPoint src, ConnectPoint dst, Type type,
+                                       Pair<DomainId, DomainId> endDomains, LinkId id,
+                                       SparseAnnotations... annotations) {
+        super(src, dst, type, true, annotations);
+
+        this.id = id;
+        this.endDomains = endDomains;
+    }
+
+    @Override
+    public Pair<DomainId, DomainId> endDomains() {
+        return endDomains;
+    }
+
+    @Override
+    public LinkId linkId() {
+        return id;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(endDomains, id);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultInterLinkDescription) {
+            final DefaultInterLinkDescription other = (DefaultInterLinkDescription) obj;
+            return  Objects.equals(this.endDomains, other.endDomains()) &&
+                    Objects.equals(this.id, other.linkId());
+
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("endDomains", endDomains.toString())
+                .add("linkId", id)
+                .toString();
+    }
+
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/DefaultIntraLinkDescription.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/DefaultIntraLinkDescription.java
new file mode 100644
index 0000000..f647427
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/DefaultIntraLinkDescription.java
@@ -0,0 +1,94 @@
+/*
+ * 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.domainprovider.api.link;
+
+import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.link.DefaultLinkDescription;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static org.onosproject.net.Link.Type;
+
+/**
+ * Default implementation of {@link IntraLinkDescription}.
+ */
+public class DefaultIntraLinkDescription extends DefaultLinkDescription implements IntraLinkDescription {
+
+    private final DomainId domainId;
+    private final String id;
+
+    /**
+     * Creates an intra-link using the supplied information.
+     *
+     * @param src source connect point
+     * @param dst destination connect point
+     * @param type link type
+     * @param domainId domain identifier
+     * @param id link identifier
+     * @param annotations more information
+     */
+    public DefaultIntraLinkDescription(ConnectPoint src,
+                                       ConnectPoint dst, Type type,
+                                       DomainId domainId, String id,
+                                       SparseAnnotations... annotations) {
+        super(src, dst, type, true, annotations);
+
+        this.domainId = domainId;
+        this.id = id;
+    }
+
+    @Override
+    public DomainId domainId() {
+        return domainId;
+    }
+
+    @Override
+    public String linkId() {
+        return id;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(domainId, id);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultIntraLinkDescription) {
+            final DefaultIntraLinkDescription other = (DefaultIntraLinkDescription) obj;
+            return  Objects.equals(this.domainId, other.domainId()) &&
+                    Objects.equals(this.id, other.linkId());
+
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("domain", domainId)
+                .add("linkId", id)
+                .toString();
+    }
+
+}
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
new file mode 100644
index 0000000..61b56ad
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/IconaSBLinkListener.java
@@ -0,0 +1,61 @@
+/*
+ * 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.domainprovider.api.link;
+
+import org.onosproject.icona.domainmgr.api.DomainId;
+
+import static org.onosproject.net.Link.State;
+
+/**
+ *  Methods implemented by the southbound components for the (local topology) link events.
+ */
+public interface IconaSBLinkListener {
+
+    /**
+     * Advertises the presence of a link between two local domain devices.
+     *
+     * @param domainId domain interested to this addition
+     * @param link link to be added
+     */
+    void addLink(DomainId domainId, IntraLinkDescription link);
+
+    /**
+     * Updates a link state.
+     *
+     * @param domainId domain interested to this update
+     * @param linkId link identifier
+     * @param state updated state
+     */
+    void updateLinkState(DomainId domainId, LinkId linkId, State state);
+
+    /**
+     * Updates a link metric.
+     *
+     * @param domainId domain interested to this update
+     * @param linkId link identifier
+     * @param metric changed metric
+     */
+    void updateLinkMetric(DomainId domainId, LinkId linkId, int metric);
+
+    /**
+     * Removes a link.
+     *
+     * @param domainId domain interested to this update
+     * @param linkId link identifier
+     */
+    void removeLink(DomainId domainId, LinkId linkId);
+}
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
new file mode 100644
index 0000000..68470c0
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/IconaSBLinkService.java
@@ -0,0 +1,68 @@
+/*
+ * 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.domainprovider.api.link;
+
+import org.onosproject.icona.domainmgr.api.DomainId;
+
+import static org.onosproject.net.Link.State;
+
+/**
+ * Interface used by the southbound components to advertise remote host events.
+ */
+public interface IconaSBLinkService {
+
+    /**
+     * Signals the domain provider to add a remote link.
+     *
+     * @param link link to be added
+     */
+    void addRemoteLink(IntraLinkDescription link);
+
+    /**
+     * 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);
+
+    /**
+     * Signals the domain provider to change a remote link state.
+     *
+     * @param domainId domain identifier
+     * @param id link identifier
+     * @param state updated link state
+     */
+    void updateRemoteLinkState(DomainId domainId, LinkId id, State state);
+
+    /**
+     * Signals the domain provider to change a remote link metric.
+     *
+     * @param domainId domain identifier
+     * @param id link identifier
+     * @param metric updated metric
+     */
+    void updateRemoteLinkMetric(DomainId domainId, LinkId id, int metric);
+
+    /**
+     * Signals the domain provider to delete a remote link.
+     *
+     * @param domainId domain identifier
+     * @param id link identifier
+     */
+    void removeRemoteLink(DomainId domainId, LinkId id);
+}
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
new file mode 100644
index 0000000..4d620a5
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/InterLinkDescription.java
@@ -0,0 +1,42 @@
+/*
+ * 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.domainprovider.api.link;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.net.link.LinkDescription;
+
+
+/**
+ * Link between domains.
+ */
+public interface InterLinkDescription extends LinkDescription {
+
+    /**
+     * Returns the source and the destination domain ids of this interlink.
+     *
+     * @return pair of source and destination id
+     */
+    Pair<DomainId, DomainId> endDomains();
+
+    /**
+     * ID of the link.
+     *
+     * @return string ID
+     */
+    LinkId linkId();
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/IntraLinkDescription.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/IntraLinkDescription.java
new file mode 100644
index 0000000..cc9e3d7
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/IntraLinkDescription.java
@@ -0,0 +1,33 @@
+/*
+ * 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.domainprovider.api.link;
+
+import org.onosproject.icona.domainprovider.api.DomainElement;
+import org.onosproject.net.link.LinkDescription;
+
+
+/**
+ * Link between two devices of the same domain.
+ */
+public interface IntraLinkDescription extends LinkDescription, DomainElement {
+
+    /**
+     * ID of the link.
+     * @return string id
+     */
+    String linkId();
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/LinkId.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/LinkId.java
new file mode 100644
index 0000000..575d50d
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/LinkId.java
@@ -0,0 +1,33 @@
+/*
+ * 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.domainprovider.api.link;
+
+import org.onlab.util.Identifier;
+
+/**
+ * Domain link identifier class.
+ */
+public class LinkId extends Identifier<String> {
+
+    public LinkId(String identifier) {
+        super(identifier);
+    }
+
+    public static LinkId linkId(String id) {
+        return new LinkId(id);
+    }
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/package-info.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/package-info.java
new file mode 100644
index 0000000..8458e95
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/link/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/**
+ * Multi domain link apis.
+ */
+
+package org.onosproject.icona.domainprovider.api.link;
\ No newline at end of file
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/package-info.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/package-info.java
new file mode 100644
index 0000000..8fc209f
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/api/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * APIs of the ICONA multi domain domainprovider.
+ */
+package org.onosproject.icona.domainprovider.api;
\ 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/IconaRemoteDeviceProvider.java
new file mode 100644
index 0000000..ec11959
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/IconaRemoteDeviceProvider.java
@@ -0,0 +1,302 @@
+/*
+ * 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.domainprovider.impl;
+
+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.Reference;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.ChassisId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+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.domainprovider.impl.config.IconaConfig;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Device;
+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.NetworkConfigRegistry;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.device.DeviceProvider;
+import org.onosproject.net.device.DeviceProviderRegistry;
+import org.onosproject.net.device.DeviceProviderService;
+import org.onosproject.net.device.DefaultDeviceDescription;
+import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.PortDescription;
+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 java.util.concurrent.Executors.newFixedThreadPool;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.slf4j.LoggerFactory.getLogger;
+import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
+
+/**
+ * Exposes remote domain devices to the core.
+ */
+@Component(immediate = true)
+@Service(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);
+    private static final String UNKNOWN = "unknown";
+
+    private ApplicationId appId;
+    private DomainId localDomainId;
+
+    @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 DeviceProviderRegistry deviceProviderRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IconaSBLinkService iconaSBLinkService;
+
+    protected DeviceProviderService deviceProviderService;
+
+    private Set<DomainConfig> domainConfigs = Sets.newConcurrentHashSet();
+
+    private final NetworkConfigListener configListener = new InternalConfigListener();
+    private final ConfigFactory configFactory =
+            new ConfigFactory(APP_SUBJECT_FACTORY, IconaConfig.class, "icona") {
+                @Override
+                public IconaConfig createConfig() {
+                    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);
+    }
+
+    @Deactivate
+    public void deactivate() {
+        //TODO: disconnect devices
+        configService.removeListener(configListener);
+        configRegistry.unregisterConfigFactory(configFactory);
+        deviceProviderRegistry.unregister(this);
+    }
+
+    /**
+     * 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();
+
+        // disable lldp for this virtual device
+        SparseAnnotations annotations = DefaultAnnotations.builder()
+                .set("no-lldp", "lldp is disabled for a domain device")
+                .set("domainId", domainId.toString())
+                .build();
+
+        // TODO: give meaningful device info from the remote cluster
+        DeviceDescription deviceDescription = new DefaultDeviceDescription(
+                deviceId.uri(),
+                Device.Type.SWITCH,
+                UNKNOWN, UNKNOWN,
+                UNKNOWN, UNKNOWN,
+                chassisId,
+                annotations);
+        deviceProviderService.deviceConnected(deviceId, deviceDescription);
+    }
+
+    /**
+     * Notifies 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.
+     *
+     * @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);
+            ConnectPoint localCp = interlinkConf.getRight();
+            ConnectPoint remoteCp = new ConnectPoint(deviceId, port.portNumber());
+            Link.Type linkType = interlinkConf.getLeft();
+            // 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());
+            InterLinkDescription interLinkDescription2 = new DefaultInterLinkDescription(remoteCp,
+                    localCp, linkType, Pair.of(domainId, localDomainId), interLinkId, annotations1);
+            iconaSBLinkService.addInterLink(domainId, interLinkDescription1);
+            iconaSBLinkService.addInterLink(domainId, interLinkDescription2);
+        } 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();
+    }
+
+    // DeviceProvider
+    @Override
+    public void triggerProbe(DeviceId deviceId) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
+    public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
+
+    }
+
+    @Override
+    public boolean isReachable(DeviceId deviceId) {
+        // TODO
+        return true;
+    }
+
+    @Override
+    public void changePortState(DeviceId deviceId, PortNumber portNumber,
+                                boolean enable) {
+        // TODO
+    }
+
+    // IconaSBDeviceService
+    @Override
+    public void connectRemoteDevice(DomainDevice domainDevice) {
+        DomainId domainId = domainDevice.domainId();
+        DeviceId deviceId = domainDevice.deviceId();
+        advertiseDevice(deviceId, domainId);
+        advertiseDevicePorts(deviceId, domainDevice.ports());
+        domainDevice.ports().forEach(port -> {
+            if (port.annotations().keys().contains(INTER_LINK_ID)) {
+                advertiseInterlinks(domainId, deviceId, port);
+            }
+        });
+    }
+
+    @Override
+    public void addRemotePort(DomainId domainId, DeviceId deviceId, PortDescription portDescription) {
+        // TODO
+    }
+
+    @Override
+    public void updateRemotePortState(DomainId domainId, DeviceId deviceId, PortDescription portDescription) {
+        // TODO
+    }
+
+    @Override
+    public void disconnectRemoteDevice(DomainId domainId, DeviceId deviceId) {
+        // TODO
+    }
+
+    @Override
+    public void removeRemotePort(DomainId domainId, DeviceId deviceId, PortNumber portNumber) {
+        // TODO
+    }
+
+    private void readConfig() {
+        IconaConfig iconaConfig =
+                configRegistry.getConfig(appId, IconaConfig.class);
+        localDomainId = iconaConfig.getLocalId();
+        domainConfigs.addAll(
+                iconaConfig.getPeersConfig());
+    }
+
+    private class InternalConfigListener implements NetworkConfigListener {
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+            if (!event.configClass().equals(IconaConfig.class)) {
+                return;
+            }
+            switch (event.type()) {
+                case CONFIG_ADDED:
+                    log.info("Network configuration added");
+                    eventExecutor.execute(IconaRemoteDeviceProvider.this::readConfig);
+                    break;
+                case CONFIG_UPDATED:
+                    log.info("Network configuration updated");
+                    eventExecutor.execute(IconaRemoteDeviceProvider.this::readConfig);
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
\ No newline at end of file
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/IconaRemoteHostProvider.java
new file mode 100644
index 0000000..2e54b8d
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/IconaRemoteHostProvider.java
@@ -0,0 +1,120 @@
+/*
+ * 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.domainprovider.impl;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onosproject.core.CoreService;
+import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.icona.domainprovider.api.host.DomainHostDescription;
+import org.onosproject.icona.domainprovider.api.host.IconaSBHostService;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.host.HostProvider;
+import org.onosproject.net.host.HostProviderService;
+import org.onosproject.net.host.HostProviderRegistry;
+import org.onosproject.net.provider.ProviderId;
+import org.slf4j.Logger;
+
+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;
+
+/**
+ * Exposes remote domain hosts to the core.
+ */
+@Component(immediate = true)
+@Service(IconaSBHostService.class)
+public class IconaRemoteHostProvider implements HostProvider, IconaSBHostService {
+
+    private final Logger log = getLogger(getClass());
+
+    private static final boolean REPLACE_IPS = true;
+    private static final boolean MERGE_IPS = false;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostProviderRegistry hostProviderRegistry;
+
+    protected HostProviderService hostProviderService;
+
+    @Override
+    public ProviderId id() {
+        return PROVIDER_ID;
+    }
+
+    @Activate
+    public void activate() {
+        coreService.registerApplication(PROVIDER_NAME);
+        hostProviderService = hostProviderRegistry.register(this);
+    }
+
+    @Deactivate
+    public void deactivate() {
+        hostProviderRegistry.unregister(this);
+    }
+
+
+    /**
+     * Notify the core system that a new host is reachable through a domain device.
+     *
+     * @param domainHostDescription host description of the remote host
+     */
+    private void advertiseHost(DomainHostDescription domainHostDescription) {
+        HostId hostId = HostId.hostId(domainHostDescription.hwAddress(), domainHostDescription.vlan());
+        hostProviderService.hostDetected(hostId, domainHostDescription, REPLACE_IPS);
+    }
+
+    /**
+     * Remove a remote domain host.
+     *
+     * @param hostId id of the vanished host
+     */
+    private void removeHost(HostId hostId) {
+        hostProviderService.hostVanished(hostId);
+    }
+
+    // IconaSBHostService interface
+    @Override
+    public void addRemoteHosts(DomainId domainId, Set<DomainHostDescription> domainHostDescriptions) {
+        // TODO
+    }
+
+    @Override
+    public void replaceRemoteHosts(DomainId domainId, Set<DomainHostDescription> domainHostDescriptions) {
+        // TODO
+    }
+
+    @Override
+    public void removeRemoteHosts(DomainId domainId, Set<HostId> hostIds) {
+        // TODO
+    }
+
+    // HostProvider interface
+    @Override
+    public void triggerProbe(Host host) {
+        // TODO Auto-generated method stub
+    }
+}
\ No newline at end of file
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/IconaRemoteLinkProvider.java
new file mode 100644
index 0000000..35485ac
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/IconaRemoteLinkProvider.java
@@ -0,0 +1,102 @@
+/*
+ * 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.domainprovider.impl;
+
+import com.google.common.annotations.Beta;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onosproject.core.CoreService;
+import org.onosproject.icona.domainmgr.api.DomainId;
+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.net.Link;
+import org.onosproject.net.link.LinkProvider;
+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.slf4j.LoggerFactory.getLogger;
+import static org.onosproject.icona.domainprovider.impl.IconaRemoteDeviceProvider.PROVIDER_ID;
+import static org.onosproject.icona.domainprovider.impl.IconaRemoteDeviceProvider.PROVIDER_NAME;
+
+/**
+ * Exposes remote domain links to the core.
+ */
+@Component(immediate = true)
+@Service(IconaSBLinkService.class)
+public class IconaRemoteLinkProvider implements LinkProvider, IconaSBLinkService {
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkProviderRegistry linkProviderRegistry;
+
+    protected LinkProviderService linkProviderService;
+
+    @Override
+    public ProviderId id() {
+        return PROVIDER_ID;
+    }
+
+    @Activate
+    public void activate() {
+        coreService.registerApplication(PROVIDER_NAME);
+        linkProviderService = linkProviderRegistry.register(this);
+    }
+
+    @Deactivate
+    public void deactivate() {
+        linkProviderRegistry.unregister(this);
+    }
+
+    // IconaSBLinkService
+    @Override
+    public void addRemoteLink(IntraLinkDescription link) {
+        // TODO
+    }
+
+    @Override
+    public void addInterLink(DomainId domainId, InterLinkDescription link) {
+    }
+
+    @Override
+    public void updateRemoteLinkState(DomainId domainId, LinkId id, Link.State state) {
+        // TODO
+    }
+
+    @Override
+    @Beta
+    public void updateRemoteLinkMetric(DomainId domainId, LinkId id, int metric) {
+        // TODO
+        // the metric is meaningful only among links within the same domain and only if there is trust between domains
+    }
+
+    @Override
+    public void removeRemoteLink(DomainId domainId, LinkId id) {
+        // TODO
+    }
+}
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/IconaTopologyManager.java
new file mode 100644
index 0000000..4050a2e
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/IconaTopologyManager.java
@@ -0,0 +1,336 @@
+/*
+ * 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.domainprovider.impl;
+
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+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.onlab.packet.Ip4Prefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.icona.domainmgr.api.DomainId;
+import org.onosproject.icona.domainprovider.api.DomainTopology;
+import org.onosproject.icona.domainprovider.api.DefaultDomainTopology;
+import org.onosproject.icona.domainprovider.api.IconaSBListener;
+import org.onosproject.icona.domainprovider.api.IconaSBListenerService;
+import org.onosproject.icona.domainprovider.api.device.DefaultDomainDevice;
+import org.onosproject.icona.domainprovider.api.device.DomainDevice;
+import org.onosproject.icona.domainprovider.api.host.DefaultDomainHostDescription;
+import org.onosproject.icona.domainprovider.api.host.DomainHostDescription;
+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.PortNumber;
+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;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.link.LinkEvent;
+import org.onosproject.net.link.LinkListener;
+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.ArrayList;
+import java.util.HashSet;
+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.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(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 INTER_LINK_ID = "interlinkId";
+
+    private static DomainId localDomainId;
+
+    private final Logger log = getLogger(IconaTopologyManager.class);
+
+    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 DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LinkService linkService;
+
+    private final ConfigFactory configFactory =
+            new ConfigFactory(APP_SUBJECT_FACTORY, IconaConfig.class, "icona") {
+                @Override
+                public IconaConfig createConfig() {
+                    return new IconaConfig();
+                }
+            };
+
+    private final ExecutorService eventExecutor =
+            newFixedThreadPool(3, groupedThreads("onos/icona-sb-manager", "event-handler-%d"));
+
+    private Set<DomainConfig> domainConfigs = Sets.newConcurrentHashSet();
+    private Set<IconaSBListener> sbListeners = new CopyOnWriteArraySet<>();
+
+    private final NetworkConfigListener configListener = new InternalConfigListener();
+    private final LocalDeviceListener deviceListener = new LocalDeviceListener();
+    private final LocalHostListener hostListener = new LocalHostListener();
+    private final LocalLinkListener linkListener = new LocalLinkListener();
+
+    @Activate
+    public void activate() {
+        appId = coreService.registerApplication(PROVIDER_NAME);
+        configRegistry.registerConfigFactory(configFactory);
+        configService.addListener(configListener);
+
+        deviceService.addListener(deviceListener);
+        linkService.addListener(linkListener);
+        hostService.addListener(hostListener);
+    }
+
+    @Deactivate
+    public void deactivate() {
+        eventExecutor.shutdown();
+        deviceService.removeListener(deviceListener);
+        linkService.removeListener(linkListener);
+        hostService.removeListener(hostListener);
+
+        configService.removeListener(configListener);
+        configRegistry.unregisterConfigFactory(configFactory);
+    }
+
+    @Override
+    public void addListener(IconaSBListener sbListener) {
+        sbListeners.add(sbListener);
+    }
+
+    @Override
+    public void removeListener(IconaSBListener sbListener) {
+        sbListeners.remove(sbListener);
+    }
+
+    private class LocalDeviceListener implements DeviceListener {
+
+        @Override
+        public void event(DeviceEvent event) {
+            switch (event.type()) {
+                case DEVICE_ADDED:
+                    // TODO: check config policy and the impact on the local topology exposed to the peers
+                    break;
+                case DEVICE_REMOVED:
+                    // TODO: check config policy and the impact on the local topology exposed to the peers
+                    break;
+                case DEVICE_SUSPENDED:
+                    // TODO: check config policy and the impact on the local topology exposed to the peers
+                    break;
+                case PORT_REMOVED:
+                    // TODO: check config policy and the impact on the local topology exposed to the peers
+                    break;
+                case PORT_ADDED:
+                    // TODO: check config policy and the impact on the local topology exposed to the peers
+                    break;
+                default:
+            }
+        }
+    }
+
+    private class LocalHostListener implements HostListener {
+        @Override
+        public void event(HostEvent event) {
+            switch (event.type()) {
+                case HOST_ADDED:
+                    // 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
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    private class LocalLinkListener implements LinkListener {
+
+        @Override
+        public void event(LinkEvent event) {
+            switch (event.type()) {
+                case LINK_ADDED:
+                    // TODO: check config policy and the impact on the local topology exposed to the peers
+                    break;
+                case LINK_REMOVED:
+                    // TODO: check config policy and the impact on the local topology exposed to the peers
+                    break;
+                case LINK_UPDATED:
+                    // TODO: check config policy and the impact on the local topology exposed to the peers
+                default:
+            }
+        }
+    }
+
+    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");
+
+        IconaConfig iconaConfig =
+                configRegistry.getConfig(appId, IconaConfig.class);
+
+        localDomainId = iconaConfig.getLocalId();
+
+        domainConfigs.addAll(
+                iconaConfig.getPeersConfig());
+
+        // TODO: different topology for different TopologyConfig.Type values
+        buildBigSwitch(iconaConfig.getBigSwitchPrefixId());
+    }
+
+    private class InternalConfigListener implements NetworkConfigListener {
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+            if (!event.configClass().equals(IconaConfig.class)) {
+                return;
+            }
+            switch (event.type()) {
+                case CONFIG_ADDED:
+                    log.info("Network configuration added");
+                    eventExecutor.execute(IconaTopologyManager.this::readConfig);
+                    break;
+                case CONFIG_UPDATED:
+                    log.info("Network configuration updated");
+                    eventExecutor.execute(IconaTopologyManager.this::readConfig);
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
\ No newline at end of file
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
new file mode 100644
index 0000000..e9ee7f6
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/config/IconaConfig.java
@@ -0,0 +1,191 @@
+/*
+ * 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.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
+ */
+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 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 END_POINTS = "endPointIds";
+
+    /**
+     * 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.
+     *
+     * @return big switch identifier
+     */
+    public String getBigSwitchPrefixId() {
+        return object.get(BIG_SWITCH_PREFIX_ID).asText();
+    }
+
+    /**
+     * Parses the list of peers from the configuration json object.
+     *
+     * @return set of domain configuration objects
+     */
+    public Set<DomainConfig> getPeersConfig() {
+
+        Set<DomainConfig> peers = Sets.newHashSet();
+
+        JsonNode peerNodes = object.get(PEERS);
+
+        peerNodes.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")
+                    .asText()) {
+                case "bigSwitch":
+                    type = BIG_SWITCH;
+                    break;
+                case "fullMesh":
+                    type = FULL_MESH;
+                    break;
+                default:
+                    type = TopologyConfig.Type.BIG_SWITCH;
+            }
+            ArrayList<String> endPointIds = new ArrayList<>();
+            topologyNode.path(END_POINTS).forEach(
+                    endPointId -> endPointIds.add(endPointId.asText())
+            );
+            TopologyConfig topologyConfig = new TopologyConfig(type, endPointIds);
+
+            peers.add(new DomainConfig(domainId, interLinkConnectPointMap, topologyConfig));
+        });
+
+        return peers;
+    }
+
+    /**
+     * Domain configuration class.
+     */
+    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) {
+            this.domainId = checkNotNull(domainId);
+            this.interLinkConnectPointMap = interLinkConnectPointMap;
+            this.topologyConfig = topologyConfig;
+        }
+
+        public DomainId peerId() {
+            return domainId;
+        }
+
+        public Map<LinkId, Pair<Link.Type, ConnectPoint>> interLinkConnectPointMap() {
+            return interLinkConnectPointMap;
+        }
+
+        public TopologyConfig topologyConfig() {
+            return topologyConfig;
+        }
+
+    }
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/config/TopologyConfig.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/config/TopologyConfig.java
new file mode 100644
index 0000000..31f4274
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/config/TopologyConfig.java
@@ -0,0 +1,69 @@
+/*
+ * 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.domainprovider.impl.config;
+
+
+import java.util.List;
+
+/**
+ * Topology config policy class.
+ * Depending on the topology abstraction type, the end-points will reside on some virtual devices,
+ * currently only BIG_SWITCH (one device) and FULL_MESH (as many devices as those where the end-points, or hosts,
+ * are attached to) are supported.
+ * The concept of end-points is still to be defined, currently it is a mac address of a NIC.
+ */
+public class TopologyConfig {
+
+    /**
+     * Type of topology exposed to/from a domain.
+     */
+    public enum Type {
+        BIG_SWITCH,
+        FULL_MESH
+    }
+
+    private Type type;
+    private List<String> endPointIds;
+
+    /**
+     * Creates a topology configuration object using the supplied information.
+     *
+     * @param type topology type
+     * @param endPointIds list of end-point mac addresses
+     */
+    public TopologyConfig(Type type, List<String> endPointIds) {
+        this.type = type;
+        this.endPointIds = endPointIds;
+    }
+
+    /**
+     * Returns the type of topology abstraction for a specific domain.
+     */
+    public Type type() {
+        return type;
+    }
+
+    /**
+     * Returns the list of end points that are exposed to a specific domain.
+     *
+     * @return list of endpoints
+     */
+    public List<String> endPointIds() {
+        return endPointIds;
+    }
+
+}
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/config/package-info.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/config/package-info.java
new file mode 100644
index 0000000..6d8ec1c
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/config/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Configuration package.
+ */
+package org.onosproject.icona.domainprovider.impl.config;
\ No newline at end of file
diff --git a/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/package-info.java b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/package-info.java
new file mode 100644
index 0000000..693c2ec
--- /dev/null
+++ b/icona/domainprovider/src/main/java/org/onosproject/icona/domainprovider/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Icona domainprovider implementation.
+ */
+package org.onosproject.icona.domainprovider.impl;
\ No newline at end of file
diff --git a/icona/pom.xml b/icona/pom.xml
new file mode 100644
index 0000000..f309754
--- /dev/null
+++ b/icona/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.onosproject</groupId>
+        <artifactId>onos-app-samples</artifactId>
+        <version>1.7.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>onos-icona</artifactId>
+    <version>1.7.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>app</module>
+        <module>domainmgr</module>
+        <module>domainprovider</module>
+    </modules>
+</project>
\ No newline at end of file
diff --git a/icona/tools/sample_configs/multidomain-config.json b/icona/tools/sample_configs/multidomain-config.json
new file mode 100644
index 0000000..537abb8
--- /dev/null
+++ b/icona/tools/sample_configs/multidomain-config.json
@@ -0,0 +1,31 @@
+{
+     "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"
+                              ]
+                            }
+                    }
+                ]
+            }
+        }
+    }
+}
diff --git a/pom.xml b/pom.xml
index cd307a9..fdda7db 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,7 +13,8 @@
   ~ 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.
-  --><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
@@ -41,6 +42,7 @@
         <module>uiref</module>
         <module>ecord/co</module>
         <module>ecord/carrierethernet</module>
+        <module>icona</module>
     </modules>
 
     <properties>