diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProviderTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProviderTest.java
new file mode 100644
index 0000000..8e11e6f
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualFlowRuleProviderTest.java
@@ -0,0 +1,386 @@
+/*
+ * Copyright 2016-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.incubator.net.virtual.impl.provider;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.graph.ScalarWeight;
+import org.onlab.graph.Weight;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
+import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
+import org.onosproject.incubator.net.virtual.DefaultVirtualPort;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminServiceAdapter;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.DefaultPath;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Path;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleServiceAdapter;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.topology.LinkWeigher;
+import org.onosproject.net.topology.Topology;
+import org.onosproject.net.topology.TopologyServiceAdapter;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertEquals;
+
+public class DefaultVirtualFlowRuleProviderTest {
+    private static final ProviderId PID = new ProviderId("of", "foo");
+
+    private static final DeviceId DID1 = DeviceId.deviceId("of:001");
+    private static final DeviceId DID2 = DeviceId.deviceId("of:002");
+    private static final PortNumber PORT_NUM1 = PortNumber.portNumber(1);
+    private static final PortNumber PORT_NUM2 = PortNumber.portNumber(2);
+
+    private static final DefaultAnnotations ANNOTATIONS =
+            DefaultAnnotations.builder().set("foo", "bar").build();
+
+    private static final Device DEV1 =
+            new DefaultDevice(PID, DID1, Device.Type.SWITCH, "", "", "", "", null);
+    private static final Device DEV2 =
+            new DefaultDevice(PID, DID2, Device.Type.SWITCH, "", "", "", "", null);
+    private static final Port PORT11 =
+            new DefaultPort(DEV1, PORT_NUM1, true, ANNOTATIONS);
+    private static final Port PORT12 =
+            new DefaultPort(DEV1, PORT_NUM2, true, ANNOTATIONS);
+    private static final Port PORT21 =
+            new DefaultPort(DEV2, PORT_NUM1, true, ANNOTATIONS);
+    private static final Port PORT22 =
+            new DefaultPort(DEV2, PORT_NUM2, true, ANNOTATIONS);
+
+    private static final ConnectPoint CP11 = new ConnectPoint(DID1, PORT_NUM1);
+    private static final ConnectPoint CP12 = new ConnectPoint(DID1, PORT_NUM2);
+    private static final ConnectPoint CP21 = new ConnectPoint(DID2, PORT_NUM1);
+    private static final ConnectPoint CP22 = new ConnectPoint(DID2, PORT_NUM2);
+    private static final Link LINK1 = DefaultLink.builder()
+            .src(CP12).dst(CP21).providerId(PID).type(Link.Type.DIRECT).build();
+
+    private static final NetworkId VNET_ID = NetworkId.networkId(1);
+    private static final DeviceId VDID = DeviceId.deviceId("of:100");
+
+    private static final VirtualNetwork VNET = new DefaultVirtualNetwork(
+            VNET_ID, TenantId.tenantId("t1"));
+    private static final VirtualDevice VDEV =
+            new DefaultVirtualDevice(VNET_ID, VDID);
+    private static final VirtualPort VPORT1 =
+            new DefaultVirtualPort(VNET_ID, VDEV, PORT_NUM1, CP11);
+    private static final VirtualPort VPORT2 =
+            new DefaultVirtualPort(VNET_ID, VDEV, PORT_NUM2, CP22);
+
+    private static final int TIMEOUT = 10;
+
+    protected DefaultVirtualFlowRuleProvider virtualProvider;
+
+    private ApplicationId vAppId;
+
+    @Before
+    public void setUp() {
+        virtualProvider = new DefaultVirtualFlowRuleProvider();
+
+        virtualProvider.deviceService = new TestDeviceService();
+        virtualProvider.coreService = new TestCoreService();
+        virtualProvider.vnService =
+                new TestVirtualNetworkAdminService();
+        virtualProvider.topologyService = new TestTopologyService();
+        virtualProvider.flowRuleService = new TestFlowRuleService();
+        virtualProvider.providerRegistryService = new VirtualProviderManager();
+
+        virtualProvider.activate();
+        vAppId = new TestApplicationId(0, "Virtual App");
+    }
+
+    @After
+    public void tearDown() {
+        virtualProvider.deactivate();
+        virtualProvider.deviceService = null;
+        virtualProvider.coreService = null;
+    }
+
+    @Test
+    public void devirtualizeFlowRuleWithInPort() {
+        TrafficSelector ts = DefaultTrafficSelector.builder()
+                .matchInPort(PORT_NUM1).build();
+        TrafficTreatment tr = DefaultTrafficTreatment.builder()
+                .setOutput(PORT_NUM2).build();
+
+        FlowRule r1 = DefaultFlowRule.builder()
+                .forDevice(VDID)
+                .withSelector(ts)
+                .withTreatment(tr)
+                .withPriority(10)
+                .fromApp(vAppId)
+                .makeTemporary(TIMEOUT)
+                .build();
+
+        virtualProvider.applyFlowRule(VNET_ID, r1);
+
+        assertEquals("2 rules should exist", 2,
+                     virtualProvider.flowRuleService.getFlowRuleCount());
+
+        Set<FlowEntry> phyRules = new HashSet<>();
+        for (FlowEntry i : virtualProvider.flowRuleService.getFlowEntries(DID1)) {
+            phyRules.add(i);
+        }
+        for (FlowEntry i : virtualProvider.flowRuleService.getFlowEntries(DID2)) {
+            phyRules.add(i);
+        }
+
+        FlowRule in = null;
+        FlowRule out = null;
+
+        for (FlowRule rule : phyRules) {
+
+            L2ModificationInstruction i = (L2ModificationInstruction)
+                    rule.treatment().allInstructions().get(0);
+
+            if (i.subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) {
+                in = rule;
+            } else {
+                out = rule;
+            }
+
+        }
+
+        assertEquals(DID1, in.deviceId());
+        assertEquals(DID2, out.deviceId());
+    }
+
+    @Test
+    public void devirtualizeFlowRuleWithoutInPort() {
+        TrafficSelector ts = DefaultTrafficSelector.builder().build();
+        TrafficTreatment tr = DefaultTrafficTreatment.builder()
+                .setOutput(PORT_NUM2).build();
+
+        FlowRule r1 = DefaultFlowRule.builder()
+                .forDevice(VDID)
+                .withSelector(ts)
+                .withTreatment(tr)
+                .withPriority(10)
+                .fromApp(vAppId)
+                .makeTemporary(TIMEOUT)
+                .build();
+
+        virtualProvider.applyFlowRule(VNET_ID, r1);
+
+        assertEquals("3 rules should exist", 3,
+                     virtualProvider.flowRuleService.getFlowRuleCount());
+
+        FlowRule inFromDID1 = null;
+        FlowRule inFromDID2 = null;
+        FlowRule out = null;
+
+        Set<FlowEntry> phyRules = new HashSet<>();
+        for (FlowEntry i : virtualProvider.flowRuleService.getFlowEntries(DID1)) {
+            phyRules.add(i);
+        }
+        for (FlowEntry i : virtualProvider.flowRuleService.getFlowEntries(DID2)) {
+            phyRules.add(i);
+        }
+
+        for (FlowRule rule : phyRules) {
+            for (Instruction inst : rule.treatment().allInstructions()) {
+                if (inst.type() == Instruction.Type.L2MODIFICATION) {
+                    L2ModificationInstruction i = (L2ModificationInstruction) inst;
+                    if (i.subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) {
+                        inFromDID1 = rule;
+                        break;
+                    } else {
+                        out = rule;
+                        break;
+                    }
+                } else {
+                    inFromDID2 = rule;
+                    break;
+                }
+            }
+        }
+
+        assertEquals(DID1, inFromDID1.deviceId());
+        assertEquals(DID2, inFromDID2.deviceId());
+        assertEquals(DID2, out.deviceId());
+    }
+
+    @Test
+    public void removeVirtualizeFlowRule() {
+        TrafficSelector ts = DefaultTrafficSelector.builder().build();
+        TrafficTreatment tr = DefaultTrafficTreatment.builder()
+                .setOutput(PORT_NUM2).build();
+
+        FlowRule r1 = DefaultFlowRule.builder()
+                .forDevice(VDID)
+                .withSelector(ts)
+                .withTreatment(tr)
+                .withPriority(10)
+                .fromApp(vAppId)
+                .makeTemporary(TIMEOUT)
+                .build();
+
+        virtualProvider.removeFlowRule(VNET_ID, r1);
+
+        assertEquals("0 rules should exist", 0,
+                     virtualProvider.flowRuleService.getFlowRuleCount());
+    }
+
+
+    private static class TestDeviceService extends DeviceServiceAdapter {
+        @Override
+        public int getDeviceCount() {
+            return 2;
+        }
+
+        @Override
+        public Iterable<Device> getDevices() {
+            return ImmutableList.of(DEV1, DEV2);
+        }
+
+        @Override
+        public Iterable<Device> getAvailableDevices() {
+            return getDevices();
+        }
+
+        @Override
+        public Device getDevice(DeviceId deviceId) {
+            return deviceId.equals(DID2) ? DEV2 : DEV1;
+        }
+    }
+
+    private static class TestCoreService extends CoreServiceAdapter {
+
+        @Override
+        public ApplicationId registerApplication(String name) {
+            return new TestApplicationId(1, name);
+        }
+    }
+
+    private static class TestApplicationId extends DefaultApplicationId {
+        public TestApplicationId(int id, String name) {
+            super(id, name);
+        }
+    }
+
+    private class TestVirtualNetworkAdminService
+            extends VirtualNetworkAdminServiceAdapter {
+
+        @Override
+        public Set<VirtualDevice> getVirtualDevices(NetworkId networkId) {
+            return ImmutableSet.of(VDEV);
+        }
+
+        @Override
+        public Set<VirtualLink> getVirtualLinks(NetworkId networkId) {
+            return new HashSet<>();
+        }
+
+        @Override
+        public Set<VirtualPort> getVirtualPorts(NetworkId networkId,
+                                                DeviceId deviceId) {
+            return ImmutableSet.of(VPORT1, VPORT2);
+        }
+
+        @Override
+        public ApplicationId getVirtualNetworkApplicationId(NetworkId networkId) {
+            return vAppId;
+        }
+    }
+
+    private static class TestTopologyService extends TopologyServiceAdapter {
+
+        Weight oneHundred = ScalarWeight.toWeight(100);
+        @Override
+        public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst) {
+            DefaultPath path = new DefaultPath(PID, ImmutableList.of(LINK1),
+                                               oneHundred, ANNOTATIONS);
+            return ImmutableSet.of(path);
+        }
+
+        @Override
+        public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst,
+                                  LinkWeigher weigher) {
+            DefaultPath path = new DefaultPath(PID, ImmutableList.of(LINK1),
+                                               oneHundred, ANNOTATIONS);
+            return ImmutableSet.of(path);
+        }
+
+    }
+
+    private static class TestFlowRuleService extends FlowRuleServiceAdapter {
+        static Set<FlowRule> ruleCollection = new HashSet<>();
+
+        @Override
+        public int getFlowRuleCount() {
+            return ruleCollection.size();
+        }
+
+        @Override
+        public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
+            return ruleCollection.stream()
+                    .filter(r -> r.deviceId().equals(deviceId))
+                    .map(DefaultFlowEntry::new)
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public void applyFlowRules(FlowRule... flowRules) {
+            ruleCollection.addAll(Arrays.asList(flowRules));
+        }
+
+        @Override
+        public void removeFlowRules(FlowRule... flowRules) {
+            Set<FlowRule> candidates = new HashSet<>();
+            for (FlowRule rule : flowRules) {
+                ruleCollection.stream()
+                        .filter(r -> r.exactMatch(rule))
+                        .forEach(candidates::add);
+            }
+            ruleCollection.removeAll(candidates);
+        }
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualPacketProviderTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualPacketProviderTest.java
new file mode 100644
index 0000000..a17a0db
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/DefaultVirtualPacketProviderTest.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright 2016-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.incubator.net.virtual.impl.provider;
+
+import com.google.common.collect.ImmutableSet;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.incubator.net.virtual.DefaultVirtualDevice;
+import org.onosproject.incubator.net.virtual.DefaultVirtualNetwork;
+import org.onosproject.incubator.net.virtual.DefaultVirtualPort;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.VirtualNetworkAdminServiceAdapter;
+import org.onosproject.incubator.net.virtual.VirtualPort;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProviderService;
+import org.onosproject.incubator.net.virtual.provider.VirtualPacketProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualPacketProviderService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.packet.DefaultInboundPacket;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+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.PacketProcessor;
+import org.onosproject.net.packet.PacketServiceAdapter;
+import org.onosproject.net.provider.ProviderId;
+
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+
+public class DefaultVirtualPacketProviderTest {
+    private static final String SRC_MAC_ADDR = "00:00:00:00:00:00";
+    private static final String DST_MAC_ADDR = "00:00:00:00:00:01";
+    private static final ProviderId PID = new ProviderId("of", "foo");
+
+    private static final DeviceId DID1 = DeviceId.deviceId("of:001");
+    private static final DeviceId DID2 = DeviceId.deviceId("of:002");
+    private static final PortNumber PORT_NUM1 = PortNumber.portNumber(1);
+    private static final PortNumber PORT_NUM2 = PortNumber.portNumber(2);
+    private static final PortNumber PORT_NUM3 = PortNumber.portNumber(3);
+    private static final PortNumber PORT_NUM4 = PortNumber.portNumber(4);
+
+    private static final DefaultAnnotations ANNOTATIONS =
+            DefaultAnnotations.builder().set("foo", "bar").build();
+
+    private static final Device DEV1 =
+            new DefaultDevice(PID, DID1, Device.Type.SWITCH, "", "", "", "", null);
+    private static final Device DEV2 =
+            new DefaultDevice(PID, DID2, Device.Type.SWITCH, "", "", "", "", null);
+    private static final Port PORT11 =
+            new DefaultPort(DEV1, PORT_NUM1, true, ANNOTATIONS);
+    private static final Port PORT12 =
+            new DefaultPort(DEV1, PORT_NUM2, true, ANNOTATIONS);
+    private static final Port PORT21 =
+            new DefaultPort(DEV2, PORT_NUM3, true, ANNOTATIONS);
+    private static final Port PORT22 =
+            new DefaultPort(DEV2, PORT_NUM4, true, ANNOTATIONS);
+
+    private static final ConnectPoint CP11 = new ConnectPoint(DID1, PORT_NUM1);
+    private static final ConnectPoint CP12 = new ConnectPoint(DID1, PORT_NUM2);
+    private static final ConnectPoint CP21 = new ConnectPoint(DID2, PORT_NUM3);
+    private static final ConnectPoint CP22 = new ConnectPoint(DID2, PORT_NUM4);
+    private static final Link LINK1 = DefaultLink.builder()
+            .src(CP12).dst(CP21).providerId(PID).type(Link.Type.DIRECT).build();
+
+    private static final TenantId TENANT_ID = TenantId.tenantId("1");
+    private static final NetworkId VNET_ID = NetworkId.networkId(1);
+    private static final DeviceId VDID = DeviceId.deviceId("of:100");
+
+    private static final PortNumber VPORT_NUM1 = PortNumber.portNumber(10);
+    private static final PortNumber VPORT_NUM2 = PortNumber.portNumber(11);
+
+    private static final VirtualNetwork VNET = new DefaultVirtualNetwork(
+            VNET_ID, TenantId.tenantId("t1"));
+    private static final VirtualDevice VDEV =
+            new DefaultVirtualDevice(VNET_ID, VDID);
+    private static final VirtualPort VPORT1 =
+            new DefaultVirtualPort(VNET_ID, VDEV, VPORT_NUM1, CP11);
+    private static final VirtualPort VPORT2 =
+            new DefaultVirtualPort(VNET_ID, VDEV, VPORT_NUM2, CP22);
+    private static final ConnectPoint VCP11 = new ConnectPoint(VDID, VPORT_NUM1);
+    private static final ConnectPoint VCP12 = new ConnectPoint(VDID, VPORT_NUM2);
+
+    protected DefaultVirtualPacketProvider virtualProvider;
+    protected TestPacketService testPacketService;
+    protected TestVirtualPacketProviderService providerService;
+
+    private VirtualProviderManager providerManager;
+
+    private ApplicationId vAppId;
+
+    @Before
+    public void setUp() {
+        virtualProvider = new DefaultVirtualPacketProvider();
+
+        virtualProvider.coreService = new CoreServiceAdapter();
+        virtualProvider.vnaService =
+                new TestVirtualNetworkAdminService();
+
+        providerService = new TestVirtualPacketProviderService();
+
+        testPacketService = new TestPacketService();
+        virtualProvider.packetService = testPacketService;
+
+        providerManager = new VirtualProviderManager();
+        virtualProvider.providerRegistryService = providerManager;
+        providerManager.registerProviderService(VNET_ID, providerService);
+
+        virtualProvider.activate();
+        vAppId = new TestApplicationId(0, "Virtual App");
+
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+
+        virtualProvider.startPacketHandling();
+    }
+
+    @After
+    public void tearDown() {
+        virtualProvider.deactivate();
+        virtualProvider.coreService = null;
+        virtualProvider.vnaService = null;
+    }
+
+
+    /** Test the virtual outbound packet is delivered to a proper (physical)
+     *  device.
+     */
+    @Test
+    public void devirtualizePacket() {
+        TrafficTreatment tr = DefaultTrafficTreatment.builder()
+                .setOutput(VPORT_NUM1).build();
+        ByteBuffer data = ByteBuffer.wrap("abc".getBytes());
+
+        OutboundPacket vOutPacket = new DefaultOutboundPacket(VDID, tr, data);
+
+        virtualProvider.emit(VNET_ID, vOutPacket);
+
+        assertEquals("The count should be 1", 1,
+                     testPacketService.getRequestedPacketCount());
+
+        OutboundPacket pOutPacket = testPacketService.getRequestedPacket(0);
+
+        assertEquals("The packet should be requested on DEV1", DID1,
+                     pOutPacket.sendThrough());
+
+        PortNumber outPort = pOutPacket.treatment()
+                .allInstructions()
+                .stream()
+                .filter(i -> i.type() == Instruction.Type.OUTPUT)
+                .map(i -> (Instructions.OutputInstruction) i)
+                .map(i -> i.port())
+                .findFirst().get();
+        assertEquals("The packet should be out at PORT1 of DEV1", PORT_NUM1,
+                     outPort);
+    }
+
+    /** Test the physical packet context is delivered to a proper (physical)
+     *  virtual network and device.
+     */
+    @Test
+    public void virtualizePacket() {
+        Ethernet eth = new Ethernet();
+        eth.setSourceMACAddress(SRC_MAC_ADDR);
+        eth.setDestinationMACAddress(DST_MAC_ADDR);
+        eth.setVlanID((short) 1);
+        eth.setPayload(null);
+
+        InboundPacket pInPacket =
+                new DefaultInboundPacket(CP22, eth,
+                                         ByteBuffer.wrap(eth.serialize()));
+
+        PacketContext pContext =
+                new TestPacketContext(System.nanoTime(), pInPacket, null, false);
+
+        testPacketService.sendTestPacketContext(pContext);
+
+        PacketContext vContext = providerService.getRequestedPacketContext(0);
+        InboundPacket vInPacket = vContext.inPacket();
+
+        assertEquals("the packet should be received from VCP12",
+                     VCP12, vInPacket.receivedFrom());
+
+        assertEquals("VLAN tag should be excludede", VlanId.UNTAGGED,
+                     vInPacket.parsed().getVlanID());
+    }
+
+    private class TestPacketContext extends DefaultPacketContext {
+
+        /**
+         * Creates a new packet context.
+         *
+         * @param time   creation time
+         * @param inPkt  inbound packet
+         * @param outPkt outbound packet
+         * @param block  whether the context is blocked or not
+         */
+        protected TestPacketContext(long time, InboundPacket inPkt,
+                                    OutboundPacket outPkt, boolean block) {
+            super(time, inPkt, outPkt, block);
+        }
+
+        @Override
+        public void send() {
+
+        }
+    }
+
+    private static class TestApplicationId extends DefaultApplicationId {
+        public TestApplicationId(int id, String name) {
+            super(id, name);
+        }
+    }
+
+    private static class TestVirtualNetworkAdminService
+            extends VirtualNetworkAdminServiceAdapter {
+
+        @Override
+        public Set<VirtualNetwork> getVirtualNetworks(TenantId tenantId) {
+            return ImmutableSet.of(VNET);
+        }
+
+        @Override
+        public Set<VirtualDevice> getVirtualDevices(NetworkId networkId) {
+            return ImmutableSet.of(VDEV);
+        }
+
+        @Override
+        public Set<VirtualPort> getVirtualPorts(NetworkId networkId,
+                                                DeviceId deviceId) {
+            return ImmutableSet.of(VPORT1, VPORT2);
+        }
+
+        @Override
+        public Set<TenantId> getTenantIds() {
+            return ImmutableSet.of(TENANT_ID);
+        }
+
+    }
+
+    private static class TestVirtualPacketProviderService
+            extends AbstractVirtualProviderService<VirtualPacketProvider>
+            implements VirtualPacketProviderService {
+
+        static List<PacketContext> requestedContext = new LinkedList();
+        static List<NetworkId> requestedNetworkId = new LinkedList();
+
+        @Override
+        public VirtualPacketProvider provider() {
+            return null;
+        }
+
+        PacketContext getRequestedPacketContext(int index) {
+            return requestedContext.get(index);
+        }
+
+        @Override
+        public void processPacket(PacketContext context) {
+            requestedContext.add(context);
+        }
+    }
+
+    private static class TestPacketService extends PacketServiceAdapter {
+        static List<OutboundPacket> requestedPacket = new LinkedList();
+        static PacketProcessor processor = null;
+
+        @Override
+        public void addProcessor(PacketProcessor processor, int priority) {
+            this.processor = processor;
+        }
+
+        @Override
+        public void emit(OutboundPacket packet) {
+            requestedPacket.add(packet);
+        }
+
+        OutboundPacket getRequestedPacket(int index) {
+            return requestedPacket.get(index);
+        }
+
+        int getRequestedPacketCount() {
+            return requestedPacket.size();
+        }
+
+        void sendTestPacketContext(PacketContext context) {
+            processor.process(context);
+        }
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualNetworkTopologyProviderTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualNetworkTopologyProviderTest.java
new file mode 100644
index 0000000..ee03783
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualNetworkTopologyProviderTest.java
@@ -0,0 +1,392 @@
+/*
+ * Copyright 2016-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.incubator.net.virtual.impl.provider;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.event.Event;
+import org.onosproject.incubator.net.tunnel.TunnelId;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.net.TenantId;
+import org.onosproject.incubator.net.virtual.VirtualDevice;
+import org.onosproject.incubator.net.virtual.VirtualLink;
+import org.onosproject.incubator.net.virtual.VirtualNetwork;
+import org.onosproject.incubator.net.virtual.provider.VirtualNetworkProvider;
+import org.onosproject.incubator.net.virtual.provider.VirtualNetworkProviderRegistry;
+import org.onosproject.incubator.net.virtual.provider.VirtualNetworkProviderService;
+import org.onosproject.incubator.net.virtual.impl.VirtualNetworkManager;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Link;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TestDeviceParams;
+import org.onosproject.net.intent.FakeIntentManager;
+import org.onosproject.net.intent.TestableIntentService;
+import org.onosproject.net.link.LinkEvent;
+import org.onosproject.net.provider.AbstractProviderService;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.topology.TopologyEvent;
+import org.onosproject.net.topology.TopologyService;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.junit.Assert.*;
+
+/**
+ * Junit tests for VirtualNetworkTopologyProvider.
+ */
+public class VirtualNetworkTopologyProviderTest extends TestDeviceParams {
+
+    private final String tenantIdValue1 = "TENANT_ID1";
+
+    private VirtualNetwork virtualNetwork;
+    private VirtualDevice virtualDevice1;
+    private VirtualDevice virtualDevice2;
+    private VirtualDevice virtualDevice3;
+    private VirtualDevice virtualDevice4;
+    private VirtualDevice virtualDevice5;
+    private ConnectPoint cp1;
+    private ConnectPoint cp2;
+    private ConnectPoint cp3;
+    private ConnectPoint cp4;
+    private ConnectPoint cp5;
+    private ConnectPoint cp6;
+    private ConnectPoint cp7;
+    private ConnectPoint cp8;
+    private ConnectPoint cp9;
+
+    private VirtualNetworkManager manager;
+    private DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private CoreService coreService;
+    private DefaultVirtualNetworkProvider topologyProvider;
+    private TopologyService topologyService;
+    private TestableIntentService intentService = new FakeIntentManager();
+    private TestServiceDirectory testDirectory;
+    private final VirtualNetworkRegistryAdapter virtualNetworkRegistry = new VirtualNetworkRegistryAdapter();
+
+    private static final int MAX_WAIT_TIME = 5;
+    private static final int MAX_PERMITS = 1;
+    private static Semaphore changed;
+
+    private Set<Set<ConnectPoint>> clusters;
+
+    @Before
+    public void setUp() throws Exception {
+
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+
+        coreService = new VirtualNetworkTopologyProviderTest.TestCoreService();
+
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService",
+                           new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        TestUtils.setField(manager, "coreService", coreService);
+        TestUtils.setField(manager, "store", virtualNetworkManagerStore);
+        TestUtils.setField(manager, "intentService", intentService);
+        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+
+        testDirectory = new TestServiceDirectory();
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+
+        topologyService = manager.get(virtualNetwork.id(), TopologyService.class);
+        topologyProvider = new DefaultVirtualNetworkProvider();
+        topologyProvider.topologyService = topologyService;
+        topologyProvider.providerRegistry = virtualNetworkRegistry;
+        topologyProvider.activate();
+
+        setupVirtualNetworkTopology();
+        changed = new Semaphore(0, true);
+    }
+
+    @After
+    public void tearDown() {
+        topologyProvider.deactivate();
+        virtualNetworkManagerStore.deactivate();
+        manager.deactivate();
+        NetTestTools.injectEventDispatcher(manager, null);
+    }
+
+    /**
+     * Method to create the virtual network for further testing.
+     **/
+    private void setupVirtualNetworkTopology() {
+        virtualDevice1 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        virtualDevice2 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID2);
+        virtualDevice3 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID3);
+        virtualDevice4 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID4);
+        virtualDevice5 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID5);
+
+        cp1 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(),
+                                  PortNumber.portNumber(1), cp1);
+
+        cp2 = new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(2));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(),
+                                  PortNumber.portNumber(2), cp2);
+
+        cp3 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(3));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(),
+                                  PortNumber.portNumber(3), cp3);
+
+        cp4 = new ConnectPoint(virtualDevice2.id(), PortNumber.portNumber(4));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(),
+                                  PortNumber.portNumber(4), cp4);
+
+        cp5 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(5));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(),
+                                  PortNumber.portNumber(5), cp5);
+
+        cp6 = new ConnectPoint(virtualDevice3.id(), PortNumber.portNumber(6));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(),
+                                  PortNumber.portNumber(6), cp6);
+
+        cp7 = new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(7));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice4.id(),
+                                  PortNumber.portNumber(7), cp7);
+
+        cp8 = new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(8));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice4.id(),
+                                  PortNumber.portNumber(8), cp8);
+
+        cp9 = new ConnectPoint(virtualDevice5.id(), PortNumber.portNumber(9));
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice5.id(),
+                                  PortNumber.portNumber(9), cp9);
+
+        VirtualLink link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3);
+        virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1);
+        virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5);
+        virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4);
+        virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link5 = manager.createVirtualLink(virtualNetwork.id(), cp8, cp9);
+        virtualNetworkManagerStore.updateLink(link5, link5.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link6 = manager.createVirtualLink(virtualNetwork.id(), cp9, cp8);
+        virtualNetworkManagerStore.updateLink(link6, link6.tunnelId(), Link.State.ACTIVE);
+
+        clusters = null;
+    }
+
+    /**
+     * Test isTraversable() method using a null source connect point.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testIsTraversableNullSrc() {
+        // test the isTraversable() method with a null source connect point.
+        topologyProvider.isTraversable(null, cp3);
+    }
+
+    /**
+     * Test isTraversable() method using a null destination connect point.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testIsTraversableNullDst() {
+        // test the isTraversable() method with a null destination connect point.
+        topologyProvider.isTraversable(cp1, null);
+    }
+
+    /**
+     * Test isTraversable() method.
+     */
+    @Test
+    public void testIsTraversable() {
+        // test the isTraversable() method.
+        assertTrue("These two connect points should be traversable.",
+                   topologyProvider.isTraversable(new ConnectPoint(cp1.elementId(), cp1.port()),
+                                                  new ConnectPoint(cp3.elementId(), cp3.port())));
+        assertTrue("These two connect points should be traversable.",
+                   topologyProvider.isTraversable(new ConnectPoint(cp1.elementId(), cp1.port()),
+                                                  new ConnectPoint(cp5.elementId(), cp5.port())));
+        assertFalse("These two connect points should not be traversable.",
+                    topologyProvider.isTraversable(
+                            new ConnectPoint(virtualDevice1.id(), PortNumber.portNumber(1)),
+                            new ConnectPoint(virtualDevice4.id(), PortNumber.portNumber(6))));
+    }
+
+    /**
+     * Test the topologyChanged() method.
+     */
+    @Test
+    public void testTopologyChanged() {
+        // Initial setup is two clusters of devices/links.
+        assertEquals("The cluster count did not match.", 2,
+                     topologyService.currentTopology().clusterCount());
+
+        // Adding this link will join the two clusters together.
+        List<Event> reasons = new ArrayList<>();
+        VirtualLink link = manager.createVirtualLink(virtualNetwork.id(), cp6, cp7);
+        virtualNetworkManagerStore.updateLink(link, link.tunnelId(), Link.State.ACTIVE);
+        VirtualLink link2 = manager.createVirtualLink(virtualNetwork.id(), cp7, cp6);
+        virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
+
+        reasons.add(new LinkEvent(LinkEvent.Type.LINK_ADDED, link));
+        reasons.add(new LinkEvent(LinkEvent.Type.LINK_ADDED, link2));
+        TopologyEvent event = new TopologyEvent(
+                TopologyEvent.Type.TOPOLOGY_CHANGED,
+                topologyService.currentTopology(),
+                reasons);
+
+        topologyProvider.topologyListener.event(event);
+
+        // Wait for the topology changed event, and that the topologyChanged method was called.
+        try {
+            if (!changed.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
+                fail("Failed to wait for topology changed event.");
+            }
+        } catch (InterruptedException e) {
+            fail("Semaphore exception." + e.getMessage());
+        }
+
+        // Validate that the topology changed method received a single cluster of connect points.
+        // This means that the two previous clusters have now joined into a single cluster.
+        assertEquals("The cluster count did not match.", 1, this.clusters.size());
+        assertEquals("The cluster count did not match.", 1,
+                     topologyService.currentTopology().clusterCount());
+
+        // Now remove the virtual link to split it back into two clusters.
+        manager.removeVirtualLink(virtualNetwork.id(), link.src(), link.dst());
+        manager.removeVirtualLink(virtualNetwork.id(), link2.src(), link2.dst());
+        assertEquals("The cluster count did not match.", 2,
+                     topologyService.currentTopology().clusterCount());
+
+        reasons = new ArrayList<>();
+        reasons.add(new LinkEvent(LinkEvent.Type.LINK_REMOVED, link));
+        reasons.add(new LinkEvent(LinkEvent.Type.LINK_REMOVED, link2));
+        event = new TopologyEvent(
+                TopologyEvent.Type.TOPOLOGY_CHANGED,
+                topologyService.currentTopology(),
+                reasons);
+
+        topologyProvider.topologyListener.event(event);
+
+        // Wait for the topology changed event, and that the topologyChanged method was called.
+        try {
+            if (!changed.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
+                fail("Failed to wait for topology changed event.");
+            }
+        } catch (InterruptedException e) {
+            fail("Semaphore exception." + e.getMessage());
+        }
+
+        // Validate that the topology changed method received two clusters of connect points.
+        // This means that the single previous clusters has now split into two clusters.
+        assertEquals("The cluster count did not match.", 2, this.clusters.size());
+    }
+
+    /**
+     * Virtual network registry implementation for this test class.
+     */
+    private class VirtualNetworkRegistryAdapter implements VirtualNetworkProviderRegistry {
+        private VirtualNetworkProvider provider;
+
+        @Override
+        public VirtualNetworkProviderService register(VirtualNetworkProvider theProvider) {
+            this.provider = theProvider;
+            return new TestVirtualNetworkProviderService(theProvider);
+        }
+
+        @Override
+        public void unregister(VirtualNetworkProvider theProvider) {
+            this.provider = null;
+        }
+
+        @Override
+        public Set<ProviderId> getProviders() {
+            return null;
+        }
+    }
+
+
+    /**
+     * Virtual network provider service implementation for this test class.
+     */
+    private class TestVirtualNetworkProviderService
+            extends AbstractProviderService<VirtualNetworkProvider>
+            implements VirtualNetworkProviderService {
+
+        /**
+         * Constructor.
+         *
+         * @param provider virtual network test provider
+         */
+        protected TestVirtualNetworkProviderService(VirtualNetworkProvider provider) {
+            super(provider);
+        }
+
+        @Override
+        public void topologyChanged(Set<Set<ConnectPoint>> theClusters) {
+            clusters = theClusters;
+            changed.release();
+        }
+
+        @Override
+        public void tunnelUp(NetworkId networkId, ConnectPoint src,
+                             ConnectPoint dst, TunnelId tunnelId) {
+        }
+
+        @Override
+        public void tunnelDown(NetworkId networkId, ConnectPoint src,
+                               ConnectPoint dst, TunnelId tunnelId) {
+        }
+    }
+
+    /**
+     * Core service test class.
+     */
+    private class TestCoreService extends CoreServiceAdapter {
+
+        @Override
+        public IdGenerator getIdGenerator(String topic) {
+            return new IdGenerator() {
+                private AtomicLong counter = new AtomicLong(0);
+
+                @Override
+                public long getNewId() {
+                    return counter.getAndIncrement();
+                }
+            };
+        }
+    }
+}
diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManagerTest.java
new file mode 100644
index 0000000..90e1664
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/provider/VirtualProviderManagerTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2017-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.incubator.net.virtual.impl.provider;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.incubator.net.virtual.NetworkId;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProvider;
+import org.onosproject.incubator.net.virtual.provider.AbstractVirtualProviderService;
+import org.onosproject.net.provider.ProviderId;
+
+import static org.junit.Assert.assertEquals;
+
+public class VirtualProviderManagerTest {
+
+    private static final String TEST_SCHEME1 = "test1";
+    private static final String TEST_SCHEME2 = "test2";
+    private static final String TEST_ID1 = "org.onosproject.virtual.testprovider1";
+    private static final String TEST_ID2 = "org.onosproject.virtual.testprovider1";
+    private static final NetworkId NETWORK_ID1 = NetworkId.networkId(1);
+    private static final NetworkId NETWORK_ID2 = NetworkId.networkId(2);
+
+    VirtualProviderManager virtualProviderManager;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualProviderManager = new VirtualProviderManager();
+    }
+
+    /**
+     * Tests registerProvider() and unregisterProvider().
+     */
+    @Test
+    public void registerProviderTest() {
+        TestProvider1 provider1 = new TestProvider1();
+        virtualProviderManager.registerProvider(provider1);
+
+        assertEquals("The number of registered provider did not match.", 1,
+                     virtualProviderManager.getProviders().size());
+
+        assertEquals("The registered provider did not match", provider1,
+                     virtualProviderManager.getProvider(TEST_SCHEME1));
+
+        virtualProviderManager.unregisterProvider(provider1);
+
+        TestProvider2 provider2 = new TestProvider2();
+        virtualProviderManager.registerProvider(provider2);
+
+        assertEquals("The number of registered provider did not match.", 1,
+                     virtualProviderManager.getProviders().size());
+
+        virtualProviderManager.unregisterProvider(provider2);
+
+        assertEquals("The number of registered provider did not match.", 0,
+                     virtualProviderManager.getProviders().size());
+    }
+
+    /**
+     * Tests registerProviderService() and getProviderService().
+     */
+    @Test
+    public void registerProviderServiceTest() {
+        TestProvider1 provider1 = new TestProvider1();
+        virtualProviderManager.registerProvider(provider1);
+
+        TestProviderService1 providerService1 = new TestProviderService1();
+        virtualProviderManager.registerProviderService(NETWORK_ID1, providerService1);
+
+        assertEquals(providerService1,
+                     virtualProviderManager.getProviderService(NETWORK_ID1, TestProvider1.class));
+    }
+
+    private class TestProvider1 extends AbstractVirtualProvider {
+        protected TestProvider1() {
+            super(new ProviderId(TEST_SCHEME1, TEST_ID1));
+        }
+    }
+
+    private class TestProvider2 extends AbstractVirtualProvider {
+        protected TestProvider2() {
+            super(new ProviderId(TEST_SCHEME2, TEST_ID2));
+        }
+    }
+
+    private class TestProviderService1 extends AbstractVirtualProviderService<TestProvider1> {
+    }
+
+    private class TestProviderService2 extends AbstractVirtualProviderService<TestProvider2> {
+    }
+}
