diff --git a/providers/null/device/pom.xml b/providers/null/device/pom.xml
deleted file mode 100644
index 1d4882f..0000000
--- a/providers/null/device/pom.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ Copyright 2014 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-null-providers</artifactId>
-        <version>1.2.0-SNAPSHOT</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
-
-    <artifactId>onos-null-provider-device</artifactId>
-    <packaging>bundle</packaging>
-
-    <description>ONOS Null protocol device provider</description>
-
-    <dependencies>
-      <dependency>
-        <groupId>org.osgi</groupId>
-        <artifactId>org.osgi.compendium</artifactId>
-      </dependency>
-    </dependencies>
-
-</project>
diff --git a/providers/null/device/src/main/java/org/onosproject/provider/nil/device/impl/NullDeviceProvider.java b/providers/null/device/src/main/java/org/onosproject/provider/nil/device/impl/NullDeviceProvider.java
deleted file mode 100644
index 157a1fd..0000000
--- a/providers/null/device/src/main/java/org/onosproject/provider/nil/device/impl/NullDeviceProvider.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright 2014-2015 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.provider.nil.device.impl;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-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.Modified;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.onlab.packet.ChassisId;
-import org.onosproject.cfg.ComponentConfigService;
-import org.onosproject.cluster.ClusterService;
-import org.onosproject.cluster.NodeId;
-import org.onosproject.net.Device;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.MastershipRole;
-import org.onosproject.net.Port;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.device.DefaultDeviceDescription;
-import org.onosproject.net.device.DefaultPortDescription;
-import org.onosproject.net.device.DeviceDescription;
-import org.onosproject.net.device.DeviceProvider;
-import org.onosproject.net.device.DeviceProviderRegistry;
-import org.onosproject.net.device.DeviceProviderService;
-import org.onosproject.net.device.PortDescription;
-import org.onosproject.net.provider.AbstractProvider;
-import org.onosproject.net.provider.ProviderId;
-import org.osgi.service.component.ComponentContext;
-import org.slf4j.Logger;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import static com.google.common.base.Strings.isNullOrEmpty;
-import static org.onlab.util.Tools.*;
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * Provider which advertises fake/nonexistant devices to the core.
- * nodeID is passed as part of the fake device id so that multiple nodes can run simultaneously.
- * To be used for benchmarking only.
- */
-@Component(immediate = true)
-public class NullDeviceProvider extends AbstractProvider implements DeviceProvider {
-
-    private static final Logger log = getLogger(NullDeviceProvider.class);
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected ClusterService clusterService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected DeviceProviderRegistry providerRegistry;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected ComponentConfigService cfgService;
-
-    private DeviceProviderService providerService;
-
-    private ExecutorService deviceBuilder =
-            Executors.newFixedThreadPool(1, groupedThreads("onos/null", "device-creator"));
-
-    private static final String SCHEME = "null";
-    private static final int DEF_NUMDEVICES = 10;
-    private static final int DEF_NUMPORTS = 10;
-
-    //Delay between events in ms.
-    private static final int EVENTINTERVAL = 5;
-
-    private final Map<Integer, DeviceDescription> descriptions = Maps.newHashMap();
-
-    @Property(name = "devConfigs", value = "", label = "Instance-specific configurations")
-    private String devConfigs = null;
-
-    private int numDevices = DEF_NUMDEVICES;
-
-    @Property(name = "numPorts", intValue = 10, label = "Number of ports per devices")
-    private int numPorts = DEF_NUMPORTS;
-
-    private DeviceCreator creator;
-
-    /**
-     *
-     * Creates a provider with the supplier identifier.
-     *
-     */
-    public NullDeviceProvider() {
-        super(new ProviderId("null", "org.onosproject.provider.nil"));
-    }
-
-    @Activate
-    public void activate(ComponentContext context) {
-        cfgService.registerProperties(getClass());
-        providerService = providerRegistry.register(this);
-        if (!modified(context)) {
-            deviceBuilder.submit(new DeviceCreator(true));
-        }
-        log.info("Started");
-
-    }
-
-    @Deactivate
-    public void deactivate(ComponentContext context) {
-        cfgService.unregisterProperties(getClass(), false);
-        deviceBuilder.submit(new DeviceCreator(false));
-        try {
-            deviceBuilder.awaitTermination(1000, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-            log.error("Device builder did not terminate");
-        }
-        deviceBuilder.shutdownNow();
-        providerRegistry.unregister(this);
-        providerService = null;
-
-        log.info("Stopped");
-    }
-
-    @Modified
-    public boolean modified(ComponentContext context) {
-        if (context == null) {
-            log.info("No configuration file, using defaults: numDevices={}, numPorts={}",
-                    numDevices, numPorts);
-            return false;
-        }
-
-        Dictionary<?, ?> properties = context.getProperties();
-
-        int newDevNum = DEF_NUMDEVICES;
-        int newPortNum = DEF_NUMPORTS;
-        try {
-            String s = get(properties, "devConfigs");
-            if (!isNullOrEmpty(s)) {
-                newDevNum = getDevicesConfig(s);
-            }
-            s = get(properties, "numPorts");
-            newPortNum = isNullOrEmpty(s) ? DEF_NUMPORTS : Integer.parseInt(s.trim());
-        } catch (NumberFormatException e) {
-            log.warn(e.getMessage());
-            newDevNum = numDevices;
-            newPortNum = numPorts;
-        }
-
-        boolean chgd = false;
-        if (newDevNum != numDevices) {
-            numDevices = newDevNum;
-            chgd |= true;
-        }
-        if (newPortNum != numPorts) {
-            numPorts = newPortNum;
-            chgd |= true;
-        }
-        log.info("Using settings numDevices={}, numPorts={}", numDevices, numPorts);
-        if (chgd) {
-            deviceBuilder.submit(new DeviceCreator(true));
-        }
-        return chgd;
-    }
-
-    private int getDevicesConfig(String config) {
-        for (String sub : config.split(",")) {
-            String[] params = sub.split(":");
-            if (params.length == 2) {
-                NodeId that = new NodeId(params[0].trim());
-                String nd = params[1];
-                if (clusterService.getLocalNode().id().equals(that)) {
-                    return Integer.parseInt(nd.trim());
-                }
-                continue;
-            }
-        }
-        return DEF_NUMDEVICES;
-    }
-
-    @Override
-    public void triggerProbe(DeviceId deviceId) {}
-
-    @Override
-    public void roleChanged(DeviceId deviceId, MastershipRole newRole) {}
-
-    @Override
-    public boolean isReachable(DeviceId deviceId) {
-        return descriptions.values().stream()
-                .anyMatch(desc -> desc.deviceURI().equals(deviceId.uri()));
-    }
-
-
-    private class DeviceCreator implements Runnable {
-
-        private boolean setup;
-
-        public DeviceCreator(boolean setup) {
-            this.setup = setup;
-        }
-
-        @Override
-        public void run() {
-            if (setup) {
-                try {
-                    advertiseDevices();
-                } catch (URISyntaxException e) {
-                    log.warn("URI creation failed during device adverts {}", e.getMessage());
-                }
-            } else {
-                removeDevices();
-            }
-        }
-
-        private void removeDevices() {
-            for (DeviceDescription desc : descriptions.values()) {
-                providerService.deviceDisconnected(
-                        DeviceId.deviceId(desc.deviceURI()));
-                delay(EVENTINTERVAL);
-            }
-            descriptions.clear();
-        }
-
-        private void advertiseDevices() throws URISyntaxException {
-            DeviceId did;
-            ChassisId cid;
-
-            // nodeIdHash takes into account for nodeID to avoid collisions when running multi-node providers.
-            long nodeIdHash = clusterService.getLocalNode().id().hashCode() << 16;
-
-            for (int i = 0; i < numDevices; i++) {
-                long id = nodeIdHash | i;
-
-                did = DeviceId.deviceId(new URI(SCHEME, toHex(id), null));
-                cid = new ChassisId(i);
-                DeviceDescription desc =
-                        new DefaultDeviceDescription(did.uri(), Device.Type.SWITCH,
-                                                     "ON.Lab", "0.0.1", "0.0.1", "1234",
-                                                     cid);
-                descriptions.put(i, desc);
-                providerService.deviceConnected(did, desc);
-                providerService.updatePorts(did, buildPorts());
-                delay(EVENTINTERVAL);
-            }
-        }
-
-        private List<PortDescription> buildPorts() {
-            List<PortDescription> ports = Lists.newArrayList();
-            for (int i = 0; i < numPorts; i++) {
-                ports.add(new DefaultPortDescription(PortNumber.portNumber(i), true,
-                                                     Port.Type.COPPER,
-                                                     0));
-            }
-            return ports;
-        }
-    }
-}
diff --git a/providers/null/device/src/main/java/org/onosproject/provider/nil/device/impl/package-info.java b/providers/null/device/src/main/java/org/onosproject/provider/nil/device/impl/package-info.java
deleted file mode 100644
index 41221ed..0000000
--- a/providers/null/device/src/main/java/org/onosproject/provider/nil/device/impl/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2014-2015 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.
- */
-
-/**
- * Provider that advertises fake devices.
- */
-package org.onosproject.provider.nil.device.impl;
diff --git a/providers/null/flow/pom.xml b/providers/null/flow/pom.xml
deleted file mode 100644
index 5514d22..0000000
--- a/providers/null/flow/pom.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ Copyright 2014 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-null-providers</artifactId>
-        <version>1.2.0-SNAPSHOT</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
-
-    <artifactId>onos-null-provider-flow</artifactId>
-    <packaging>bundle</packaging>
-
-    <description>ONOS Null protocol flow provider</description>
-
-</project>
diff --git a/providers/null/flow/src/main/java/org/onosproject/provider/nil/flow/impl/NullFlowRuleProvider.java b/providers/null/flow/src/main/java/org/onosproject/provider/nil/flow/impl/NullFlowRuleProvider.java
deleted file mode 100644
index 0686349..0000000
--- a/providers/null/flow/src/main/java/org/onosproject/provider/nil/flow/impl/NullFlowRuleProvider.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright 2015 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.provider.nil.flow.impl;
-
-import com.google.common.collect.Sets;
-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.jboss.netty.util.HashedWheelTimer;
-import org.jboss.netty.util.Timeout;
-import org.jboss.netty.util.TimerTask;
-import org.onlab.util.Timer;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.flow.CompletedBatchOperation;
-import org.onosproject.net.flow.DefaultFlowEntry;
-import org.onosproject.net.flow.FlowEntry;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleBatchEntry;
-import org.onosproject.net.flow.FlowRuleBatchOperation;
-import org.onosproject.net.flow.FlowRuleProvider;
-import org.onosproject.net.flow.FlowRuleProviderRegistry;
-import org.onosproject.net.flow.FlowRuleProviderService;
-import org.onosproject.net.provider.AbstractProvider;
-import org.onosproject.net.provider.ProviderId;
-import org.slf4j.Logger;
-
-import java.util.Collections;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.TimeUnit;
-
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * Null provider to accept any flow and report them.
- */
-@Component(immediate = true)
-public class NullFlowRuleProvider extends AbstractProvider implements FlowRuleProvider {
-
-    private final Logger log = getLogger(getClass());
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected FlowRuleProviderRegistry providerRegistry;
-
-    private ConcurrentMap<DeviceId, Set<FlowEntry>> flowTable = new ConcurrentHashMap<>();
-
-    private FlowRuleProviderService providerService;
-
-    private HashedWheelTimer timer = Timer.getTimer();
-    private Timeout timeout;
-
-    public NullFlowRuleProvider() {
-        super(new ProviderId("null", "org.onosproject.provider.nil"));
-    }
-
-    @Activate
-    public void activate() {
-        providerService = providerRegistry.register(this);
-        timeout = timer.newTimeout(new StatisticTask(), 5, TimeUnit.SECONDS);
-
-        log.info("Started");
-    }
-
-    @Deactivate
-    public void deactivate() {
-        providerRegistry.unregister(this);
-        providerService = null;
-        timeout.cancel();
-
-        log.info("Stopped");
-    }
-
-    @Override
-    public void applyFlowRule(FlowRule... flowRules) {}
-
-    @Override
-    public void removeFlowRule(FlowRule... flowRules) {}
-
-    @Override
-    public void removeRulesById(ApplicationId id, FlowRule... flowRules) {
-        log.info("removal by app id not supported in null provider");
-    }
-
-    @Override
-    public void executeBatch(
-            FlowRuleBatchOperation batch) {
-        Set<FlowEntry> flowRules = flowTable.getOrDefault(batch.deviceId(), Sets.newConcurrentHashSet());
-        for (FlowRuleBatchEntry fbe : batch.getOperations()) {
-            switch (fbe.operator()) {
-                case ADD:
-                    flowRules.add(new DefaultFlowEntry(fbe.target()));
-                    break;
-                case REMOVE:
-                    flowRules.remove(new DefaultFlowEntry(fbe.target()));
-                    break;
-                case MODIFY:
-                    FlowEntry entry = new DefaultFlowEntry(fbe.target());
-                    flowRules.remove(entry);
-                    flowRules.add(entry);
-                    break;
-                default:
-                    log.error("Unknown flow operation: {}", fbe);
-            }
-        }
-        flowTable.put(batch.deviceId(), flowRules);
-        providerService.batchOperationCompleted(batch.id(),
-                                                new CompletedBatchOperation(
-                                                        true,
-                                                        Collections.emptySet(),
-                                                        batch.deviceId()));
-    }
-
-    private class StatisticTask implements TimerTask {
-
-        @Override
-        public void run(Timeout to) throws Exception {
-            for (DeviceId devId : flowTable.keySet()) {
-                    providerService.pushFlowMetrics(devId,
-                                                    flowTable.getOrDefault(devId, Collections.emptySet()));
-            }
-            timeout = timer.newTimeout(to.getTask(), 5, TimeUnit.SECONDS);
-
-        }
-    }
-}
diff --git a/providers/null/flow/src/main/java/org/onosproject/provider/nil/flow/impl/package-info.java b/providers/null/flow/src/main/java/org/onosproject/provider/nil/flow/impl/package-info.java
deleted file mode 100644
index 2c36ca9..0000000
--- a/providers/null/flow/src/main/java/org/onosproject/provider/nil/flow/impl/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2014-2015 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.
- */
-
-/**
- * Provider that will accept any flow rules.
- */
-package org.onosproject.provider.nil.flow.impl;
diff --git a/providers/null/host/pom.xml b/providers/null/host/pom.xml
deleted file mode 100644
index 81806e1..0000000
--- a/providers/null/host/pom.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ Copyright 2014 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-null-providers</artifactId>
-        <version>1.2.0-SNAPSHOT</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
-
-    <artifactId>onos-null-provider-host</artifactId>
-    <packaging>bundle</packaging>
-
-    <description>ONOS Null host provider</description>
-
-</project>
diff --git a/providers/null/host/src/main/java/org/onosproject/provider/nil/host/impl/NullHostProvider.java b/providers/null/host/src/main/java/org/onosproject/provider/nil/host/impl/NullHostProvider.java
deleted file mode 100644
index 51cf4e6..0000000
--- a/providers/null/host/src/main/java/org/onosproject/provider/nil/host/impl/NullHostProvider.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright 2015 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.provider.nil.host.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.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onosproject.cluster.ClusterService;
-import org.onosproject.mastership.MastershipService;
-import org.onosproject.net.Device;
-import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
-import org.onosproject.net.HostLocation;
-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.DefaultHostDescription;
-import org.onosproject.net.host.HostDescription;
-import org.onosproject.net.host.HostProvider;
-import org.onosproject.net.host.HostProviderRegistry;
-import org.onosproject.net.host.HostProviderService;
-import org.onosproject.net.provider.AbstractProvider;
-import org.onosproject.net.provider.ProviderId;
-import org.slf4j.Logger;
-
-import static org.onlab.util.Tools.toHex;
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * Null provider to advertise fake hosts.
- */
-@Component(immediate = true)
-public class NullHostProvider extends AbstractProvider implements HostProvider {
-
-    private final Logger log = getLogger(getClass());
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected DeviceService deviceService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected MastershipService roleService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected ClusterService nodeService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected HostProviderRegistry providerRegistry;
-
-    private HostProviderService providerService;
-
-    //make sure the device has enough ports to accomodate all of them.
-    private static final int HOSTSPERDEVICE = 5;
-
-    private final InternalHostProvider hostProvider = new InternalHostProvider();
-
-    /**
-     * Creates an OpenFlow host provider.
-     */
-    public NullHostProvider() {
-        super(new ProviderId("null", "org.onosproject.provider.nil"));
-    }
-
-    /**
-     * Creates a provider with the supplier identifier.
-     *
-     * @param id provider id
-     */
-    protected NullHostProvider(ProviderId id) {
-        super(id);
-    }
-
-    @Activate
-    public void activate() {
-        providerService = providerRegistry.register(this);
-        for (Device dev : deviceService.getDevices()) {
-            addHosts(dev);
-        }
-        deviceService.addListener(hostProvider);
-
-        log.info("Started");
-    }
-
-    @Deactivate
-    public void deactivate() {
-        providerRegistry.unregister(this);
-        deviceService.removeListener(hostProvider);
-        providerService = null;
-        log.info("Stopped");
-    }
-
-    @Override
-    public void triggerProbe(Host host) {}
-
-    private void addHosts(Device device) {
-        String nhash = toHex(nodeService.getLocalNode().id().hashCode());
-        String dhash = device.id().toString();
-        // make sure this instance owns the device.
-        if (!nhash.substring(nhash.length() - 3)
-                .equals(dhash.substring(14, 17))) {
-            log.warn("Device {} is not mine. Can't add hosts.", device.id());
-            return;
-        }
-        for (int i = 0; i < HOSTSPERDEVICE; i++) {
-            providerService.hostDetected(
-                    HostId.hostId(MacAddress.valueOf(i + device.hashCode()),
-                                  VlanId.vlanId((short) -1)),
-                    buildHostDescription(device, i));
-        }
-    }
-
-    private void removeHosts(Device device) {
-        for (int i = 0; i < HOSTSPERDEVICE; i++) {
-            providerService.hostVanished(
-                    HostId.hostId(MacAddress.valueOf(i + device.hashCode()),
-                                  VlanId.vlanId((short) -1)));
-        }
-    }
-
-    private HostDescription buildHostDescription(Device device, int port) {
-        MacAddress mac = MacAddress.valueOf(device.hashCode() + port);
-        HostLocation location = new HostLocation(device.id(),
-                                                 PortNumber.portNumber(port), 0L);
-        return new DefaultHostDescription(mac, VlanId.vlanId((short) -1), location);
-    }
-
-    private class InternalHostProvider implements DeviceListener {
-        @Override
-        public void event(DeviceEvent event) {
-            Device dev = event.subject();
-            if (!deviceService.getRole(event.subject().id()).equals(
-                    MastershipRole.MASTER)) {
-                log.info("Local node is not master for device {}", event
-                        .subject().id());
-                return;
-            }
-            switch (event.type()) {
-
-                case DEVICE_ADDED:
-                    addHosts(dev);
-                    break;
-                case DEVICE_UPDATED:
-                    break;
-                case DEVICE_REMOVED:
-                    removeHosts(dev);
-                    break;
-                case DEVICE_SUSPENDED:
-                    break;
-                case DEVICE_AVAILABILITY_CHANGED:
-                    break;
-                case PORT_ADDED:
-                    break;
-                case PORT_UPDATED:
-                    break;
-                case PORT_REMOVED:
-                    break;
-                default:
-                    break;
-            }
-        }
-
-    }
-
-}
diff --git a/providers/null/host/src/main/java/org/onosproject/provider/nil/host/impl/package-info.java b/providers/null/host/src/main/java/org/onosproject/provider/nil/host/impl/package-info.java
deleted file mode 100644
index d80078f..0000000
--- a/providers/null/host/src/main/java/org/onosproject/provider/nil/host/impl/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2014-2015 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.
- */
-
-/**
- * Provider that advertises fake hosts.
- */
-package org.onosproject.provider.nil.host.impl;
diff --git a/providers/null/link/pom.xml b/providers/null/link/pom.xml
deleted file mode 100644
index b401b29..0000000
--- a/providers/null/link/pom.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ Copyright 2014 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-null-providers</artifactId>
-        <version>1.2.0-SNAPSHOT</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
-
-    <artifactId>onos-null-provider-link</artifactId>
-    <packaging>bundle</packaging>
-
-    <description>ONOS Null link provider</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.compendium</artifactId>
-        </dependency>
-    </dependencies>
-
-</project>
diff --git a/providers/null/link/src/main/java/org/onosproject/provider/nil/link/impl/NullLinkProvider.java b/providers/null/link/src/main/java/org/onosproject/provider/nil/link/impl/NullLinkProvider.java
deleted file mode 100644
index 7bbe89d..0000000
--- a/providers/null/link/src/main/java/org/onosproject/provider/nil/link/impl/NullLinkProvider.java
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * Copyright 2015 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.provider.nil.link.impl;
-
-import com.google.common.base.Charsets;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.io.Files;
-
-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.Modified;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.onosproject.cfg.ComponentConfigService;
-import org.onosproject.cluster.ClusterService;
-import org.onosproject.cluster.NodeId;
-import org.onosproject.mastership.MastershipService;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.Device;
-import org.onosproject.net.DeviceId;
-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.link.DefaultLinkDescription;
-import org.onosproject.net.link.LinkDescription;
-import org.onosproject.net.link.LinkProvider;
-import org.onosproject.net.link.LinkProviderRegistry;
-import org.onosproject.net.link.LinkProviderService;
-import org.onosproject.net.provider.AbstractProvider;
-import org.onosproject.net.provider.ProviderId;
-import org.osgi.service.component.ComponentContext;
-import org.slf4j.Logger;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Dictionary;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import static org.onlab.util.Tools.groupedThreads;
-import static org.onlab.util.Tools.get;
-import static org.onlab.util.Tools.toHex;
-import static org.onosproject.net.Link.Type.DIRECT;
-import static org.slf4j.LoggerFactory.getLogger;
-import static com.google.common.base.Strings.isNullOrEmpty;
-
-/**
- * Provider which advertises fake/nonexistent links to the core. To be used for
- * benchmarking only.
- *
- * This provider takes a topology graph file with a DOT-like syntax.
- */
-@Component(immediate = true)
-public class NullLinkProvider extends AbstractProvider implements LinkProvider {
-
-    private final Logger log = getLogger(getClass());
-
-    // default topology file location and name.
-    private static final String CFG_PATH = "etc/linkGraph.cfg";
-
-    // default number of workers. Eventually make this tunable
-    private static final int THREADS = (int) Math.max(1, Runtime.getRuntime().availableProcessors() * 0.8);
-
-    private static final int CHECK_DURATION = 10;   // sec
-    private static final int DEFAULT_RATE = 0;      // usec
-    private static final int REFRESH_RATE = 3;      // sec
-    // Fake device used for non-flickering thread in deviceMap
-    private static final DeviceId DEFAULT = DeviceId.deviceId("null:ffffffffffffffff");
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected DeviceService deviceService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected MastershipService roleService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected ClusterService nodeService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected LinkProviderRegistry providerRegistry;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected ComponentConfigService cfgService;
-
-    private LinkProviderService providerService;
-
-    private final InternalLinkProvider linkProvider = new InternalLinkProvider();
-
-    // Mapping between device and drivers that advertise links from device
-    private final ConcurrentMap<DeviceId, Set<LinkDriver>> driverMap = Maps
-            .newConcurrentMap();
-
-    // Link descriptions
-    private final List<LinkDescription> linkDescrs = Lists.newArrayList();
-
-    // Thread to description map for dividing links amongst threads in flicker mode
-    private final List<List<LinkDescription>> linkTasks = Lists.newArrayList();
-
-    private ScheduledExecutorService linkDriver =
-            Executors.newScheduledThreadPool(THREADS, groupedThreads("onos/null", "link-driver-%d"));
-
-    // For flicker = true, duration between events in msec.
-    @Property(name = "eventRate", intValue = DEFAULT_RATE, label = "Duration between Link Event")
-    private int eventRate = DEFAULT_RATE;
-
-    // topology configuration file
-    @Property(name = "cfgFile", value = CFG_PATH, label = "Topology file location")
-    private String cfgFile = CFG_PATH;
-
-    // flag checked to create a LinkDriver, if rate is non-zero.
-    private volatile boolean flicker = false;
-
-    public NullLinkProvider() {
-        super(new ProviderId("null", "org.onosproject.provider.nil"));
-    }
-
-    @Activate
-    public void activate(ComponentContext context) {
-        cfgService.registerProperties(getClass());
-        providerService = providerRegistry.register(this);
-        modified(context);
-        log.info("started");
-    }
-
-    @Deactivate
-    public void deactivate(ComponentContext context) {
-        cfgService.unregisterProperties(getClass(), false);
-        linkDriver.shutdown();
-        try {
-            linkDriver.awaitTermination(1000, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-            log.error("LinkBuilder did not terminate");
-            linkDriver.shutdownNow();
-        }
-        deviceService.removeListener(linkProvider);
-        providerRegistry.unregister(this);
-        deviceService = null;
-
-        log.info("stopped");
-    }
-
-    @Modified
-    public void modified(ComponentContext context) {
-        if (context == null) {
-            log.info("No configs, using defaults: eventRate={}", DEFAULT_RATE);
-            return;
-        }
-        Dictionary<?, ?> properties = context.getProperties();
-        int newRate;
-        String newPath;
-        try {
-            String s = get(properties, "eventRate");
-            newRate = isNullOrEmpty(s) ? DEFAULT_RATE : Integer.parseInt(s.trim());
-            s = (String) properties.get("cfgFile");
-            newPath = isNullOrEmpty(s) ? CFG_PATH : s.trim();
-        } catch (NumberFormatException e) {
-            log.warn(e.getMessage());
-            newRate = eventRate;
-            newPath = cfgFile;
-        }
-        // find/read topology file.
-        if (!newPath.equals(cfgFile)) {
-            cfgFile = newPath;
-        }
-        readGraph(cfgFile, nodeService.getLocalNode().id());
-        // check for new eventRate settings.
-        if (newRate != eventRate) {
-            if (eventRate < 0) {
-                log.warn("Invalid rate, ignoring and using default");
-                eventRate = DEFAULT_RATE;
-            } else {
-                eventRate = newRate;
-            }
-        }
-        configureWorkers();
-        log.info("Using settings: eventRate={}, topofile={}", eventRate, cfgFile);
-    }
-
-    // Configures and schedules worker threads based on settings.
-    private void configureWorkers() {
-        if (eventRate > 0) {
-            // now set to 'flicker', previously not flickering
-            if (!flicker) {
-                flicker = true;
-                allocateLinks();
-                // kill off refresh worker for symmetry
-                if (driverMap.containsKey(DEFAULT)) {
-                    driverMap.get(DEFAULT).forEach(d -> d.setTasks(Lists.newArrayList()));
-                    driverMap.remove(DEFAULT);
-                }
-                for (int i = 0; i < linkTasks.size(); i++) {
-                    List<LinkDescription> links = linkTasks.get(i);
-                    LinkDriver driver = new LinkDriver(links);
-                    links.forEach(v -> {
-                        DeviceId sd = v.src().deviceId();
-                        DeviceId dd = v.src().deviceId();
-                        driverMap.computeIfAbsent(sd, k -> Sets.newConcurrentHashSet()).add(driver);
-                        driverMap.computeIfAbsent(dd, k -> Sets.newConcurrentHashSet()).add(driver);
-                    });
-                    linkDriver.schedule(driver, eventRate, TimeUnit.MICROSECONDS);
-                }
-            }
-            // no need for was flicker since eventRate will be read by workers
-        } else {
-            // now set to 'refresh' was 'flicker' before
-            if (flicker) {
-                driverMap.forEach((dev, lds) -> lds.forEach(l -> l.deviceRemoved(dev)));
-                driverMap.clear();
-                linkTasks.clear();
-                flicker = false;
-                LinkDriver driver = new LinkDriver(linkDescrs);
-                driverMap.computeIfAbsent(DEFAULT, k -> Sets.newConcurrentHashSet()).add(driver);
-                linkDriver.schedule(driver, DEFAULT_RATE, TimeUnit.SECONDS);
-                // was 'refresh' - something changed or we're just starting.
-            } else {
-                if (driverMap.containsKey(DEFAULT)) {
-                    driverMap.forEach((dev, ld) -> ld.forEach(d -> d.setTasks(linkDescrs)));
-                    return;
-                }
-                LinkDriver driver = new LinkDriver(linkDescrs);
-                driverMap.computeIfAbsent(DEFAULT, k -> Sets.newConcurrentHashSet()).add(driver);
-                linkDriver.schedule(driver, DEFAULT_RATE, TimeUnit.SECONDS);
-            }
-        }
-    }
-
-    // parse simplified dot-like topology graph
-    private void readGraph(String path, NodeId me) {
-        log.info("path: {}, local: {}", path, me);
-        Set<LinkDescription> read = Sets.newHashSet();
-        BufferedReader br = null;
-        try {
-            br = Files.newReader(new File(path), Charsets.US_ASCII);
-            String cur = br.readLine();
-            while (cur != null) {
-                if (cur.startsWith("#")) {
-                    cur = br.readLine();
-                    continue;
-                }
-                String[] parts = cur.trim().split(" ");
-                if (parts.length < 1) {
-                    continue;
-                }
-                if (parts[0].equals("graph")) {
-                    String node = parts[1].trim();
-                    if (node.equals(me.toString())) {
-                        cur = br.readLine(); // move to next line, start of links list
-                        while (cur != null) {
-                            if (cur.trim().contains("}")) {
-                                break;
-                            }
-                            readLink(cur.trim().split(" "), me, read);
-                            cur = br.readLine();
-                        }
-                    } else {
-                        while (cur != null) {
-                            if (cur.trim().equals("}")) {
-                                break;
-                            }
-                            cur = br.readLine();
-                        }
-                    }
-                }
-                cur = br.readLine();
-            }
-        } catch (IOException e) {
-            log.warn("Could not find topology file: {}", e);
-        } finally {
-            try {
-                if (br != null) {
-                    br.close();
-                }
-            } catch (IOException e) {
-                log.warn("Could not close topology file: {}", e);
-            }
-        }
-        synchronized (linkDescrs) {
-            if (!read.isEmpty()) {
-                linkDescrs.clear();
-                linkDescrs.addAll(read);
-            }
-        }
-    }
-
-    // parses a link descriptor to make a LinkDescription
-    private void readLink(String[] linkArr, NodeId me, Set<LinkDescription> links) {
-        if (linkArr[0].startsWith("#")) {
-            return;
-        }
-        if (linkArr.length != 3) {
-            log.warn("Malformed link descriptor:"
-                    + " link should be of format src:port [--|->] dst:port,"
-                    + " skipping");
-            return;
-        }
-
-        String op = linkArr[1];
-        String[] cp1 = linkArr[0].split(":");
-        String[] cp2 = linkArr[2].split(":");
-
-        if (cp1.length != 2 && (cp2.length != 2 || cp2.length != 3)) {
-            log.warn("Malformed endpoint descriptor(s):"
-                    + "endpoint format should be DeviceId:port or DeviceId:port:NodeId,"
-                    + "skipping");
-            return;
-        }
-        // read in hints about topology.
-        NodeId adj = null;
-        if (cp2.length == 3) {
-            adj = new NodeId(cp2[2]);
-            log.debug("found an island: {}", adj);
-        }
-
-        // reconstruct deviceIDs. Convention is based on NullDeviceProvider.
-        DeviceId sdev = recover(cp1[0], me);
-        DeviceId ddev = (adj == null) ? recover(cp2[0], me) : recover(cp2[0], adj);
-        ConnectPoint src = new ConnectPoint(sdev, PortNumber.portNumber(cp1[1]));
-        ConnectPoint dst = new ConnectPoint(ddev, PortNumber.portNumber(cp2[1]));
-        // both link types have incoming half-link
-        LinkDescription in = new DefaultLinkDescription(dst, src, DIRECT);
-        links.add(in);
-        if (op.equals("--")) {
-            // bidirectional - within our node's island, make outbound link
-            LinkDescription out = new DefaultLinkDescription(src, dst, DIRECT);
-            links.add(out);
-            log.info("Created bidirectional link: {}, {}", out, in);
-        } else if (op.equals("->")) {
-            log.info("Created unidirectional link: {}", in);
-        } else {
-            log.warn("Unknown link descriptor operand:"
-                    + " operand must be '--' or '->', skipping");
-            return;
-        }
-    }
-
-    // recover DeviceId from configs and NodeID
-    private DeviceId recover(String base, NodeId node) {
-        long hash = node.hashCode() << 16;
-        int dev = Integer.parseInt(base);
-        try {
-            return DeviceId.deviceId(new URI("null", toHex(hash | dev), null));
-        } catch (URISyntaxException e) {
-            log.warn("could not create a DeviceID for descriptor {}", dev);
-            return DeviceId.NONE;
-        }
-    }
-
-    // adds a LinkDescription to a worker's to-be queue, for flickering
-    private void allocateLinks() {
-        int index, lcount = 0;
-        linkTasks.clear();
-        for (LinkDescription ld : linkDescrs) {
-            index = (lcount % THREADS);
-            log.info("allocation: total={}, index={}", linkDescrs.size(), lcount, index);
-            if (linkTasks.size() <= index) {
-                linkTasks.add(index, Lists.newArrayList(ld));
-            } else {
-                linkTasks.get(index).add(ld);
-            }
-            lcount++;
-        }
-    }
-
-    /**
-     * Generate LinkEvents using configurations when devices are found.
-     */
-    private class InternalLinkProvider implements DeviceListener {
-
-        @Override
-        public void event(DeviceEvent event) {
-            Device dev = event.subject();
-            switch (event.type()) {
-            case DEVICE_ADDED:
-                // TODO: wait for all devices to stop core from balking
-                break;
-            case DEVICE_REMOVED:
-                for (LinkDriver d : driverMap.get(dev.id())) {
-                    d.deviceRemoved(dev.id());
-                }
-                providerService.linksVanished(dev.id());
-                break;
-            default:
-                break;
-            }
-        }
-    }
-
-    /**
-     * Generates link events using fake links.
-     * TODO: stats collection should be its own thing.
-     */
-    private class LinkDriver implements Runnable {
-        // List to actually work off of
-        List<LinkDescription> tasks = Lists.newCopyOnWriteArrayList();
-        float effLoad = 0;
-        Long counter = 0L;
-        int next = 0;
-        boolean up = true;
-
-        long startTime;
-
-        LinkDriver(List<LinkDescription> links) {
-            setTasks(links);
-            startTime = System.currentTimeMillis(); // yes, this will start off inaccurate
-        }
-
-        @Override
-        public void run() {
-            if (flicker) {
-                flicker();
-            } else {
-                refresh();
-            }
-        }
-
-        private void flicker() {
-            if ((!linkDriver.isShutdown() || !tasks.isEmpty())) {
-                log.trace("next: {}, count: {}", next, counter);
-                if (counter <= CHECK_DURATION * 1_000_000 / eventRate) {
-                    if (up) {
-                        providerService.linkDetected(tasks.get(next++));
-                    } else {
-                        providerService.linkVanished(tasks.get(next++));
-                    }
-                    if (next >= tasks.size()) {
-                        next = 0;
-                        up = !up;
-                    }
-                    counter++;
-                } else {
-                    // log in WARN the effective load generation rate in events/sec, every 10 seconds
-                    effLoad = (float) (counter * 1000.0 / (System
-                            .currentTimeMillis() - startTime));
-                    log.warn("Effective Loading for thread is {} events/second",
-                            String.valueOf(effLoad));
-                    counter = 0L;
-                    startTime = System.currentTimeMillis();
-                }
-                linkDriver.schedule(this, eventRate, TimeUnit.MICROSECONDS);
-            }
-        }
-
-        private void refresh() {
-            if (!linkDriver.isShutdown() || !tasks.isEmpty()) {
-                log.trace("iter {} refresh_links", counter);
-
-                for (LinkDescription desc : tasks) {
-                    providerService.linkDetected(desc);
-                    log.info("iteration {}, {}", counter, desc);
-                }
-                counter++;
-                linkDriver.schedule(this, REFRESH_RATE, TimeUnit.SECONDS);
-            }
-        }
-
-        public void deviceRemoved(DeviceId did) {
-            List<LinkDescription> rm = Lists.newArrayList();
-            for (LinkDescription ld : tasks) {
-                if (did.equals(ld.dst().deviceId())
-                        || (did.equals(ld.src().deviceId()))) {
-                    rm.add(ld);
-                }
-            }
-            tasks.removeAll(rm);
-        }
-
-        public void setTasks(List<LinkDescription> links) {
-            HashMultimap<ConnectPoint, ConnectPoint> nm = HashMultimap.create();
-            List<LinkDescription> rm = Lists.newArrayList();
-            links.forEach(v -> nm.put(v.src(), v.dst()));
-            // remove and send linkVanished for stale links.
-            for (LinkDescription l : tasks) {
-                if (!nm.containsEntry(l.src(), l.dst())) {
-                    rm.add(l);
-                }
-            }
-            tasks.clear();
-            tasks.addAll(links);
-            rm.forEach(l -> providerService.linkVanished(l));
-        }
-    }
-
-}
diff --git a/providers/null/link/src/main/java/org/onosproject/provider/nil/link/impl/package-info.java b/providers/null/link/src/main/java/org/onosproject/provider/nil/link/impl/package-info.java
deleted file mode 100644
index 0b56740..0000000
--- a/providers/null/link/src/main/java/org/onosproject/provider/nil/link/impl/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2014-2015 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.
- */
-
-/**
- * Provider that advertises fake links.
- */
-package org.onosproject.provider.nil.link.impl;
diff --git a/providers/null/packet/pom.xml b/providers/null/packet/pom.xml
deleted file mode 100644
index d795119..0000000
--- a/providers/null/packet/pom.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ Copyright 2014 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-null-providers</artifactId>
-        <version>1.2.0-SNAPSHOT</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
-
-    <artifactId>onos-null-provider-packet</artifactId>
-    <packaging>bundle</packaging>
-
-    <description>ONOS Null packet provider</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.compendium</artifactId>
-        </dependency>
-    </dependencies>
-
-</project>
diff --git a/providers/null/packet/src/main/java/org/onosproject/provider/nil/packet/impl/NullPacketProvider.java b/providers/null/packet/src/main/java/org/onosproject/provider/nil/packet/impl/NullPacketProvider.java
deleted file mode 100644
index 15bd671..0000000
--- a/providers/null/packet/src/main/java/org/onosproject/provider/nil/packet/impl/NullPacketProvider.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright 2015 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.provider.nil.packet.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.Modified;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.onlab.packet.Ethernet;
-import org.onlab.packet.ICMP;
-import org.onosproject.cfg.ComponentConfigService;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.Device;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.packet.DefaultInboundPacket;
-import org.onosproject.net.packet.DefaultPacketContext;
-import org.onosproject.net.packet.InboundPacket;
-import org.onosproject.net.packet.OutboundPacket;
-import org.onosproject.net.packet.PacketContext;
-import org.onosproject.net.packet.PacketProvider;
-import org.onosproject.net.packet.PacketProviderRegistry;
-import org.onosproject.net.packet.PacketProviderService;
-import org.onosproject.net.provider.AbstractProvider;
-import org.onosproject.net.provider.ProviderId;
-import org.osgi.service.component.ComponentContext;
-import org.slf4j.Logger;
-
-import java.nio.ByteBuffer;
-import java.util.Dictionary;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import static com.google.common.base.Strings.isNullOrEmpty;
-import static org.onlab.util.Tools.delay;
-import static org.onlab.util.Tools.groupedThreads;
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * Provider which 1) intercepts network-bound messages from the core, and 2)
- * generates PacketEvents at some tunable rate. To be used for benchmarking
- * only.
- */
-@Component(immediate = true)
-public class NullPacketProvider extends AbstractProvider implements
-        PacketProvider {
-
-    private final Logger log = getLogger(getClass());
-
-    // Default packetEvent generation rate (in packets/sec)
-    // If 0, we are just a sink for network-bound packets
-    private static final int DEFAULT_RATE = 5;
-    // arbitrary host "destination"
-    private static final int DESTHOST = 5;
-
-    private PacketProviderService providerService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected PacketProviderRegistry providerRegistry;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected DeviceService deviceService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected ComponentConfigService cfgService;
-
-    // Rate to generate PacketEvents, per second
-    @Property(name = "pktRate", intValue = DEFAULT_RATE,
-            label = "Rate of PacketEvent generation")
-    private int pktRate = DEFAULT_RATE;
-
-    private ExecutorService packetDriver =
-            Executors.newFixedThreadPool(1, groupedThreads("onos/null", "packet-driver"));
-
-    public NullPacketProvider() {
-        super(new ProviderId("null", "org.onosproject.provider.nil"));
-    }
-
-    @Activate
-    public void activate(ComponentContext context) {
-        cfgService.registerProperties(getClass());
-        providerService = providerRegistry.register(this);
-        if (!modified(context)) {
-            packetDriver.submit(new PacketDriver());
-        }
-        log.info("started");
-    }
-
-    @Deactivate
-    public void deactivate(ComponentContext context) {
-        cfgService.unregisterProperties(getClass(), false);
-        try {
-            packetDriver.awaitTermination(1000, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-            log.error("PacketDriver did not terminate");
-        }
-        packetDriver.shutdownNow();
-        providerRegistry.unregister(this);
-        log.info("stopped");
-    }
-
-    @Modified
-    public boolean modified(ComponentContext context) {
-        if (context == null) {
-            log.info("No configuration change, using defaults: pktRate={}",
-                    DEFAULT_RATE);
-            return false;
-        }
-        Dictionary<?, ?> properties = context.getProperties();
-
-        int newRate;
-        try {
-            String s = String.valueOf(properties.get("pktRate"));
-            newRate = isNullOrEmpty(s) ? pktRate : Integer.parseInt(s.trim());
-        } catch (NumberFormatException | ClassCastException e) {
-            log.warn(e.getMessage());
-            newRate = pktRate;
-        }
-
-        if (newRate != pktRate) {
-            pktRate = newRate;
-            packetDriver.submit(new PacketDriver());
-            log.info("Using new settings: pktRate={}", pktRate);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void emit(OutboundPacket packet) {
-        // We don't have a network to emit to. Keep a counter here, maybe?
-    }
-
-    /**
-     * Generates packet events at a given rate.
-     */
-    private class PacketDriver implements Runnable {
-
-        // time between event firing, in milliseconds
-        int pktInterval;
-        // filler echo request
-        ICMP icmp;
-        Ethernet eth;
-
-        public PacketDriver() {
-            pktInterval = 1000 / pktRate;
-            icmp = new ICMP();
-            icmp.setIcmpType((byte) 8).setIcmpCode((byte) 0)
-                    .setChecksum((short) 0);
-            eth = new Ethernet();
-            eth.setEtherType(Ethernet.TYPE_IPV4);
-            eth.setPayload(icmp);
-        }
-
-        @Override
-        public void run() {
-            log.info("PacketDriver started");
-            while (!packetDriver.isShutdown()) {
-                for (Device dev : deviceService.getDevices()) {
-                    sendEvents(dev);
-                }
-            }
-        }
-
-        private void sendEvents(Device dev) {
-            // make it look like things came from ports attached to hosts
-            for (int i = 0; i < 4; i++) {
-                eth.setSourceMACAddress("00:00:10:00:00:0" + i)
-                        .setDestinationMACAddress("00:00:10:00:00:0" + DESTHOST);
-                InboundPacket inPkt = new DefaultInboundPacket(
-                        new ConnectPoint(dev.id(), PortNumber.portNumber(i)),
-                        eth, ByteBuffer.wrap(eth.serialize()));
-                PacketContext pctx = new NullPacketContext(
-                        System.currentTimeMillis(), inPkt, null, false);
-                providerService.processPacket(pctx);
-                delay(pktInterval);
-            }
-        }
-
-    }
-
-    /**
-     * Minimal PacketContext to make core + applications happy.
-     */
-    private class NullPacketContext extends DefaultPacketContext {
-
-        public NullPacketContext(long time, InboundPacket inPkt,
-                OutboundPacket outPkt, boolean block) {
-            super(time, inPkt, outPkt, block);
-        }
-
-        @Override
-        public void send() {
-            // We don't send anything out.
-        }
-
-    }
-
-}
diff --git a/providers/null/packet/src/main/java/org/onosproject/provider/nil/packet/impl/package-info.java b/providers/null/packet/src/main/java/org/onosproject/provider/nil/packet/impl/package-info.java
deleted file mode 100644
index f385f4d..0000000
--- a/providers/null/packet/src/main/java/org/onosproject/provider/nil/packet/impl/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2014-2015 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.
- */
-
-/**
- * Provider that sends and brings packets to &amp; from oblivion.
- */
-package org.onosproject.provider.nil.packet.impl;
diff --git a/providers/null/pom.xml b/providers/null/pom.xml
index fa1b6d3..e6d417d 100644
--- a/providers/null/pom.xml
+++ b/providers/null/pom.xml
@@ -29,7 +29,7 @@
     <artifactId>onos-null-provider</artifactId>
     <packaging>bundle</packaging>
 
-    <description>ONOS null protocol adapters</description>
+    <description>Null southbound providers application</description>
 
     <dependencies>
         <dependency>
