diff --git a/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkIntentManagerTest.java b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkIntentManagerTest.java
new file mode 100644
index 0000000..ba0adda
--- /dev/null
+++ b/apps/virtual/app/src/test/java/org/onosproject/incubator/net/virtual/impl/VirtualNetworkIntentManagerTest.java
@@ -0,0 +1,414 @@
+/*
+ * 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;
+
+import com.google.common.collect.Iterators;
+import com.google.common.collect.Lists;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.TestApplicationId;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.IdGenerator;
+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.VirtualNetworkIntent;
+import org.onosproject.incubator.net.virtual.VirtualNetworkIntentStore;
+import org.onosproject.incubator.net.virtual.VirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.DistributedVirtualNetworkStore;
+import org.onosproject.incubator.net.virtual.store.impl.SimpleVirtualIntentStore;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultPort;
+import org.onosproject.net.EncapsulationType;
+import org.onosproject.net.Link;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.TestDeviceParams;
+import org.onosproject.net.intent.Constraint;
+import org.onosproject.net.intent.FakeIntentManager;
+import org.onosproject.net.intent.FlowRuleIntent;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentCompiler;
+import org.onosproject.net.intent.IntentEvent;
+import org.onosproject.net.intent.IntentExtensionService;
+import org.onosproject.net.intent.IntentListener;
+import org.onosproject.net.intent.IntentService;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.IntentTestsMocks;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MockIdGenerator;
+import org.onosproject.net.intent.PathIntent;
+import org.onosproject.net.intent.TestableIntentService;
+import org.onosproject.net.intent.WorkPartitionService;
+import org.onosproject.net.intent.WorkPartitionServiceAdapter;
+import org.onosproject.net.intent.constraint.EncapsulationConstraint;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Junit tests for VirtualNetworkIntentService.
+ */
+@Ignore("deprecated prototype implementation")
+public class VirtualNetworkIntentManagerTest extends TestDeviceParams {
+
+    private final String tenantIdValue1 = "TENANT_ID1";
+    private static final ApplicationId APP_ID =
+            new TestApplicationId("MyAppId");
+
+    private ConnectPoint cp1;
+    private ConnectPoint cp2;
+    private ConnectPoint cp3;
+    private ConnectPoint cp4;
+    private ConnectPoint cp5;
+    private ConnectPoint cp6;
+    private VirtualLink link1;
+    private VirtualLink link2;
+    private VirtualLink link3;
+    private VirtualLink link4;
+    private VirtualLink link5;
+    private VirtualLink link6;
+
+    private VirtualNetworkManager manager;
+    private static DistributedVirtualNetworkStore virtualNetworkManagerStore;
+    private VirtualNetworkIntentStore intentStore;
+    private CoreService coreService;
+    private TestableIntentService intentService = new FakeIntentManager();
+    private VirtualNetworkIntentManager vnetIntentService;
+    private TestIntentCompiler compiler = new TestIntentCompiler();
+    private IntentExtensionService intentExtensionService;
+    private WorkPartitionService workPartitionService;
+    private ServiceDirectory testDirectory;
+    private TestListener listener = new TestListener();
+    private static final int MAX_WAIT_TIME = 5;
+    private static final int MAX_PERMITS = 1;
+    private static Semaphore created;
+    private static Semaphore withdrawn;
+    private static Semaphore purged;
+
+    @Before
+    public void setUp() throws Exception {
+        virtualNetworkManagerStore = new DistributedVirtualNetworkStore();
+        intentStore = new SimpleVirtualIntentStore();
+
+        coreService = new VirtualNetworkIntentManagerTest.TestCoreService();
+
+        MockIdGenerator.cleanBind();
+
+        TestUtils.setField(virtualNetworkManagerStore, "coreService", coreService);
+        TestUtils.setField(virtualNetworkManagerStore, "storageService", new TestStorageService());
+        virtualNetworkManagerStore.activate();
+
+        manager = new VirtualNetworkManager();
+        manager.store = virtualNetworkManagerStore;
+        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
+        intentService.addListener(listener);
+
+        // Register a compiler and an installer both setup for success.
+        intentExtensionService = intentService;
+        intentExtensionService.registerCompiler(VirtualNetworkIntent.class, compiler);
+
+        created = new Semaphore(0, true);
+        withdrawn = new Semaphore(0, true);
+        purged = new Semaphore(0, true);
+
+        workPartitionService = new WorkPartitionServiceAdapter();
+        testDirectory = new TestServiceDirectory()
+                .add(VirtualNetworkStore.class, virtualNetworkManagerStore)
+                .add(IntentService.class, intentService)
+                .add(WorkPartitionService.class, workPartitionService);
+        TestUtils.setField(manager, "serviceDirectory", testDirectory);
+
+        manager.activate();
+    }
+
+    @After
+    public void tearDown() {
+        virtualNetworkManagerStore.deactivate();
+        manager.deactivate();
+        NetTestTools.injectEventDispatcher(manager, null);
+        MockIdGenerator.unbind();
+        intentService.removeListener(listener);
+        created = null;
+        withdrawn = null;
+        purged = null;
+    }
+
+    /**
+     * Method to create the virtual network for further testing.
+     *
+     * @return virtual network
+     */
+    private VirtualNetwork setupVirtualNetworkTopology() {
+        manager.registerTenantId(TenantId.tenantId(tenantIdValue1));
+        VirtualNetwork virtualNetwork = manager.createVirtualNetwork(TenantId.tenantId(tenantIdValue1));
+        VirtualDevice virtualDevice1 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID1);
+        VirtualDevice virtualDevice2 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID2);
+        VirtualDevice virtualDevice3 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID3);
+        VirtualDevice virtualDevice4 =
+                manager.createVirtualDevice(virtualNetwork.id(), DID4);
+
+        Port port1 = new DefaultPort(virtualDevice1, PortNumber.portNumber(1), true);
+        cp1 = new ConnectPoint(virtualDevice1.id(), port1.number());
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), port1.number(), cp1);
+
+        Port port2 = new DefaultPort(virtualDevice1, PortNumber.portNumber(2), true);
+        cp2 = new ConnectPoint(virtualDevice1.id(), port2.number());
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice1.id(), port2.number(), cp2);
+
+        Port port3 = new DefaultPort(virtualDevice2, PortNumber.portNumber(3), true);
+        cp3 = new ConnectPoint(virtualDevice2.id(), port3.number());
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), port3.number(), cp3);
+
+        Port port4 = new DefaultPort(virtualDevice2, PortNumber.portNumber(4), true);
+        cp4 = new ConnectPoint(virtualDevice2.id(), port4.number());
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice2.id(), port4.number(), cp4);
+
+        Port port5 = new DefaultPort(virtualDevice3, PortNumber.portNumber(5), true);
+        cp5 = new ConnectPoint(virtualDevice3.id(), port5.number());
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), port5.number(), cp5);
+
+        Port port6 = new DefaultPort(virtualDevice3, PortNumber.portNumber(6), true);
+        cp6 = new ConnectPoint(virtualDevice3.id(), port6.number());
+        manager.createVirtualPort(virtualNetwork.id(), virtualDevice3.id(), port6.number(), cp6);
+
+        link1 = manager.createVirtualLink(virtualNetwork.id(), cp1, cp3);
+        virtualNetworkManagerStore.updateLink(link1, link1.tunnelId(), Link.State.ACTIVE);
+        link2 = manager.createVirtualLink(virtualNetwork.id(), cp3, cp1);
+        virtualNetworkManagerStore.updateLink(link2, link2.tunnelId(), Link.State.ACTIVE);
+        link3 = manager.createVirtualLink(virtualNetwork.id(), cp4, cp5);
+        virtualNetworkManagerStore.updateLink(link3, link3.tunnelId(), Link.State.ACTIVE);
+        link4 = manager.createVirtualLink(virtualNetwork.id(), cp5, cp4);
+        virtualNetworkManagerStore.updateLink(link4, link4.tunnelId(), Link.State.ACTIVE);
+
+        vnetIntentService = new VirtualNetworkIntentManager(manager, virtualNetwork.id());
+        vnetIntentService.intentStore = intentStore;
+        return virtualNetwork;
+    }
+
+    /**
+     * Tests the submit(), withdraw(), and purge() methods.
+     */
+    @Test
+    public void testCreateAndRemoveIntent() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        Key intentKey = Key.of("test", APP_ID);
+
+        List<Constraint> constraints = new ArrayList<>();
+        constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));
+
+        VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
+                .networkId(virtualNetwork.id())
+                .key(intentKey)
+                .appId(APP_ID)
+                .ingressPoint(cp1)
+                .egressPoint(cp5)
+                .constraints(constraints)
+                .build();
+        // Test the submit() method.
+        vnetIntentService.submit(virtualIntent);
+
+        // Wait for the both intents to go into an INSTALLED state.
+        try {
+            if (!created.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
+                fail("Failed to wait for intent to get installed.");
+            }
+        } catch (InterruptedException e) {
+            fail("Semaphore exception during intent installation." + e.getMessage());
+        }
+
+        // Test the getIntentState() method
+        assertEquals("The intent state did not match as expected.", IntentState.INSTALLED,
+                     vnetIntentService.getIntentState(virtualIntent.key()));
+
+        // Test the withdraw() method.
+        vnetIntentService.withdraw(virtualIntent);
+        // Wait for the both intents to go into a WITHDRAWN state.
+        try {
+            if (!withdrawn.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
+                fail("Failed to wait for intent to get withdrawn.");
+            }
+        } catch (InterruptedException e) {
+            fail("Semaphore exception during intent withdrawal." + e.getMessage());
+        }
+
+        // Test the getIntentState() method
+        assertEquals("The intent state did not match as expected.", IntentState.WITHDRAWN,
+                     vnetIntentService.getIntentState(virtualIntent.key()));
+
+        // Test the purge() method.
+        vnetIntentService.purge(virtualIntent);
+        // Wait for the both intents to be removed/purged.
+        try {
+            if (!purged.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
+                fail("Failed to wait for intent to get purged.");
+            }
+        } catch (InterruptedException e) {
+            fail("Semaphore exception during intent purging." + e.getMessage());
+        }
+
+    }
+
+    /**
+     * Tests the getIntents, getIntent(), getIntentData(), getIntentCount(),
+     * isLocal() methods.
+     */
+    @Test
+    public void testGetIntents() {
+        VirtualNetwork virtualNetwork = setupVirtualNetworkTopology();
+
+        Key intentKey = Key.of("test", APP_ID);
+
+        List<Constraint> constraints = new ArrayList<>();
+        constraints.add(new EncapsulationConstraint(EncapsulationType.VLAN));
+
+        VirtualNetworkIntent virtualIntent = VirtualNetworkIntent.builder()
+                .networkId(virtualNetwork.id())
+                .key(intentKey)
+                .appId(APP_ID)
+                .ingressPoint(cp1)
+                .egressPoint(cp5)
+                .constraints(constraints)
+                .build();
+        // Test the submit() method.
+        vnetIntentService.submit(virtualIntent);
+
+        // Wait for the both intents to go into an INSTALLED state.
+        try {
+            if (!created.tryAcquire(MAX_PERMITS, MAX_WAIT_TIME, TimeUnit.SECONDS)) {
+                fail("Failed to wait for intent to get installed.");
+            }
+        } catch (InterruptedException e) {
+            fail("Semaphore exception during intent installation." + e.getMessage());
+        }
+
+        // Test the getIntents() method
+        assertEquals("The intents size did not match as expected.", 1,
+                     Iterators.size(vnetIntentService.getIntents().iterator()));
+
+        // Test the getIntent() method
+        assertNotNull("The intent should have been found.", vnetIntentService.getIntent(virtualIntent.key()));
+
+        // Test the getIntentData() method
+        assertEquals("The intent data size did not match as expected.", 1,
+                     Iterators.size(vnetIntentService.getIntentData().iterator()));
+
+        // Test the getIntentCount() method
+        assertEquals("The intent count did not match as expected.", 1,
+                     vnetIntentService.getIntentCount());
+
+        // Test the isLocal() method
+        assertTrue("The intent should be local.", vnetIntentService.isLocal(virtualIntent.key()));
+
+    }
+
+    /**
+     * Test listener to listen for intent events.
+     */
+    private static class TestListener implements IntentListener {
+
+        @Override
+        public void event(IntentEvent event) {
+            switch (event.type()) {
+                case INSTALLED:
+                    // Release one permit on the created semaphore since the Intent event was received.
+//                    virtualNetworkManagerStore.addOrUpdateIntent(event.subject(), IntentState.INSTALLED);
+                    created.release();
+                    break;
+                case WITHDRAWN:
+                    // Release one permit on the removed semaphore since the Intent event was received.
+//                    virtualNetworkManagerStore.addOrUpdateIntent(event.subject(), IntentState.WITHDRAWN);
+                    withdrawn.release();
+                    break;
+                case PURGED:
+                    // Release one permit on the purged semaphore since the Intent event was received.
+                    purged.release();
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    /**
+     * 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();
+                }
+            };
+        }
+    }
+
+    private static class TestIntentCompiler implements IntentCompiler<VirtualNetworkIntent> {
+        @Override
+        public List<Intent> compile(VirtualNetworkIntent intent, List<Intent> installable) {
+            return Lists.newArrayList(new MockInstallableIntent());
+        }
+    }
+
+    private static class MockInstallableIntent extends FlowRuleIntent {
+
+        public MockInstallableIntent() {
+            super(APP_ID, null, Collections.singletonList(new IntentTestsMocks.MockFlowRule(100)),
+                    Collections.emptyList(), PathIntent.ProtectionType.PRIMARY, null);
+        }
+    }
+
+//    private void addOrUpdateIntent(Intent intent, IntentState state) {
+//        checkNotNull(intent, "Intent cannot be null");
+//        IntentData intentData = intentStore.(intent.key());
+//        if (intentData == null) {
+//            intentData = new IntentData(intent, state, new WallClockTimestamp(System.currentTimeMillis()));
+//        } else {
+//            intentData = new IntentData(intent, state, intentData.version());
+//        }
+//        intentKeyIntentDataMap.put(intent.key(), intentData);
+//    }
+}
