diff --git a/apps/inbandtelemetry/impl/src/main/java/org/onosproject/inbandtelemetry/impl/IntManager.java b/apps/inbandtelemetry/impl/src/main/java/org/onosproject/inbandtelemetry/impl/IntManager.java
deleted file mode 100644
index 5cf32da..0000000
--- a/apps/inbandtelemetry/impl/src/main/java/org/onosproject/inbandtelemetry/impl/IntManager.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Foundation
- *
- * 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.inbandtelemetry.impl;
-
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.Service;
-import org.onlab.util.KryoNamespace;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.inbandtelemetry.api.IntConfig;
-import org.onosproject.inbandtelemetry.api.IntIntent;
-import org.onosproject.inbandtelemetry.api.IntIntentId;
-import org.onosproject.inbandtelemetry.api.IntObjective;
-import org.onosproject.inbandtelemetry.api.IntProgrammable;
-import org.onosproject.inbandtelemetry.api.IntService;
-import org.onosproject.net.Device;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.flow.FlowRuleService;
-import org.onosproject.net.host.HostEvent;
-import org.onosproject.net.host.HostListener;
-import org.onosproject.net.host.HostService;
-import org.onosproject.store.serializers.KryoNamespaces;
-import org.onosproject.store.service.AtomicIdGenerator;
-import org.onosproject.store.service.ConsistentMap;
-import org.onosproject.store.service.Serializer;
-import org.onosproject.store.service.StorageService;
-import org.slf4j.Logger;
-
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * Implementation of IntService, for controlling INT-capable pipelines.
- */
-@Component(immediate = true)
-@Service
-public class IntManager implements IntService {
-    private final String appName = "org.onosproject.inbandtelemetry";
-    private ApplicationId appId;
-    private final Logger log = getLogger(getClass());
-    private ConsistentMap<IntIntentId, IntIntent> intentConsistentMap;
-    private ConsistentMap<DeviceId, IntDeviceRole> deviceRoleConsistentMap;
-    private IntConfig cfg;
-    private AtomicIdGenerator intentIds;
-
-    private InternalHostListener hostListener = new InternalHostListener();
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    private CoreService coreService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    private DeviceService deviceService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    private StorageService storageService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    private HostService hostService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    private FlowRuleService flowRuleService;
-
-    @Activate
-    public void activate() {
-        appId = coreService.registerApplication(appName);
-
-        KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
-                .register(KryoNamespaces.API)
-                .register(IntIntent.class)
-                .register(IntIntentId.class)
-                .register(IntDeviceRole.class)
-                .register(IntIntent.IntHeaderType.class)
-                .register(IntIntent.IntMetadataType.class)
-                .register(IntIntent.IntReportType.class)
-                .register(IntIntent.TelemetryMode.class);
-
-        intentConsistentMap = storageService.<IntIntentId, IntIntent>consistentMapBuilder()
-                .withSerializer(Serializer.using(serializer.build()))
-                .withName("int-intents")
-                .withApplicationId(appId)
-                .withPurgeOnUninstall()
-                .build();
-
-        deviceRoleConsistentMap = storageService.<DeviceId, IntDeviceRole>consistentMapBuilder()
-                .withSerializer(Serializer.using(serializer.build()))
-                .withName("int-device-roles")
-                .withApplicationId(appId)
-                .withPurgeOnUninstall()
-                .build();
-
-        // Assign IntDeviceRole to each device
-        deviceService.getAvailableDevices().forEach(device ->
-                deviceRoleConsistentMap.put(device.id(),
-                                            hostService.getConnectedHosts(device.id()).isEmpty() ?
-                                                    IntDeviceRole.TRANSIT :
-                                                    IntDeviceRole.SOURCE_SINK)
-        );
-        hostService.addListener(hostListener);
-        intentIds = storageService.getAtomicIdGenerator("int-intent-id-generator");
-        startInt();
-        log.info("Started", appId.id());
-    }
-
-    @Deactivate
-    public void deactivate() {
-        hostService.removeListener(hostListener);
-        log.info("Deactivated");
-    }
-
-    @Override
-    public void startInt() {
-        deviceService.getAvailableDevices().forEach(device -> {
-            if (device.is(IntProgrammable.class)) {
-                IntProgrammable intDevice = device.as(IntProgrammable.class);
-                intDevice.init();
-            }
-        });
-    }
-
-    @Override
-    public void startInt(Set<DeviceId> deviceIds) {
-        deviceIds.forEach(deviceId -> {
-            Device device = deviceService.getDevice(deviceId);
-            if (device.is(IntProgrammable.class) &&
-                    getIntRole(deviceId) == IntDeviceRole.TRANSIT) {
-                IntProgrammable intDevice = device.as(IntProgrammable.class);
-                intDevice.init();
-            }
-        });
-    }
-
-    @Override
-    public void stopInt() {
-        flowRuleService.removeFlowRulesById(appId);
-    }
-
-    @Override
-    public void stopInt(Set<DeviceId> deviceIds) {
-
-    }
-
-    @Override
-    public void setConfig(IntConfig cfg) {
-        this.cfg = cfg;
-        deviceService.getAvailableDevices().forEach(device -> {
-            if (device.is(IntProgrammable.class)) {
-                IntProgrammable intDevice = device.as(IntProgrammable.class);
-                intDevice.setupIntConfig(cfg);
-            }
-        });
-    }
-
-    @Override
-    public IntConfig getConfig() {
-        return cfg;
-    }
-
-    @Override
-    public IntIntentId installIntIntent(IntIntent intent) {
-        Integer intentId = (int) intentIds.nextId();
-        IntIntentId intIntentId = IntIntentId.valueOf(intentId);
-        intentConsistentMap.put(intIntentId, intent);
-
-        // Convert IntIntent into an IntObjective
-        IntObjective obj = new IntObjective.Builder()
-                .withSelector(intent.selector())
-                .withMetadataTypes(intent.metadataTypes())
-                .withHeaderType(intent.headerType())
-                .build();
-
-        // Install IntObjective on each INT source device
-        deviceService.getAvailableDevices().forEach(device -> {
-            if (device.is(IntProgrammable.class)
-                    && deviceRoleConsistentMap.get(device.id()).value() == IntDeviceRole.SOURCE_SINK) {
-                IntProgrammable intDevice = device.as(IntProgrammable.class);
-                intDevice.addIntObjective(obj);
-            }
-        });
-        return intIntentId;
-    }
-
-    @Override
-    public void removeIntIntent(IntIntentId intentId) {
-        IntIntent intent = intentConsistentMap.remove(intentId).value();
-
-        // Convert IntIntent into an IntObjective
-        IntObjective obj = new IntObjective.Builder()
-                .withSelector(intent.selector())
-                .withMetadataTypes(intent.metadataTypes())
-                .withHeaderType(intent.headerType())
-                .build();
-
-        // Remove IntObjective on each INT source device
-        deviceService.getAvailableDevices().forEach(device -> {
-            if (device.is(IntProgrammable.class)
-                    && deviceRoleConsistentMap.get(device.id()).value() == IntDeviceRole.SOURCE_SINK) {
-                IntProgrammable intDevice = device.as(IntProgrammable.class);
-                intDevice.removeIntObjective(obj);
-            }
-        });
-    }
-
-    @Override
-    public IntIntent getIntIntent(IntIntentId intentId) {
-        return Optional.ofNullable(intentConsistentMap.get(intentId).value()).orElse(null);
-    }
-
-    @Override
-    public Map<IntIntentId, IntIntent> getIntIntents() {
-        return intentConsistentMap.asJavaMap();
-    }
-
-    private IntDeviceRole getIntRole(DeviceId deviceId) {
-        return deviceRoleConsistentMap.get(deviceId).value();
-    }
-
-    private void setIntRole(DeviceId deviceId, IntDeviceRole role) {
-        deviceRoleConsistentMap.put(deviceId, role);
-    }
-
-    private class InternalHostListener implements HostListener {
-        @Override
-        public void event(HostEvent event) {
-            DeviceId deviceId = event.subject().location().deviceId();
-            if (!deviceService.getDevice(deviceId).is(IntProgrammable.class)) {
-                return;
-            }
-            switch (event.type()) {
-                case HOST_ADDED:
-                    // When a host is attached to the switch, we can configure it
-                    // to work as SOURCE_SINK switch.
-                    if (deviceRoleConsistentMap.getOrDefault(deviceId, IntDeviceRole.TRANSIT).value()
-                            != IntDeviceRole.SOURCE_SINK) {
-                        setIntRole(deviceId, IntDeviceRole.SOURCE_SINK);
-                    }
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
-
-}
diff --git a/apps/inbandtelemetry/impl/src/main/java/org/onosproject/inbandtelemetry/impl/SimpleIntManager.java b/apps/inbandtelemetry/impl/src/main/java/org/onosproject/inbandtelemetry/impl/SimpleIntManager.java
new file mode 100644
index 0000000..56ee52b
--- /dev/null
+++ b/apps/inbandtelemetry/impl/src/main/java/org/onosproject/inbandtelemetry/impl/SimpleIntManager.java
@@ -0,0 +1,527 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * 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.inbandtelemetry.impl;
+
+import com.google.common.collect.Maps;
+import com.google.common.util.concurrent.Striped;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.util.KryoNamespace;
+import org.onlab.util.SharedScheduledExecutors;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.inbandtelemetry.api.IntConfig;
+import org.onosproject.inbandtelemetry.api.IntIntent;
+import org.onosproject.inbandtelemetry.api.IntIntentId;
+import org.onosproject.inbandtelemetry.api.IntObjective;
+import org.onosproject.inbandtelemetry.api.IntProgrammable;
+import org.onosproject.inbandtelemetry.api.IntService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.MastershipRole;
+import org.onosproject.net.PortNumber;
+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.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.AtomicIdGenerator;
+import org.onosproject.store.service.AtomicValue;
+import org.onosproject.store.service.AtomicValueEvent;
+import org.onosproject.store.service.AtomicValueEventListener;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.MapEvent;
+import org.onosproject.store.service.MapEventListener;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.Versioned;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.locks.Lock;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Simple implementation of IntService, for controlling INT-capable pipelines.
+ * <p>
+ * All INT intents are converted to an equivalent INT objective and applied to
+ * all SOURCE_SINK devices. A device is deemed SOURCE_SINK if it has at least
+ * one host attached.
+ * <p>
+ * The implementation listens for different types of events and when required it
+ * configures a device by cleaning-up any previous state and applying the new
+ * one.
+ */
+@Component(immediate = true)
+@Service
+public class SimpleIntManager implements IntService {
+
+    private final Logger log = getLogger(getClass());
+
+    private static final int CONFIG_EVENT_DELAY = 5; // Seconds.
+
+    private static final String APP_NAME = "org.onosproject.inbandtelemetry";
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private StorageService storageService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    private HostService hostService;
+
+    private final Striped<Lock> deviceLocks = Striped.lock(10);
+
+    private final ConcurrentMap<DeviceId, ScheduledFuture<?>> scheduledDeviceTasks = Maps.newConcurrentMap();
+
+    // Distributed state.
+    private ConsistentMap<IntIntentId, IntIntent> intentMap;
+    private ConsistentMap<DeviceId, Long> devicesToConfigure;
+    private AtomicValue<IntConfig> intConfig;
+    private AtomicValue<Boolean> intStarted;
+    private AtomicIdGenerator intentIds;
+
+    // Event listeners.
+    private final InternalHostListener hostListener = new InternalHostListener();
+    private final InternalDeviceListener deviceListener = new InternalDeviceListener();
+    private final InternalIntentMapListener intentMapListener = new InternalIntentMapListener();
+    private final InternalIntConfigListener intConfigListener = new InternalIntConfigListener();
+    private final InternalIntStartedListener intStartedListener = new InternalIntStartedListener();
+    private final InternalDeviceToConfigureListener devicesToConfigureListener =
+            new InternalDeviceToConfigureListener();
+
+    @Activate
+    public void activate() {
+
+        final ApplicationId appId = coreService.registerApplication(APP_NAME);
+
+        KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
+                .register(KryoNamespaces.API)
+                .register(IntIntent.class)
+                .register(IntIntentId.class)
+                .register(IntDeviceRole.class)
+                .register(IntIntent.IntHeaderType.class)
+                .register(IntIntent.IntMetadataType.class)
+                .register(IntIntent.IntReportType.class)
+                .register(IntIntent.TelemetryMode.class)
+                .register(IntConfig.class)
+                .register(IntConfig.TelemetrySpec.class);
+
+        devicesToConfigure = storageService.<DeviceId, Long>consistentMapBuilder()
+                .withSerializer(Serializer.using(serializer.build()))
+                .withName("onos-int-devices-to-configure")
+                .withApplicationId(appId)
+                .withPurgeOnUninstall()
+                .build();
+        devicesToConfigure.addListener(devicesToConfigureListener);
+
+        intentMap = storageService.<IntIntentId, IntIntent>consistentMapBuilder()
+                .withSerializer(Serializer.using(serializer.build()))
+                .withName("onos-int-intents")
+                .withApplicationId(appId)
+                .withPurgeOnUninstall()
+                .build();
+        intentMap.addListener(intentMapListener);
+
+        intStarted = storageService.<Boolean>atomicValueBuilder()
+                .withSerializer(Serializer.using(serializer.build()))
+                .withName("onos-int-started")
+                .withApplicationId(appId)
+                .build()
+                .asAtomicValue();
+        intStarted.addListener(intStartedListener);
+
+        intConfig = storageService.<IntConfig>atomicValueBuilder()
+                .withSerializer(Serializer.using(serializer.build()))
+                .withName("onos-int-config")
+                .withApplicationId(appId)
+                .build()
+                .asAtomicValue();
+        intConfig.addListener(intConfigListener);
+
+        intentIds = storageService.getAtomicIdGenerator("int-intent-id-generator");
+
+        // Bootstrap config for already existing devices.
+        triggerAllDeviceConfigure();
+
+        hostService.addListener(hostListener);
+        deviceService.addListener(deviceListener);
+
+        startInt();
+        log.info("Started", appId.id());
+    }
+
+    @Deactivate
+    public void deactivate() {
+        deviceService.removeListener(deviceListener);
+        hostService.removeListener(hostListener);
+        intentIds = null;
+        intConfig.removeListener(intConfigListener);
+        intConfig = null;
+        intStarted.removeListener(intStartedListener);
+        intStarted = null;
+        intentMap.removeListener(intentMapListener);
+        intentMap = null;
+        devicesToConfigure.removeListener(devicesToConfigureListener);
+        devicesToConfigure.destroy();
+        devicesToConfigure = null;
+        // Cancel tasks (if any).
+        scheduledDeviceTasks.values().forEach(f -> {
+            f.cancel(true);
+            if (!f.isDone()) {
+                try {
+                    f.get(1, TimeUnit.SECONDS);
+                } catch (InterruptedException | ExecutionException | TimeoutException e) {
+                    // Don't care, we are terminating the service anyways.
+                }
+            }
+        });
+        // Clean up INT rules from existing devices.
+        deviceService.getDevices().forEach(d -> cleanupDevice(d.id()));
+        log.info("Deactivated");
+    }
+
+    @Override
+    public void startInt() {
+        // Atomic value event will trigger device configure.
+        intStarted.set(true);
+    }
+
+    @Override
+    public void startInt(Set<DeviceId> deviceIds) {
+        log.warn("Starting INT for a subset of devices is not supported");
+    }
+
+    @Override
+    public void stopInt() {
+        // Atomic value event will trigger device configure.
+        intStarted.set(false);
+    }
+
+    @Override
+    public void stopInt(Set<DeviceId> deviceIds) {
+        log.warn("Stopping INT for a subset of devices is not supported");
+    }
+
+    @Override
+    public void setConfig(IntConfig cfg) {
+        checkNotNull(cfg);
+        // Atomic value event will trigger device configure.
+        intConfig.set(cfg);
+    }
+
+    @Override
+    public IntConfig getConfig() {
+        return intConfig.get();
+    }
+
+    @Override
+    public IntIntentId installIntIntent(IntIntent intent) {
+        checkNotNull(intent);
+        final Integer intentId = (int) intentIds.nextId();
+        final IntIntentId intIntentId = IntIntentId.valueOf(intentId);
+        // Intent map event will trigger device configure.
+        intentMap.put(intIntentId, intent);
+        return intIntentId;
+    }
+
+    @Override
+    public void removeIntIntent(IntIntentId intentId) {
+        checkNotNull(intentId);
+        // Intent map event will trigger device configure.
+        intentMap.remove(intentId).value();
+    }
+
+    @Override
+    public IntIntent getIntIntent(IntIntentId intentId) {
+        return Optional.ofNullable(intentMap.get(intentId).value()).orElse(null);
+    }
+
+    @Override
+    public Map<IntIntentId, IntIntent> getIntIntents() {
+        return intentMap.asJavaMap();
+    }
+
+    private boolean isConfigTaskValid(DeviceId deviceId, long creationTime) {
+        Versioned<?> versioned = devicesToConfigure.get(deviceId);
+        return versioned != null && versioned.creationTime() == creationTime;
+    }
+
+    private boolean isIntStarted() {
+        return intStarted.get();
+    }
+
+    private boolean isNotIntConfigured() {
+        return intConfig.get() == null;
+    }
+
+    private boolean isIntProgrammable(DeviceId deviceId) {
+        final Device device = deviceService.getDevice(deviceId);
+        return device != null && device.is(IntProgrammable.class);
+    }
+
+    private void triggerDeviceConfigure(DeviceId deviceId) {
+        if (isIntProgrammable(deviceId)) {
+            devicesToConfigure.put(deviceId, System.nanoTime());
+        }
+    }
+
+    private void triggerAllDeviceConfigure() {
+        deviceService.getDevices().forEach(d -> triggerDeviceConfigure(d.id()));
+    }
+
+    private void configDeviceTask(DeviceId deviceId, long creationTime) {
+        if (isConfigTaskValid(deviceId, creationTime)) {
+            // Task outdated.
+            return;
+        }
+        if (!deviceService.isAvailable(deviceId)) {
+            return;
+        }
+        final MastershipRole role = mastershipService.requestRoleForSync(deviceId);
+        if (!role.equals(MastershipRole.MASTER)) {
+            return;
+        }
+        deviceLocks.get(deviceId).lock();
+        try {
+            // Clean up first.
+            cleanupDevice(deviceId);
+            if (!configDevice(deviceId)) {
+                // Clean up if fails.
+                cleanupDevice(deviceId);
+                return;
+            }
+            devicesToConfigure.remove(deviceId);
+        } finally {
+            deviceLocks.get(deviceId).unlock();
+        }
+    }
+
+    private void cleanupDevice(DeviceId deviceId) {
+        final Device device = deviceService.getDevice(deviceId);
+        if (device == null || !device.is(IntProgrammable.class)) {
+            return;
+        }
+        device.as(IntProgrammable.class).cleanup();
+    }
+
+    private boolean configDevice(DeviceId deviceId) {
+        // Returns true if config was successful, false if not and a clean up is
+        // needed.
+        final Device device = deviceService.getDevice(deviceId);
+        if (device == null || !device.is(IntProgrammable.class)) {
+            return true;
+        }
+
+        if (isNotIntConfigured()) {
+            log.warn("Missing INT config, aborting programming of INT device {}", deviceId);
+            return true;
+        }
+
+        final boolean isEdge = !hostService.getConnectedHosts(deviceId).isEmpty();
+        final IntDeviceRole intDeviceRole = isEdge
+                ? IntDeviceRole.SOURCE_SINK
+                : IntDeviceRole.TRANSIT;
+
+        log.info("Started programming of INT device {} with role {}...",
+                 deviceId, intDeviceRole);
+
+        final IntProgrammable intProg = device.as(IntProgrammable.class);
+
+        if (!isIntStarted()) {
+            // Leave device with no INT configuration.
+            return true;
+        }
+
+        if (!intProg.init()) {
+            log.warn("Unable to init INT pipeline on {}", deviceId);
+            return false;
+        }
+
+        if (intDeviceRole != IntDeviceRole.SOURCE_SINK) {
+            // Stop here, no more configuration needed for transit devices.
+            return true;
+        }
+
+        if (intProg.supportsFunctionality(IntProgrammable.IntFunctionality.SINK)) {
+            if (!intProg.setupIntConfig(intConfig.get())) {
+                log.warn("Unable to apply INT report config on {}", deviceId);
+                return false;
+            }
+        }
+
+        // Port configuration.
+        final Set<PortNumber> hostPorts = deviceService.getPorts(deviceId)
+                .stream()
+                .map(port -> new ConnectPoint(deviceId, port.number()))
+                .filter(cp -> !hostService.getConnectedHosts(cp).isEmpty())
+                .map(ConnectPoint::port)
+                .collect(Collectors.toSet());
+
+        for (PortNumber port : hostPorts) {
+            if (intProg.supportsFunctionality(IntProgrammable.IntFunctionality.SOURCE)) {
+                log.info("Setting port {}/{} as INT source port...", deviceId, port);
+                if (!intProg.setSourcePort(port)) {
+                    log.warn("Unable to set INT source port {} on {}", port, deviceId);
+                    return false;
+                }
+            }
+            if (intProg.supportsFunctionality(IntProgrammable.IntFunctionality.SINK)) {
+                log.info("Setting port {}/{} as INT sink port...", deviceId, port);
+                if (!intProg.setSinkPort(port)) {
+                    log.warn("Unable to set INT sink port {} on {}", port, deviceId);
+                    return false;
+                }
+            }
+        }
+
+        if (!intProg.supportsFunctionality(IntProgrammable.IntFunctionality.SOURCE)) {
+            // Stop here, no more configuration needed for sink devices.
+            return true;
+        }
+
+        // Apply intents.
+        // This is a trivial implementation where we simply get the
+        // corresponding INT objective from an intent and we apply to all source
+        // device.
+        final Collection<IntObjective> objectives = intentMap.values().stream()
+                .map(v -> getIntObjective(v.value()))
+                .collect(Collectors.toList());
+        int appliedCount = 0;
+        for (IntObjective objective : objectives) {
+            if (intProg.addIntObjective(objective)) {
+                appliedCount = appliedCount + 1;
+            }
+        }
+
+        log.info("Completed programming of {}, applied {} INT objectives of {} total",
+                 deviceId, appliedCount, objectives.size());
+
+        return true;
+    }
+
+    private IntObjective getIntObjective(IntIntent intent) {
+        return new IntObjective.Builder()
+                .withSelector(intent.selector())
+                .withMetadataTypes(intent.metadataTypes())
+                .withHeaderType(intent.headerType())
+                .build();
+    }
+
+    /* Event listeners which trigger device configuration. */
+
+    private class InternalHostListener implements HostListener {
+        @Override
+        public void event(HostEvent event) {
+            final DeviceId deviceId = event.subject().location().deviceId();
+            triggerDeviceConfigure(deviceId);
+        }
+    }
+
+    private class InternalDeviceListener implements DeviceListener {
+        @Override
+        public void event(DeviceEvent event) {
+            switch (event.type()) {
+                case DEVICE_ADDED:
+                case DEVICE_UPDATED:
+                case DEVICE_REMOVED:
+                case DEVICE_SUSPENDED:
+                case DEVICE_AVAILABILITY_CHANGED:
+                case PORT_ADDED:
+                case PORT_UPDATED:
+                case PORT_REMOVED:
+                    triggerDeviceConfigure(event.subject().id());
+                    return;
+                case PORT_STATS_UPDATED:
+                    return;
+                default:
+                    log.warn("Unknown device event type {}", event.type());
+            }
+        }
+    }
+
+    private class InternalIntentMapListener
+            implements MapEventListener<IntIntentId, IntIntent> {
+        @Override
+        public void event(MapEvent<IntIntentId, IntIntent> event) {
+            triggerAllDeviceConfigure();
+        }
+    }
+
+    private class InternalIntConfigListener
+            implements AtomicValueEventListener<IntConfig> {
+        @Override
+        public void event(AtomicValueEvent<IntConfig> event) {
+            triggerAllDeviceConfigure();
+        }
+    }
+
+    private class InternalIntStartedListener
+            implements AtomicValueEventListener<Boolean> {
+        @Override
+        public void event(AtomicValueEvent<Boolean> event) {
+            triggerAllDeviceConfigure();
+        }
+    }
+
+    private class InternalDeviceToConfigureListener
+            implements MapEventListener<DeviceId, Long> {
+        @Override
+        public void event(MapEvent<DeviceId, Long> event) {
+            if (event.type().equals(MapEvent.Type.REMOVE) ||
+                    event.newValue() == null) {
+                return;
+            }
+            // Schedule task in the future. Wait for events for this device to
+            // stabilize.
+            final DeviceId deviceId = event.key();
+            final long creationTime = event.newValue().creationTime();
+            ScheduledFuture<?> newTask = SharedScheduledExecutors.newTimeout(
+                    () -> configDeviceTask(deviceId, creationTime),
+                    CONFIG_EVENT_DELAY, TimeUnit.SECONDS);
+            ScheduledFuture<?> oldTask = scheduledDeviceTasks.put(deviceId, newTask);
+            if (oldTask != null) {
+                oldTask.cancel(false);
+            }
+        }
+    }
+}
